root/src/add-ons/kernel/network/protocols/l2cap/L2capEndpointManager.h
/*
 * Copyright 2024, Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 */
#ifndef L2CAP_ENDPOINT_MANAGER_H
#define L2CAP_ENDPOINT_MANAGER_H

#include <util/AVLTree.h>

#include "L2capEndpoint.h"


class L2capEndpointManager {
public:
                                                L2capEndpointManager();
                                                ~L2capEndpointManager();

        status_t                        Bind(L2capEndpoint* endpoint, const sockaddr_l2cap& address);
        status_t                        Unbind(L2capEndpoint* endpoint);
        L2capEndpoint*          ForPSM(uint16 psm);

        status_t                        BindToChannel(L2capEndpoint* endpoint);
        status_t                        UnbindFromChannel(L2capEndpoint* endpoint);
        L2capEndpoint*          ForChannel(uint16 cid);
        void                            Disconnected(HciConnection* connection);

private:
        struct EndpointTreeDefinitionBase {
                typedef uint16                  Key;
                typedef L2capEndpoint   Value;

                AVLTreeNode* GetAVLTreeNode(Value* value) const
                {
                        return value;
                }

                Value* GetValue(AVLTreeNode* node) const
                {
                        return static_cast<Value*>(node);
                }
        };
        struct EndpointBindTreeDefinition : public EndpointTreeDefinitionBase {
                int Compare(const Key& a, const Value* b) const
                {
                        return a - ((sockaddr_l2cap*)*b->LocalAddress())->l2cap_psm;
                }

                int Compare(const Value* a, const Value* b) const
                {
                        return Compare(((sockaddr_l2cap*)*a->LocalAddress())->l2cap_psm, b);
                }
        };
        struct EndpointChannelTreeDefinition : public EndpointTreeDefinitionBase {
                int Compare(const Key& a, const Value* b) const
                {
                        return a - b->ChannelID();
                }

                int Compare(const Value* a, const Value* b) const
                {
                        return Compare(a->ChannelID(), b);
                }
        };

        rw_lock fBoundEndpointsLock;
        AVLTree<EndpointBindTreeDefinition> fBoundEndpoints;

        rw_lock fChannelEndpointsLock;
        uint16 fNextChannelID;
        AVLTree<EndpointChannelTreeDefinition> fChannelEndpoints;
};

extern L2capEndpointManager gL2capEndpointManager;


#endif  // L2CAP_ENDPOINT_MANAGER_H