1/*
2 * Copyright 2024, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef L2CAP_ENDPOINT_MANAGER_H
6#define L2CAP_ENDPOINT_MANAGER_H
7
8#include <util/AVLTree.h>
9
10#include "L2capEndpoint.h"
11
12
13class L2capEndpointManager {
14public:
15						L2capEndpointManager();
16						~L2capEndpointManager();
17
18	status_t			Bind(L2capEndpoint* endpoint, const sockaddr_l2cap& address);
19	status_t			Unbind(L2capEndpoint* endpoint);
20	L2capEndpoint*		ForPSM(uint16 psm);
21
22	status_t			BindToChannel(L2capEndpoint* endpoint);
23	status_t			UnbindFromChannel(L2capEndpoint* endpoint);
24	L2capEndpoint*		ForChannel(uint16 cid);
25	void				Disconnected(HciConnection* connection);
26
27private:
28	struct EndpointTreeDefinitionBase {
29		typedef uint16			Key;
30		typedef L2capEndpoint	Value;
31
32		AVLTreeNode* GetAVLTreeNode(Value* value) const
33		{
34			return value;
35		}
36
37		Value* GetValue(AVLTreeNode* node) const
38		{
39			return static_cast<Value*>(node);
40		}
41	};
42	struct EndpointBindTreeDefinition : public EndpointTreeDefinitionBase {
43		int Compare(const Key& a, const Value* b) const
44		{
45			return a - ((sockaddr_l2cap*)*b->LocalAddress())->l2cap_psm;
46		}
47
48		int Compare(const Value* a, const Value* b) const
49		{
50			return Compare(((sockaddr_l2cap*)*a->LocalAddress())->l2cap_psm, b);
51		}
52	};
53	struct EndpointChannelTreeDefinition : public EndpointTreeDefinitionBase {
54		int Compare(const Key& a, const Value* b) const
55		{
56			return a - b->ChannelID();
57		}
58
59		int Compare(const Value* a, const Value* b) const
60		{
61			return Compare(a->ChannelID(), b);
62		}
63	};
64
65	rw_lock fBoundEndpointsLock;
66	AVLTree<EndpointBindTreeDefinition> fBoundEndpoints;
67
68	rw_lock fChannelEndpointsLock;
69	uint16 fNextChannelID;
70	AVLTree<EndpointChannelTreeDefinition> fChannelEndpoints;
71};
72
73extern L2capEndpointManager gL2capEndpointManager;
74
75
76#endif	// L2CAP_ENDPOINT_MANAGER_H
77