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