1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef TRANSPORT_L2CAP_H
17 #define TRANSPORT_L2CAP_H
18 
19 #include <map>
20 #include <mutex>
21 #include <stdint.h>
22 #include "l2cap_if.h"
23 #include "packet.h"
24 #include "raw_address.h"
25 #include "transport_def.h"
26 
27 namespace OHOS {
28 namespace bluetooth {
29 /**
30  * @brief This L2capTransport class provides a set of methods that is interactive with L2CAP.
31  */
32 class L2capTransport : public DataTransport {
33 public:
34     /**
35      * @brief Constructor.
36      * @param createInfo  create info struct.
37      */
38     explicit L2capTransport(L2capTransportInfo &createInfo);
39 
40     /**
41      * @brief Destructor.
42      */
43     virtual ~L2capTransport();
44 
45     /**
46      * @brief The client initiates the connection.
47      *
48      * @return int
49      */
50     int Connect() override;
51 
52     /**
53      * @brief The client initiates the disconnection request.
54      *
55      * @return int
56      */
57     int Disconnect() override;
58 
59     /**
60      * @brief The server register to L2CAP.
61      *
62      * @return int
63      */
64     int RegisterServer() override;
65 
66     /**
67      * @brief Close server.
68      *
69      * @return int
70      */
71     int RemoveServer(bool isDisable = true) override;
72 
73     /**
74      * @brief The server accept the connection.
75      *
76      * @param addr remote device address.
77      * @param scn the server channel.
78      * @return int
79      */
80     int AcceptConnection(const RawAddress &addr, uint16_t psm) override;
81 
82     /**
83      * @brief The server reject the connection.
84      *
85      * @param addr remote device address.
86      * @param scn the server channel.
87      * @return int
88      */
89     int RejectConnection(const RawAddress &addr, uint16_t psm) override;
90 
91     /**
92      * @brief Receive data from L2CAP.
93      * @param pkt  Data packet
94      * @return int
95      */
96     int Read(Packet **pkt) override;
97 
98     /**
99      * @brief Send data to L2CAP.
100      *
101      * @param pkt Data packet
102      * @return int
103      */
104     int Write(Packet *pkt) override;
105 
106     /**
107      * @brief Get the remote device address.
108      *
109      * @return RawAddress
110      */
111     RawAddress GetRemoteAddress() override;
112 
113     /**
114      * @brief RegisterService to l2cap
115      *
116      * @param lpsm local channel id.
117      */
118     static int RegisterClientPsm(uint16_t lpsm);
119 
120     /**
121      * @brief DeregisterService to l2cap
122      *
123      * @param lpsm local channel id.
124      */
125     static void DeregisterClientPsm(uint16_t lpsm);
126 
127 private:
128     /**
129      * @brief L2cap event
130      *
131      * @param addr remote bluetooth address.
132      * @param lcid local channel id.
133      * @param result if the operation is successful, otherwise the operation fails.
134      */
135     static void TransportL2cConnectReqCallback(const BtAddr *addr, uint16_t lcid, int result, void *context);
136 
137     /**
138      * @brief L2cap event
139      *
140      * @param addr remote bluetooth address.
141      * @param lcid local channel id.
142      * @param result if the operation is successful, otherwise the operation fails.
143      */
144     static void TransportL2cSendDataCallback(uint16_t lcid, int result);
145 
146     /**
147      * @brief L2cap event
148      *
149      * @param lcid local channel id.
150      * @param result if the operation is successful, otherwise the operation fails.
151      */
152     static void TransportRecvConnectionReqCallback(
153         uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *ctx);
154 
155     /**
156      * @brief L2cap event
157      *
158      * @param lcid local channel id.
159      * @param result if the operation is successful, otherwise the operation fails.
160      */
161     static void TransportRecvConnectionRspCallback(
162         uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *ctx);
163 
164     /**
165      * @brief L2cap event
166      *
167      * @param lcid local channel id.
168      * @param result if the operation is successful, otherwise the operation fails.
169      */
170     static void TransportRecvConfigReqCallback(uint16_t lcid, uint8_t id, const L2capConfigInfo *cfg, void *ctx);
171 
172     /**
173      * @brief L2cap event
174      *
175      * @param lcid local channel id.
176      * @param result if the operation is successful, otherwise the operation fails.
177      */
178     static void TransportRecvConfigRspCallback(uint16_t lcid, const L2capConfigInfo *cfg, uint16_t result, void *ctx);
179 
180     /**
181      * @brief L2cap event
182      *
183      * @param lcid local channel id.
184      * @param result if the operation is successful, otherwise the operation fails.
185      */
186     static void TransportRecvDisconnectionReqCallback(uint16_t lcid, uint8_t id, void *ctx);
187 
188     /**
189      * @brief L2cap event
190      *
191      * @param lcid local channel id.
192      * @param result if the operation is successful, otherwise the operation fails.
193      */
194     static void TransportRecvDisconnectionRspCallback(uint16_t lcid, void *ctx);
195 
196     /**
197      * @brief L2cap event
198      *
199      * @param lcid local channel id.
200      * @param result if the operation is successful, otherwise the operation fails.
201      */
202     static void TransportDisconnectAbnormalCallback(uint16_t lcid, uint8_t reason, void *ctx);
203 
204     /**
205      * @brief L2cap event
206      *
207      * @param lcid local channel id.
208      * @param result if the operation is successful, otherwise the operation fails.
209      */
210     static void TransportRecvDataCallback(uint16_t lcid, Packet *pkt, void *ctx);
211 
212     /**
213      * @brief L2cap event
214      *
215      * @param lcid local channel id.
216      * @param result if the operation is successful, otherwise the operation fails.
217      */
218     static void TransportRemoteBusyCallback(uint16_t lcid, uint8_t isBusy, void *ctx);
219 
220     /**
221      * @brief L2cap event
222      *
223      * @param addr remote bluetooth address.
224      * @param lcid local channel id.
225      * @param result if the operation is successful, otherwise the operation fails.
226      */
227     void TransportL2cConnectReqCallbackNative(L2capTransport *transport,
228                                               const BtAddr &addr, uint16_t lcid, int result);
229 
230     /**
231      * @brief L2cap event
232      *
233      * @param lcid local channel id.
234      * @param result if the operation is successful, otherwise the operation fails.
235      */
236     void TransportRecvConnectionReqCallbackNative(
237         L2capTransport *transport, uint16_t lcid, uint8_t id, const L2capConnectionInfo info, uint16_t lpsm);
238 
239     /**
240      * @brief L2cap event
241      *
242      * @param lcid local channel id.
243      * @param result if the operation is successful, otherwise the operation fails.
244      */
245     void TransportRecvConnectionRspCallbackNative(
246         L2capTransport *transport, uint16_t lcid, const L2capConnectionInfo info, uint16_t result, uint16_t status);
247 
248     /**
249      * @brief L2cap event
250      *
251      * @param lcid local channel id.
252      * @param result if the operation is successful, otherwise the operation fails.
253      */
254     void TransportRecvConfigReqCallbackNative(
255         L2capTransport *transport, uint16_t lcid, uint8_t id, const L2capConfigInfo cfg);
256 
257     /**
258      * @brief L2cap event
259      *
260      * @param lcid local channel id.
261      * @param result if the operation is successful, otherwise the operation fails.
262      */
263     void TransportRecvConfigRspCallbackNative(
264         L2capTransport *transport, uint16_t lcid, const L2capConfigInfo cfg, uint16_t result);
265 
266     /**
267      * @brief L2cap event
268      *
269      * @param lcid local channel id.
270      * @param result if the operation is successful, otherwise the operation fails.
271      */
272     void TransportRecvDisconnectionReqCallbackNative(L2capTransport *transport, uint16_t lcid, uint8_t id);
273 
274     /**
275      * @brief L2cap event
276      *
277      * @param lcid local channel id.
278      * @param result if the operation is successful, otherwise the operation fails.
279      */
280     void TransportRecvDisconnectionRspCallbackNative(L2capTransport *transport, uint16_t lcid);
281 
282     /**
283      * @brief L2cap event
284      *
285      * @param lcid local channel id.
286      * @param result if the operation is successful, otherwise the operation fails.
287      */
288     void TransportDisconnectAbnormalCallbackNative(L2capTransport *transport, uint16_t lcid, uint8_t reason);
289 
290     /**
291      * @brief L2cap event
292      *
293      * @param lcid local channel id.
294      * @param result if the operation is successful, otherwise the operation fails.
295      */
296     void TransportRecvDataCallbackNative(L2capTransport *transport, uint16_t lcid, Packet *pkt);
297 
298     /**
299      * @brief L2cap event
300      *
301      * @param lcid local channel id.
302      * @param result if the operation is successful, otherwise the operation fails.
303      */
304     void TransportRemoteBusyCallbackNative(L2capTransport *transport, uint16_t lcid, uint8_t isBusy);
305 
306     /**
307      * @brief When server accept a connection request, generate a new transport.
308      *
309      * @param addr remote device address.
310      * @param handle l2cap connection handle.
311      * @return L2capTransport*
312      */
313     L2capTransport *AddTransportInternal(RawAddress addr, uint16_t lcid);
314 
315     /**
316      * @brief Find client transport.
317      *
318      * @param lcid l2cap connect id.
319      * @return L2capTransport*
320      */
321     static L2capTransport *FindClientTransport(uint16_t lcid);
322 
323     /**
324      * @brief Find accept transport.
325      *
326      * @param lcid l2cap connect id.
327      * @return L2capTransport*
328      */
329     static L2capTransport *FindAcceptTransport(L2capTransport *transport, uint16_t lcid);
330 
331     /**
332      * @brief get transport.
333      *
334      * @param lcid l2cap connect id.
335      * @return L2capTransport*
336      */
337     static L2capTransport *GetTransport(uint16_t lcid, void *ctx);
338 
339     /**
340      * @brief is server or not.
341      *
342      * @return true the role is server.
343      * @return false the role is client
344      */
IsServer()345     bool IsServer() const
346     {
347         return isServer_;
348     }
349 
350     struct ConnectReqInfo {
351         uint16_t lcid;
352         uint8_t id;
353     };
354 
355     // remote device address.
356     RawAddress remoteAddr_ {};
357     // local psm
358     uint16_t lpsm_ {0};
359     // remote psm
360     uint16_t rpsm_ {0};
361     // mtu
362     uint16_t localMtu_ {0};
363     uint16_t remoteMtu_ {0};
364     // is server or not.
365     bool isServer_ {false};
366     // is connected or not.
367     bool isConnected_ {false};
368     // is remove server or not.
369     bool isRemoveServer_ {false};
370     // L2CAP handle
371     uint16_t l2capHandle_ {0};
372     // L2CAP config handle
373     int l2capConfigState_ {0};
374     // L2CAP id
375     uint8_t l2capId_ {0};
376     // The map manages the correspondence between new transport and rfcomm handle.
377     std::map<uint16_t, L2capTransport *> transportMap_ {};
378     // The map manages the correspondence between remote address and l2cap handle.
379     std::map<RawAddress, ConnectReqInfo> handleMap_ {};
380     // The map manages the correspondence between new transport and rfcomm handle.
381     std::map<L2capTransport *, RawAddress> remoteAddrMap_ {};
382     // the pointer of the DataTransportObserver
383     DataTransportObserver &observer_;
384     utility::Dispatcher &dispatcher_;
385     // std::mutex mutex_;
386     std::mutex transportMutex_ {};
387     static std::recursive_mutex g_clientTransportMutex;
388 
389     static constexpr L2capService L2CAP_CALLBACK = {
390         TransportRecvConnectionReqCallback,
391         TransportRecvConnectionRspCallback,
392         TransportRecvConfigReqCallback,
393         TransportRecvConfigRspCallback,
394         TransportRecvDisconnectionReqCallback,
395         TransportRecvDisconnectionRspCallback,
396         TransportDisconnectAbnormalCallback,
397         TransportRecvDataCallback,
398         TransportRemoteBusyCallback
399     };
400 
401     static std::map<uint16_t, L2capTransport *> g_clientTransportMap;
402 
403     BT_DISALLOW_COPY_AND_ASSIGN(L2capTransport);
404 };
405 }  // namespace bluetooth
406 }  // namespace OHOS
407 #endif  // TRANSPORT_L2CAP_H