/* * 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 #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(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 fBoundEndpoints; rw_lock fChannelEndpointsLock; uint16 fNextChannelID; AVLTree fChannelEndpoints; }; extern L2capEndpointManager gL2capEndpointManager; #endif // L2CAP_ENDPOINT_MANAGER_H