• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include "l2cap_cmn.h"
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include "log.h"
23 
24 #include "allocator.h"
25 #include "bt_endian.h"
26 
27 #include "btm.h"
28 #include "hci/hci.h"
29 
30 #include "../btm/btm_thread.h"
31 
32 typedef struct {
33     uint16_t handle;
34     uint16_t length;
35     uint16_t cid;
36     Packet *pkt;
37 } L2capFragmentationPacket;
38 
39 static L2capBdrCallback g_l2capBdr;
40 static L2capLeCallback g_l2capLe;
41 
42 static List *g_fragmentationList;
43 
L2capProcessPacket(uint16_t handle,uint16_t cid,Packet * pkt)44 static void L2capProcessPacket(uint16_t handle, uint16_t cid, Packet *pkt)
45 {
46     if (cid >= L2CAP_MIN_CID) {
47         if (g_l2capBdr.recvL2capPacket != NULL) {
48             g_l2capBdr.recvL2capPacket(handle, cid, pkt);
49         }
50         return;
51     } else if ((cid >= L2CAP_LE_MIN_CID) && (cid <= L2CAP_LE_MAX_CID)) {
52         if (g_l2capLe.recvL2capPacket != NULL) {
53             g_l2capLe.recvL2capPacket(handle, cid, pkt);
54         }
55         return;
56     }
57 
58     switch (cid) {
59         case L2CAP_SIGNALING_CHANNEL:
60             if (g_l2capBdr.recvL2capPacket != NULL) {
61                 g_l2capBdr.recvL2capPacket(handle, cid, pkt);
62             }
63             return;
64         case L2CAP_LE_ATTRIBUTE_PROTOCOL:  // dummy
65         case L2CAP_LE_SIGNALING_CHANNEL:   // dummy
66         case L2CAP_LE_SECURITY_MANAGER_PROTOCOL:
67             if (g_l2capLe.recvL2capPacket != NULL) {
68                 g_l2capLe.recvL2capPacket(handle, cid, pkt);
69             }
70             return;
71         default:
72             break;
73     }
74 
75     return;
76 }
77 
L2capRecombineStart(uint16_t handle,uint16_t length,uint16_t cid,const Packet * pkt)78 static void L2capRecombineStart(uint16_t handle, uint16_t length, uint16_t cid, const Packet *pkt)
79 {
80     L2capFragmentationPacket *frag = NULL;
81     ListNode *node = NULL;
82     Packet *tpkt = NULL;
83 
84     if (g_fragmentationList == NULL) {
85         return;
86     }
87 
88     // if there are already packet with the same handle, the old packet will be discard
89     node = ListGetFirstNode(g_fragmentationList);
90     while (node != NULL) {
91         frag = ListGetNodeData(node);
92         if (frag->handle == handle) {
93             ListRemoveNode(g_fragmentationList, frag);
94             PacketFree(frag->pkt);
95             L2capFree(frag);
96             break;
97         }
98 
99         node = ListGetNextNode(node);
100     }
101 
102     tpkt = PacketRefMalloc(pkt);
103     frag = L2capAlloc(sizeof(L2capFragmentationPacket));
104     if (frag == NULL) {
105         LOG_WARN("malloc failed");
106         return;
107     }
108 
109     frag->handle = handle;
110     frag->length = length;
111     frag->cid = cid;
112     frag->pkt = tpkt;
113 
114     ListAddLast(g_fragmentationList, frag);
115     return;
116 }
117 
L2capRecombineContinue(uint16_t handle,const Packet * pkt)118 static void L2capRecombineContinue(uint16_t handle, const Packet *pkt)
119 {
120     L2capFragmentationPacket *frag = NULL;
121     ListNode *node = NULL;
122     uint32_t pktLength;
123 
124     if (g_fragmentationList == NULL) {
125         return;
126     }
127 
128     node = ListGetFirstNode(g_fragmentationList);
129     while (node != NULL) {
130         frag = ListGetNodeData(node);
131         if (frag->handle == handle) {
132             PacketAssemble(frag->pkt, pkt);
133             pktLength = PacketSize(frag->pkt);
134             if (frag->length == (pktLength - L2CAP_HEADER_LENGTH)) {
135                 L2capProcessPacket(handle, frag->cid, frag->pkt);
136 
137                 ListRemoveNode(g_fragmentationList, frag);
138                 PacketFree(frag->pkt);
139                 L2capFree(frag);
140             } else if (frag->length < (pktLength - L2CAP_HEADER_LENGTH)) {  // invalid packet length
141                 ListRemoveNode(g_fragmentationList, frag);
142                 PacketFree(frag->pkt);
143                 L2capFree(frag);
144             }
145 
146             break;
147         }
148 
149         node = ListGetNextNode(node);
150     }
151 
152     return;
153 }
154 
L2capAclDataReceived(uint16_t handle,uint8_t pb,uint8_t bc,Packet * pkt)155 static void L2capAclDataReceived(uint16_t handle, uint8_t pb, uint8_t bc, Packet *pkt)
156 {
157     if ((pb == L2CAP_FIRST_NON_AUTOMATICALLY_FLUSHABLE_PACKET) ||
158         (pb == L2CAP_FIRST_AUTOMATICALLY_FLUSHABLE_PACKET)) {  // start packet
159         uint16_t pktLength = PacketSize(pkt);
160         if (pktLength <= L2CAP_HEADER_LENGTH) {
161             return;
162         }
163 
164         uint8_t header[L2CAP_HEADER_LENGTH] = {0};
165         PacketRead(pkt, header, 0, sizeof(header));
166         uint16_t length = L2capLe16ToCpu(header + 0);
167         uint16_t cid = L2capLe16ToCpu(header + L2CAP_OFFSET_2);
168 
169         if (length == (pktLength - L2CAP_HEADER_LENGTH)) {
170             L2capProcessPacket(handle, cid, pkt);
171         } else {
172             // invalid packet length
173             if (length < (pktLength - L2CAP_HEADER_LENGTH)) {
174                 return;
175             }
176             L2capRecombineStart(handle, length, cid, pkt);
177         }
178     } else {  // continue packet
179         L2capRecombineContinue(handle, pkt);
180     }
181 
182     return;
183 }
184 
185 typedef struct {
186     uint16_t handle;
187     uint8_t pb;
188     uint8_t bc;
189     Packet *pkt;
190 } L2capAclDataReceivedContext;
191 
L2capAclDataReceivedContextDestroy(void * context)192 static void L2capAclDataReceivedContextDestroy(void *context)
193 {
194     L2capAclDataReceivedContext *ctx = NULL;
195 
196     ctx = context;
197 
198     PacketFree(ctx->pkt);
199     L2capFree(ctx);
200     return;
201 }
202 
L2capAclDataReceivedCallbackProcess(const void * context)203 static void L2capAclDataReceivedCallbackProcess(const void *context)
204 {
205     L2capAclDataReceivedContext *ctx = NULL;
206 
207     ctx = (L2capAclDataReceivedContext *)context;
208 
209     L2capAclDataReceived(ctx->handle, ctx->pb, ctx->bc, ctx->pkt);
210 
211     L2capAclDataReceivedContextDestroy(ctx);
212     return;
213 }
214 
L2capAclDataReceivedCallback(uint16_t handle,uint8_t pb,uint8_t bc,Packet * pkt)215 static void L2capAclDataReceivedCallback(uint16_t handle, uint8_t pb, uint8_t bc, Packet *pkt)
216 {
217     L2capAclDataReceivedContext *ctx = NULL;
218 
219     ctx = L2capAlloc(sizeof(L2capAclDataReceivedContext));
220     if (ctx == NULL) {
221         LOG_WARN("malloc failed");
222         return;
223     }
224 
225     ctx->handle = handle;
226     ctx->pb = pb;
227     ctx->bc = bc;
228     ctx->pkt = PacketRefMalloc(pkt);
229 
230     L2capAsynchronousProcess(L2capAclDataReceivedCallbackProcess, L2capAclDataReceivedContextDestroy, ctx);
231     return;
232 }
233 
L2capAclDisconnected(uint8_t status,uint16_t handle,uint8_t reason,void * context)234 static void L2capAclDisconnected(uint8_t status, uint16_t handle, uint8_t reason, void *context)
235 {
236     L2capFragmentationPacket *frag = NULL;
237     ListNode *node = NULL;
238 
239     if (g_fragmentationList != NULL) {
240         node = ListGetFirstNode(g_fragmentationList);
241         while (node != NULL) {
242             frag = ListGetNodeData(node);
243             if (frag->handle == handle) {
244                 ListRemoveNode(g_fragmentationList, frag);
245                 PacketFree(frag->pkt);
246                 L2capFree(frag);
247 
248                 node = ListGetFirstNode(g_fragmentationList);
249                 continue;
250             }
251 
252             node = ListGetNextNode(node);
253         }
254     }
255 
256     if (g_l2capBdr.aclDisconnected != NULL) {
257         g_l2capBdr.aclDisconnected(handle, status, reason);
258     }
259 
260     if (g_l2capLe.aclDisconnected != NULL) {
261         g_l2capLe.aclDisconnected(handle, status, reason);
262     }
263     return;
264 }
265 
266 typedef struct {
267     uint8_t status;
268     uint16_t handle;
269     uint8_t reason;
270     void *context;
271 } L2capAclDisconnectedContext;
272 
L2capAclDisconnectedCallbackProcess(const void * context)273 static void L2capAclDisconnectedCallbackProcess(const void *context)
274 {
275     L2capAclDisconnectedContext *ctx = NULL;
276 
277     ctx = (L2capAclDisconnectedContext *)context;
278 
279     L2capAclDisconnected(ctx->status, ctx->handle, ctx->reason, ctx->context);
280 
281     L2capFree(ctx);
282     return;
283 }
284 
L2capAclDisconnectedCallback(uint8_t status,uint16_t handle,uint8_t reason,void * context)285 static void L2capAclDisconnectedCallback(uint8_t status, uint16_t handle, uint8_t reason, void *context)
286 {
287     L2capAclDisconnectedContext *ctx = NULL;
288 
289     ctx = L2capAlloc(sizeof(L2capAclDisconnectedContext));
290     if (ctx == NULL) {
291         LOG_WARN("malloc failed");
292         return;
293     }
294 
295     ctx->status = status;
296     ctx->handle = handle;
297     ctx->reason = reason;
298     ctx->context = context;
299 
300     L2capAsynchronousProcess(L2capAclDisconnectedCallbackProcess, L2capFree, ctx);
301     return;
302 }
303 
L2capBdrAclConnected(uint8_t status,uint16_t handle,const BtAddr * addr)304 static void L2capBdrAclConnected(uint8_t status, uint16_t handle, const BtAddr *addr)
305 {
306     if (g_l2capBdr.aclConnected != NULL) {
307         g_l2capBdr.aclConnected((BtAddr *)addr, handle, status);
308     }
309     return;
310 }
311 
312 typedef struct {
313     uint8_t status;
314     uint16_t handle;
315     BtAddr addr;
316 } L2capBdrAclConnectedContext;
317 
L2capBdrAclConnectedCallbackProcess(const void * context)318 static void L2capBdrAclConnectedCallbackProcess(const void *context)
319 {
320     L2capBdrAclConnectedContext *ctx = NULL;
321 
322     ctx = (L2capBdrAclConnectedContext *)context;
323 
324     L2capBdrAclConnected(ctx->status, ctx->handle, &(ctx->addr));
325 
326     L2capFree(ctx);
327     return;
328 }
329 
L2capBdrAclConnectedCallback(const BtmAclConnectCompleteParam * param,void * context)330 static void L2capBdrAclConnectedCallback(const BtmAclConnectCompleteParam *param, void *context)
331 {
332     L2capBdrAclConnectedContext *ctx = NULL;
333 
334     ctx = L2capAlloc(sizeof(L2capBdrAclConnectedContext));
335     if (ctx == NULL) {
336         LOG_WARN("malloc failed");
337         return;
338     }
339     ctx->status = param->status;
340     ctx->handle = param->connectionHandle;
341     (void)memcpy_s(&(ctx->addr), sizeof(BtAddr), param->addr, sizeof(BtAddr));
342 
343     L2capAsynchronousProcess(L2capBdrAclConnectedCallbackProcess, L2capFree, ctx);
344     return;
345 }
346 
L2capLeAclConnected(uint8_t status,uint16_t handle,const BtAddr * addr,uint8_t role,void * context)347 static void L2capLeAclConnected(uint8_t status, uint16_t handle, const BtAddr *addr, uint8_t role, void *context)
348 {
349     if (g_l2capLe.aclConnected != NULL) {
350         g_l2capLe.aclConnected((BtAddr *)addr, handle, role, status);
351     }
352     return;
353 }
354 
355 typedef struct {
356     uint8_t status;
357     uint16_t handle;
358     BtAddr addr;
359     uint8_t role;
360     void *context;
361 } L2capLeAclConnectedContext;
362 
L2capLeAclConnectedCallbackProcess(const void * context)363 static void L2capLeAclConnectedCallbackProcess(const void *context)
364 {
365     L2capLeAclConnectedContext *ctx = NULL;
366 
367     ctx = (L2capLeAclConnectedContext *)context;
368 
369     L2capLeAclConnected(ctx->status, ctx->handle, &(ctx->addr), ctx->role, ctx->context);
370 
371     L2capFree(ctx);
372     return;
373 }
374 
L2capLeAclConnectedCallback(uint8_t status,uint16_t handle,const BtAddr * addr,uint8_t role,void * context)375 static void L2capLeAclConnectedCallback(
376     uint8_t status, uint16_t handle, const BtAddr *addr, uint8_t role, void *context)
377 {
378     L2capLeAclConnectedContext *ctx = NULL;
379 
380     ctx = L2capAlloc(sizeof(L2capLeAclConnectedContext));
381     if (ctx == NULL) {
382         LOG_WARN("malloc failed");
383         return;
384     }
385 
386     ctx->status = status;
387     ctx->handle = handle;
388     (void)memcpy_s(&(ctx->addr), sizeof(BtAddr), addr, sizeof(BtAddr));
389     ctx->role = role;
390     ctx->context = context;
391 
392     L2capAsynchronousProcess(L2capLeAclConnectedCallbackProcess, L2capFree, ctx);
393     return;
394 }
395 
L2capCpuToLe16(uint8_t * dst,uint16_t src)396 void L2capCpuToLe16(uint8_t *dst, uint16_t src)
397 {
398     uint16_t tmp;
399 
400     tmp = H2LE_16(src);
401     (void)memcpy_s(dst, sizeof(uint16_t), &tmp, sizeof(uint16_t));
402     return;
403 }
404 
L2capLe16ToCpu(const uint8_t * src)405 uint16_t L2capLe16ToCpu(const uint8_t *src)
406 {
407     uint16_t tmp = 0;
408 
409     for (size_t i = 0; i < sizeof(uint16_t); i++) {
410         tmp += (src[i] << (L2CAP_SIZE_8 * i));
411     }
412 
413     return LE2H_16(tmp);
414 }
415 
L2capAlloc(int size)416 void *L2capAlloc(int size)
417 {
418     void *p;
419 
420     p = MEM_MALLOC.alloc(size);
421     if (p != NULL) {
422         (void)memset_s(p, size, 0, size);
423     }
424 
425     return p;
426 }
427 
L2capFree(void * p)428 void L2capFree(void *p)
429 {
430     MEM_MALLOC.free(p);
431     return;
432 }
433 
L2capAsynchronousProcess(void (* task)(const void * context),void (* destroy)(void * context),void * context)434 int L2capAsynchronousProcess(void (*task)(const void *context), void (*destroy)(void *context), void *context)
435 {
436     int result;
437 
438     result = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_LA2CAP, (void (*)(void *))task, context);
439     if (result != BT_SUCCESS) {
440         if (destroy != NULL) {
441             destroy(context);
442         }
443     }
444 
445     return result;
446 }
447 
L2capBuildSignalPacket(uint16_t cid,const L2capSignalHeader * signal,const uint8_t * data)448 Packet *L2capBuildSignalPacket(uint16_t cid, const L2capSignalHeader *signal, const uint8_t *data)
449 {
450     Packet *pkt = NULL;
451     uint8_t *buff = NULL;
452 
453     pkt = PacketMalloc(0, 0, L2CAP_HEADER_LENGTH + L2CAP_SIGNAL_HEADER_LENGTH + signal->length);
454     if (pkt == NULL) {
455         return NULL;
456     }
457 
458     buff = BufferPtr(PacketContinuousPayload(pkt));
459 
460     // build Length field
461     L2capCpuToLe16(buff + 0, L2CAP_SIGNAL_HEADER_LENGTH + signal->length);
462 
463     // build cid field
464     L2capCpuToLe16(buff + L2CAP_OFFSET_2, cid);
465 
466     buff[L2CAP_OFFSET_4] = signal->code;
467     buff[L2CAP_OFFSET_5] = signal->identifier;
468 
469     L2capCpuToLe16(buff + L2CAP_OFFSET_6, signal->length);
470 
471     if (signal->length > 0) {
472         if (memcpy_s(
473             buff + L2CAP_HEADER_LENGTH + L2CAP_SIGNAL_HEADER_LENGTH, signal->length, data, signal->length) != EOK) {
474             LOG_ERROR("L2capBuildSignalPacket memcpy_s failed");
475         }
476     }
477 
478     return pkt;
479 }
480 
L2capSendCommandReject(uint16_t handle,uint16_t cid,uint8_t ident,uint16_t reason,uint16_t data[2])481 int L2capSendCommandReject(uint16_t handle, uint16_t cid, uint8_t ident, uint16_t reason, uint16_t data[2])
482 {
483     Packet *pkt = NULL;
484     uint8_t buff[12] = {0};
485     L2capSignalHeader siganl = {0};
486 
487     (void)memset_s(buff, sizeof(buff), 0, sizeof(buff));
488 
489     L2capCpuToLe16(buff + 0, reason);
490 
491     if (reason == L2CAP_COMMAND_NOT_UNDERSTOOD) {
492         siganl.length = L2CAP_SIZE_2;
493     } else if (reason == L2CAP_SIGNAL_MTU_EXCEEDED) {
494         L2capCpuToLe16(buff + L2CAP_OFFSET_2, L2CAP_SIGNAL_MTU);
495         siganl.length = L2CAP_SIZE_4;
496     } else if (reason == L2CAP_INVALID_CID_IN_REQUEST) {
497         L2capCpuToLe16(buff + L2CAP_OFFSET_2, data[0]);
498         L2capCpuToLe16(buff + L2CAP_OFFSET_4, data[1]);
499 
500         siganl.length = L2CAP_SIZE_6;
501     } else {
502         return BT_BAD_PARAM;
503     }
504 
505     siganl.code = L2CAP_COMMAND_REJECT;
506     siganl.identifier = ident;
507 
508     pkt = L2capBuildSignalPacket(cid, &siganl, buff);
509     return L2capSendPacket(handle, L2CAP_NONE_FLUSH_PACKET, pkt);
510 }
511 
L2capCreatePendingRequest(List * pendingList,uint16_t lcid,const L2capSignalHeader * signal,uint64_t timeo,AlarmCallback timerExpired)512 void L2capCreatePendingRequest(
513     List *pendingList, uint16_t lcid, const L2capSignalHeader *signal, uint64_t timeo, AlarmCallback timerExpired)
514 {
515     L2capPendingRequest *req = NULL;
516 
517     req = L2capAlloc(sizeof(L2capPendingRequest));
518     if (req == NULL) {
519         LOG_WARN("malloc failed");
520         return;
521     }
522 
523     req->lcid = lcid;
524     req->code = signal->code;
525     req->identifier = signal->identifier;
526     req->timer = AlarmCreate("", false);
527     AlarmSet(req->timer, timeo, timerExpired, req);
528 
529     ListAddLast(pendingList, req);
530     return;
531 }
532 
L2capDestroyPendingRequest(List * pendingList,uint8_t identifier)533 void L2capDestroyPendingRequest(List *pendingList, uint8_t identifier)
534 {
535     L2capPendingRequest *req = NULL;
536 
537     req = L2capGetPendingRequest(pendingList, identifier);
538     if (req != NULL) {
539         ListRemoveNode(pendingList, req);
540         AlarmCancel(req->timer);
541         AlarmDelete(req->timer);
542         L2capFree(req);
543     }
544 
545     return;
546 }
547 
L2capGetPendingRequest(List * pendingList,uint8_t identifier)548 L2capPendingRequest *L2capGetPendingRequest(List *pendingList, uint8_t identifier)
549 {
550     L2capPendingRequest *req = NULL;
551     ListNode *node = NULL;
552 
553     node = ListGetFirstNode(pendingList);
554     while (node != NULL) {
555         req = ListGetNodeData(node);
556         if (req->identifier == identifier) {
557             return req;
558         }
559 
560         node = ListGetNextNode(node);
561     }
562 
563     return NULL;
564 }
565 
L2capGetPendingRequest2(List * pendingList,const void * request)566 L2capPendingRequest *L2capGetPendingRequest2(List *pendingList, const void *request)
567 {
568     L2capPendingRequest *req = NULL;
569     ListNode *node = NULL;
570 
571     node = ListGetFirstNode(pendingList);
572     while (node != NULL) {
573         req = ListGetNodeData(node);
574         if (req == request) {
575             return req;
576         }
577 
578         node = ListGetNextNode(node);
579     }
580 
581     return NULL;
582 }
583 
L2capClearPendingRequest(List * pendingList)584 void L2capClearPendingRequest(List *pendingList)
585 {
586     L2capPendingRequest *req = NULL;
587     ListNode *node = NULL;
588 
589     while (1) {
590         node = ListGetFirstNode(pendingList);
591         if (node == NULL) {
592             break;
593         }
594 
595         req = ListGetNodeData(node);
596 
597         ListRemoveNode(pendingList, req);
598         AlarmCancel(req->timer);
599         AlarmDelete(req->timer);
600         L2capFree(req);
601     }
602 
603     return;
604 }
605 
L2capSendPacket(uint16_t handle,uint16_t flushTimeout,Packet * pkt)606 int L2capSendPacket(uint16_t handle, uint16_t flushTimeout, Packet *pkt)
607 {
608     int result;
609 
610     result = L2capSendPacketNoFree(handle, flushTimeout, pkt);
611     PacketFree(pkt);
612     return result;
613 }
614 
L2capSendPacketNoFree(uint16_t handle,uint16_t flushTimeout,Packet * pkt)615 int L2capSendPacketNoFree(uint16_t handle, uint16_t flushTimeout, Packet *pkt)
616 {
617     int result;
618 
619     if (BTM_IsControllerSupportNonFlushablePacketBoundaryFlag()) {
620         if (flushTimeout == L2CAP_NONE_FLUSH_PACKET) {
621             result = HCI_SendAclData(handle, NON_FLUSHABLE_PACKET, pkt);
622         } else {
623             result = HCI_SendAclData(handle, FLUSHABLE_PACKET, pkt);
624         }
625     } else {
626         result = HCI_SendAclData(handle, FLUSHABLE_PACKET, pkt);
627     }
628 
629     return result;
630 }
631 
L2capLeSendPacket(uint16_t handle,Packet * pkt)632 int L2capLeSendPacket(uint16_t handle, Packet *pkt)
633 {
634     int result;
635 
636     result = HCI_SendAclData(handle, NON_FLUSHABLE_PACKET, pkt);
637     PacketFree(pkt);
638     return result;
639 }
640 
L2capGetTxBufferSize()641 uint16_t L2capGetTxBufferSize()
642 {
643     uint16_t bufferSize = 0;
644 
645     BTM_GetAclDataPacketLength(&bufferSize);
646     return bufferSize;
647 }
648 
L2capLeGetTxBufferSize()649 uint16_t L2capLeGetTxBufferSize()
650 {
651     uint16_t bufferSize = 0;
652 
653     BTM_GetLeAclDataPacketLength(&bufferSize);
654     return bufferSize;
655 }
656 
L2capGetRxBufferSize()657 uint16_t L2capGetRxBufferSize()
658 {
659     return (uint16_t)L2CAP_MTU_SIZE;
660 }
661 
L2capConnectBdr(const BtAddr * addr)662 int L2capConnectBdr(const BtAddr *addr)
663 {
664     return BTM_AclConnect(addr);
665 }
666 
L2capConnectLe(const BtAddr * addr)667 int L2capConnectLe(const BtAddr *addr)
668 {
669     return BTM_LeConnect(addr);
670 }
671 
L2capConnectLeCancel(const BtAddr * addr)672 int L2capConnectLeCancel(const BtAddr *addr)
673 {
674     return BTM_LeCancelConnect(addr);
675 }
676 
L2capAddConnectionRef(uint16_t handle)677 int L2capAddConnectionRef(uint16_t handle)
678 {
679     LOG_DEBUG("L2cap Call BTM_AclAddRef, handle = 0x%04X", handle);
680     return BTM_AclAddRef(handle);
681 }
682 
L2capDisconnect(uint16_t handle,uint8_t reason)683 int L2capDisconnect(uint16_t handle, uint8_t reason)
684 {
685     LOG_DEBUG("L2cap Call BTM_AclRelease, handle = 0x%04X", handle);
686     BTM_AclRelease(handle);
687     return BT_SUCCESS;
688 }
689 
690 static BtmAclCallbacks g_btmAclCallback = {
691     .connectionComplete = L2capBdrAclConnectedCallback,
692     .disconnectionComplete = L2capAclDisconnectedCallback,
693     .leConnectionComplete = L2capLeAclConnectedCallback,
694     .leDisconnectionComplete = L2capAclDisconnectedCallback,
695 };
696 
697 static HciAclCallbacks g_hciAclCallback = {
698     L2capAclDataReceivedCallback,
699 };
700 
L2capRegisterBdr(const L2capBdrCallback * cb)701 int L2capRegisterBdr(const L2capBdrCallback *cb)
702 {
703     (void)memcpy_s(&g_l2capBdr, sizeof(L2capBdrCallback), cb, sizeof(L2capBdrCallback));
704     return BT_SUCCESS;
705 }
706 
L2capRegisterLe(const L2capLeCallback * cb)707 int L2capRegisterLe(const L2capLeCallback *cb)
708 {
709     (void)memcpy_s(&g_l2capLe, sizeof(L2capLeCallback), cb, sizeof(L2capLeCallback));
710     return BT_SUCCESS;
711 }
712 
L2capCommonStartup()713 void L2capCommonStartup()
714 {
715     if (g_fragmentationList != NULL) {
716         return;
717     }
718 
719     g_fragmentationList = ListCreate(NULL);
720 
721     BTM_RegisterAclCallbacks(&g_btmAclCallback, NULL);
722     HCI_RegisterAclCallbacks(&g_hciAclCallback);
723 
724     return;
725 }
726 
L2capCommonShutdown()727 void L2capCommonShutdown()
728 {
729     BTM_DeregisterAclCallbacks(&g_btmAclCallback);
730     HCI_DeregisterAclCallbacks(&g_hciAclCallback);
731 
732     if (g_fragmentationList != NULL) {
733         L2capFragmentationPacket *frag = NULL;
734         ListNode *node = NULL;
735 
736         while (true) {
737             node = ListGetFirstNode(g_fragmentationList);
738             if (node == NULL) {
739                 break;
740             }
741 
742             frag = ListGetNodeData(node);
743             ListRemoveNode(g_fragmentationList, frag);
744             PacketFree(frag->pkt);
745             L2capFree(frag);
746         }
747 
748         ListDelete(g_fragmentationList);
749         g_fragmentationList = NULL;
750     }
751 
752     return;
753 }
754