xref: /haiku/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.h (revision bb83316a5811a550c4f850d07fa8e328e7ac0a94)
1 /*
2  * Copyright 2008, Oliver Ruiz Dorantes. All rights reserved.
3  * Copyright 2024, Haiku, Inc. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  */
6 #ifndef L2CAP_ENDPOINT_H
7 #define L2CAP_ENDPOINT_H
8 
9 
10 #include <lock.h>
11 #include <condition_variable.h>
12 #include <util/AVLTree.h>
13 
14 #include <net_protocol.h>
15 #include <net_socket.h>
16 #include <ProtocolUtilities.h>
17 
18 #include <bluetooth/L2CAP/btL2CAP.h>
19 #include "l2cap_internal.h"
20 
21 
22 class L2capEndpoint;
23 
24 
25 class L2capEndpoint : public net_protocol, public ProtocolSocket, public AVLTreeNode {
26 public:
27 						L2capEndpoint(net_socket* socket);
28 	virtual				~L2capEndpoint();
29 
30 			status_t	Open();
31 			status_t	Shutdown();
32 			status_t	Close();
33 			status_t	Free();
34 
35 			status_t	Bind(const struct sockaddr* _address);
36 			status_t	Unbind();
37 			status_t	Listen(int backlog);
38 			status_t	Connect(const struct sockaddr* address);
39 			status_t	Accept(net_socket** _acceptedSocket);
40 
ChannelID()41 			uint16		ChannelID() const { return fChannelID; }
42 
43 			ssize_t		ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer);
44 			ssize_t		SendData(net_buffer* buffer);
45 			status_t	ReceiveData(net_buffer* buffer);
46 			ssize_t		Sendable();
47 			ssize_t		Receivable();
48 
49 public:
50 			void		_HandleCommandRejected(uint8 ident, uint16 reason,
51 							const l2cap_command_reject_data& data);
52 			void 		_HandleConnectionReq(HciConnection* connection,
53 							uint8 ident, uint16 psm, uint16 scid);
54 			void		_HandleConnectionRsp(uint8 ident, const l2cap_connection_rsp& response);
55 			void		_HandleConfigurationReq(uint8 ident, uint16 flags,
56 							uint16* mtu, uint16* flush_timeout, l2cap_qos* flow);
57 			void		_HandleConfigurationRsp(uint8 ident, uint16 scid, uint16 flags,
58 							uint16 result, uint16* mtu, uint16* flush_timeout, l2cap_qos* flow);
59 			void		_HandleDisconnectionReq(uint8 ident, uint16 scid);
60 			void		_HandleDisconnectionRsp(uint8 ident, uint16 dcid, uint16 scid);
61 
62 private:
63 	inline bool
_IsEstablishing()64 	_IsEstablishing()
65 	{
66 		return fState > LISTEN && fState < OPEN;
67 	}
68 
69 			status_t	_WaitForStateChange(bigtime_t absoluteTimeout);
70 
71 	static	void		_SendTimer(net_timer* timer, void* _endpoint);
72 			void		_SendQueued();
73 
74 			void		_SendChannelConfig();
75 			status_t	_MarkEstablished();
76 			void		_MarkClosed();
77 
78 private:
79 	friend class L2capEndpointManager;
80 
81 	sem_id			fAcceptSemaphore;
82 	mutex			fLock;
83 
84 	enum channel_status {
85 		CLOSED,
86 		BOUND,
87 		LISTEN,
88 
89 		WAIT_FOR_CONNECTION_RSP,
90 		CONFIGURATION,
91 		OPEN,
92 		WAIT_FOR_DISCONNECTION_RSP,
93 		RECEIVED_DISCONNECTION_REQ,
94 	} fState;
95 
96 	HciConnection*	fConnection;
97 
98 	ConditionVariable fCommandWait;
99 
100 	uint16			fChannelID, fDestinationChannelID;
101 
102 	net_fifo		fReceiveQueue, fSendQueue;
103 	net_timer		fSendTimer;
104 
105 	struct ConfigState {
106 		enum : uint8 {
107 			NONE,
108 			SENT,
109 			DONE,
110 		} in, out;
111 	} fConfigState;
112 	struct ChannelConfiguration {
113 		uint16		incoming_mtu;
114 		l2cap_qos	incoming_flow;
115 		uint16		outgoing_mtu;
116 		l2cap_qos	outgoing_flow;
117 
118 		uint16		flush_timeout;
119 		uint16		link_timeout;
120 	} fChannelConfig;
121 };
122 
123 
124 #endif	// L2CAP_ENDPOINT_H
125