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 "hci_acl.h"
17 
18 #include <stdbool.h>
19 
20 #include "btstack.h"
21 #include "platform/include/allocator.h"
22 #include "platform/include/list.h"
23 #include "platform/include/mutex.h"
24 #include "platform/include/queue.h"
25 
26 #include "hci/hci.h"
27 #include "hci/hci_internal.h"
28 
29 #define PACKET_BOUNDARY_FIRST_NON_FLUSHABLE 0x00
30 #define PACKET_BOUNDARY_CONTINUING 0x01
31 #define PACKET_BOUNDARY_FIRST_FLUSHABLE 0x02
32 
33 #define BROADCAST_POINT_TO_POINT 0x00
34 #define BROADCAST_ACTIVE_SLAVE 0x01
35 
36 #define MAX_ACL_DATA_CACHE UINT32_MAX
37 
38 #pragma pack(1)
39 typedef struct {
40     uint16_t handle : 12;
41     uint16_t pbFlag : 2;
42     uint16_t bcFlag : 2;
43     uint16_t dataTotalLength;
44 } HciAclDataHeader;
45 
46 typedef struct {
47     uint16_t connectionHandle;
48     uint8_t transport;
49 } HciConnectionHandleBlock;
50 #pragma pack()
51 
52 typedef struct {
53     uint16_t connectionHandle;
54     uint16_t count;
55 } HciTxPackets;
56 
57 static uint16_t g_aclDataPacketLength = 0;
58 static uint16_t g_totalNumAclDataPackets = 0;
59 
60 static uint16_t g_numOfAclDataPackets = 0;
61 static List *g_txAclPackets = NULL;
62 static Mutex *g_numOfAclDataPacketsLock = NULL;
63 
64 static List *g_aclDataCache = NULL;
65 static Mutex *g_aclDataCacheLock = NULL;
66 
67 static bool g_sharedDataBuffers = false;
68 static uint16_t g_leAclDataPacketLength = 0;
69 static uint8_t g_totalNumLeDataPackets = 0;
70 
71 static uint8_t g_numOfLeDataPackets = 0;
72 static List *g_txLePackets = NULL;
73 static Mutex *g_numOfLeDataPacketsLock = NULL;
74 
75 static List *g_leAclDataCache = NULL;
76 static Mutex *g_leAclDataCacheLock = NULL;
77 
78 static List *g_hciAclCallbackList = NULL;
79 static Mutex *g_hciAclCallbackListLock = NULL;
80 
81 static List *g_connectionHandleList = NULL;
82 static Mutex *g_connectionHandleListLock = NULL;
83 
HciAllocConnectionHandleBlock(uint16_t connectionHandle,uint8_t transport)84 static HciConnectionHandleBlock *HciAllocConnectionHandleBlock(uint16_t connectionHandle, uint8_t transport)
85 {
86     HciConnectionHandleBlock *block = MEM_MALLOC.alloc(sizeof(HciConnectionHandleBlock));
87     if (block != NULL) {
88         block->connectionHandle = connectionHandle;
89         block->transport = transport;
90     }
91     return block;
92 }
93 
HciFreeConnectionHandleBlock(void * block)94 static void HciFreeConnectionHandleBlock(void *block)
95 {
96     MEM_MALLOC.free(block);
97 }
98 
HciFindConnectionHandleBlock(uint16_t connectionHandle)99 static HciConnectionHandleBlock *HciFindConnectionHandleBlock(uint16_t connectionHandle)
100 {
101     HciConnectionHandleBlock *block = NULL;
102 
103     ListNode *node = ListGetFirstNode(g_connectionHandleList);
104     while (node != NULL) {
105         block = ListGetNodeData(node);
106         if (block->connectionHandle == connectionHandle) {
107             break;
108         } else {
109             block = NULL;
110         }
111         node = ListGetNextNode(node);
112     }
113 
114     return block;
115 }
116 
HciAclGetTransport(uint16_t connectionHandle)117 static uint8_t HciAclGetTransport(uint16_t connectionHandle)
118 {
119     uint8_t transport = -1;
120 
121     HciConnectionHandleBlock *block = NULL;
122 
123     MutexLock(g_connectionHandleListLock);
124 
125     block = HciFindConnectionHandleBlock(connectionHandle);
126     if (block != NULL) {
127         transport = block->transport;
128     }
129 
130     MutexUnlock(g_connectionHandleListLock);
131 
132     return transport;
133 }
134 
AllocTxPacketsEntity(uint16_t connectionHandle)135 static HciTxPackets *AllocTxPacketsEntity(uint16_t connectionHandle)
136 {
137     HciTxPackets *entity = MEM_CALLOC.alloc(sizeof(HciTxPackets));
138     if (entity != NULL) {
139         entity->connectionHandle = connectionHandle;
140     }
141     return entity;
142 }
143 
FreeTxPacketsEntity(void * packet)144 static void FreeTxPacketsEntity(void *packet)
145 {
146     MEM_CALLOC.free(packet);
147 }
148 
HciInitAcl()149 void HciInitAcl()
150 {
151     g_hciAclCallbackList = ListCreate(NULL);
152     g_hciAclCallbackListLock = MutexCreate();
153 
154     g_numOfAclDataPacketsLock = MutexCreate();
155     g_aclDataCache = ListCreate(NULL);
156     g_aclDataCacheLock = MutexCreate();
157 
158     g_numOfLeDataPacketsLock = MutexCreate();
159     g_leAclDataCache = ListCreate(NULL);
160     g_leAclDataCacheLock = MutexCreate();
161 
162     g_connectionHandleList = ListCreate(HciFreeConnectionHandleBlock);
163     g_connectionHandleListLock = MutexCreate();
164 
165     g_txAclPackets = ListCreate(FreeTxPacketsEntity);
166     g_txLePackets = ListCreate(FreeTxPacketsEntity);
167 }
168 
HciCleanupCallback()169 static void HciCleanupCallback()
170 {
171     if (g_hciAclCallbackList != NULL) {
172         ListDelete(g_hciAclCallbackList);
173         g_hciAclCallbackList = NULL;
174     }
175     if (g_hciAclCallbackListLock != NULL) {
176         MutexDelete(g_hciAclCallbackListLock);
177         g_hciAclCallbackListLock = NULL;
178     }
179 }
180 
HciCleanupAclData()181 static void HciCleanupAclData()
182 {
183     if (g_numOfAclDataPacketsLock != NULL) {
184         MutexDelete(g_numOfAclDataPacketsLock);
185         g_numOfAclDataPacketsLock = NULL;
186     }
187     if (g_aclDataCache != NULL) {
188         ListNode *node = ListGetFirstNode(g_aclDataCache);
189         while (node != NULL) {
190             PacketFree(ListGetNodeData(node));
191             node = ListGetNextNode(node);
192         }
193         ListDelete(g_aclDataCache);
194         g_aclDataCache = NULL;
195     }
196     if (g_aclDataCacheLock != NULL) {
197         MutexDelete(g_aclDataCacheLock);
198         g_aclDataCacheLock = NULL;
199     }
200 }
201 
HciCleanupLeAclData()202 static void HciCleanupLeAclData()
203 {
204     if (g_numOfLeDataPacketsLock != NULL) {
205         MutexDelete(g_numOfLeDataPacketsLock);
206         g_numOfLeDataPacketsLock = NULL;
207     }
208     if (g_leAclDataCache != NULL) {
209         ListNode *node = ListGetFirstNode(g_leAclDataCache);
210         while (node != NULL) {
211             PacketFree(ListGetNodeData(node));
212             node = ListGetNextNode(node);
213         }
214         ListDelete(g_leAclDataCache);
215         g_leAclDataCache = NULL;
216     }
217     if (g_leAclDataCacheLock != NULL) {
218         MutexDelete(g_leAclDataCacheLock);
219         g_leAclDataCacheLock = NULL;
220     }
221 }
222 
HciCleanupAclHandle()223 static void HciCleanupAclHandle()
224 {
225     if (g_connectionHandleList != NULL) {
226         ListDelete(g_connectionHandleList);
227         g_connectionHandleList = NULL;
228     }
229     if (g_connectionHandleListLock != NULL) {
230         MutexDelete(g_connectionHandleListLock);
231         g_connectionHandleListLock = NULL;
232     }
233 }
234 
FindTxPacketsEntityByConnectionHandle(uint16_t connectionHandle)235 static HciTxPackets *FindTxPacketsEntityByConnectionHandle(uint16_t connectionHandle)
236 {
237     HciTxPackets *entity = NULL;
238     ListNode *node = ListGetFirstNode(g_txAclPackets);
239     while (node != NULL) {
240         entity = (HciTxPackets *)ListGetNodeData(node);
241         if (entity->connectionHandle == connectionHandle) {
242             break;
243         } else {
244             entity = NULL;
245         }
246         node = ListGetNextNode(node);
247     }
248     return entity;
249 }
250 
FindLeTxPacketsEntityByConnectionHandle(uint16_t connectionHandle)251 static HciTxPackets *FindLeTxPacketsEntityByConnectionHandle(uint16_t connectionHandle)
252 {
253     HciTxPackets *entity = NULL;
254     ListNode *node = ListGetFirstNode(g_txLePackets);
255     while (node != NULL) {
256         entity = (HciTxPackets *)ListGetNodeData(node);
257         if (entity->connectionHandle == connectionHandle) {
258             break;
259         } else {
260             entity = NULL;
261         }
262         node = ListGetNextNode(node);
263     }
264     return entity;
265 }
266 
HciAddTxAclPacket(uint16_t connectionHandle)267 static void HciAddTxAclPacket(uint16_t connectionHandle)
268 {
269     HciTxPackets *entity = FindTxPacketsEntityByConnectionHandle(connectionHandle);
270     if (entity == NULL) {
271         entity = AllocTxPacketsEntity(connectionHandle);
272         ListAddLast(g_txAclPackets, entity);
273     }
274 
275     if (entity != NULL) {
276         entity->count++;
277     }
278 }
279 
HciOnAclPacketComplete(uint16_t connectionHandle,uint16_t count)280 static void HciOnAclPacketComplete(uint16_t connectionHandle, uint16_t count)
281 {
282     HciTxPackets *entity = FindTxPacketsEntityByConnectionHandle(connectionHandle);
283     if (entity != NULL) {
284         entity->count -= count;
285     }
286 }
287 
HciAddTxLePacket(uint16_t connectionHandle)288 static void HciAddTxLePacket(uint16_t connectionHandle)
289 {
290     HciTxPackets *entity = FindLeTxPacketsEntityByConnectionHandle(connectionHandle);
291     if (entity == NULL) {
292         entity = AllocTxPacketsEntity(connectionHandle);
293         ListAddLast(g_txLePackets, entity);
294     }
295 
296     if (entity != NULL) {
297         entity->count++;
298     }
299 }
300 
HciOnLePacketComplete(uint16_t connectionHandle,uint16_t count)301 static void HciOnLePacketComplete(uint16_t connectionHandle, uint16_t count)
302 {
303     HciTxPackets *entity = FindLeTxPacketsEntityByConnectionHandle(connectionHandle);
304     if (entity != NULL) {
305         entity->count -= count;
306     }
307 }
308 
HciGetAclHandleFromPacket(const Packet * packet)309 static uint16_t HciGetAclHandleFromPacket(const Packet *packet)
310 {
311     uint16_t handle = 0;
312     Buffer *headerBuffer = PacketHead(packet);
313     HciAclDataHeader *header = BufferPtr(headerBuffer);
314     if (header != NULL) {
315         handle = header->handle;
316     }
317     return handle;
318 }
319 
HciCloseAcl()320 void HciCloseAcl()
321 {
322     if (g_txAclPackets != NULL) {
323         ListDelete(g_txAclPackets);
324         g_txAclPackets = NULL;
325     }
326     if (g_txLePackets != NULL) {
327         ListDelete(g_txLePackets);
328         g_txLePackets = NULL;
329     }
330 
331     HciCleanupCallback();
332     HciCleanupAclData();
333     HciCleanupLeAclData();
334     HciCleanupAclHandle();
335 }
336 
HCI_SetBufferSize(uint16_t packetLength,uint16_t totalPackets)337 void HCI_SetBufferSize(uint16_t packetLength, uint16_t totalPackets)
338 {
339     g_aclDataPacketLength = packetLength;
340     g_totalNumAclDataPackets = totalPackets;
341 
342     MutexLock(g_numOfAclDataPacketsLock);
343     g_numOfAclDataPackets = g_totalNumAclDataPackets;
344     MutexUnlock(g_numOfAclDataPacketsLock);
345 }
346 
HCI_SetLeBufferSize(uint16_t packetLength,uint8_t totalPackets)347 void HCI_SetLeBufferSize(uint16_t packetLength, uint8_t totalPackets)
348 {
349     if (totalPackets == 0) {
350         g_sharedDataBuffers = true;
351     } else {
352         g_sharedDataBuffers = false;
353     }
354 
355     g_leAclDataPacketLength = packetLength;
356     g_totalNumLeDataPackets = totalPackets;
357 
358     MutexLock(g_numOfLeDataPacketsLock);
359     g_numOfLeDataPackets = g_totalNumLeDataPackets;
360     MutexUnlock(g_numOfLeDataPacketsLock);
361 }
362 
HCI_RegisterAclCallbacks(const HciAclCallbacks * callbacks)363 int HCI_RegisterAclCallbacks(const HciAclCallbacks *callbacks)
364 {
365     if (callbacks == NULL) {
366         return BT_BAD_PARAM;
367     }
368     MutexLock(g_hciAclCallbackListLock);
369     ListAddLast(g_hciAclCallbackList, (void *)callbacks);
370     MutexUnlock(g_hciAclCallbackListLock);
371 
372     return BT_SUCCESS;
373 }
374 
HCI_DeregisterAclCallbacks(const HciAclCallbacks * callbacks)375 int HCI_DeregisterAclCallbacks(const HciAclCallbacks *callbacks)
376 {
377     if (callbacks == NULL) {
378         return BT_BAD_PARAM;
379     }
380     MutexLock(g_hciAclCallbackListLock);
381     ListRemoveNode(g_hciAclCallbackList, (void *)callbacks);
382     MutexUnlock(g_hciAclCallbackListLock);
383 
384     return BT_SUCCESS;
385 }
386 
HciAclPushToTxQueue(Packet * packet)387 static int HciAclPushToTxQueue(Packet *packet)
388 {
389     int reuslt = BT_SUCCESS;
390     HciPacket *hciPacket = MEM_MALLOC.alloc(sizeof(HciPacket));
391     if (hciPacket != NULL) {
392         hciPacket->type = H2C_ACLDATA;
393         hciPacket->packet = packet;
394         HciPushToTxQueue(hciPacket);
395     } else {
396         reuslt = BT_NO_MEMORY;
397     }
398     return reuslt;
399 }
400 
HciFargment(uint16_t handle,uint8_t flushable,Packet * packet,uint16_t frameLength,int * frameCount)401 static Packet **HciFargment(uint16_t handle, uint8_t flushable, Packet *packet, uint16_t frameLength, int *frameCount)
402 {
403     if (frameLength == 0) {
404         return NULL;
405     }
406 
407     size_t totalLength = PacketSize(packet);
408 
409     int count = (totalLength / frameLength) + ((totalLength % frameLength) ? 1 : 0);
410     Packet *fargmented = NULL;
411     Buffer *headerBuffer = NULL;
412     HciAclDataHeader *header = NULL;
413     Packet **fargmentedPackets = MEM_MALLOC.alloc(sizeof(Packet *) * count);
414     if (fargmentedPackets == NULL) {
415         return NULL;
416     }
417 
418     for (int i = 0; i < count; i++) {
419         fargmented = PacketMalloc(sizeof(HciAclDataHeader), 0, 0);
420         PacketFragment(packet, fargmented, frameLength);
421         headerBuffer = PacketHead(fargmented);
422         header = BufferPtr(headerBuffer);
423         if (header != NULL) {
424             header->handle = handle;
425             if (i == 0) {
426                 header->pbFlag = (flushable == NON_FLUSHABLE_PACKET) ?
427                     PACKET_BOUNDARY_FIRST_NON_FLUSHABLE : PACKET_BOUNDARY_FIRST_FLUSHABLE;
428             } else {
429                 header->pbFlag = PACKET_BOUNDARY_CONTINUING;
430             }
431             header->bcFlag = BROADCAST_POINT_TO_POINT;
432             header->dataTotalLength = PacketPayloadSize(fargmented);
433             header = NULL;
434         }
435         headerBuffer = NULL;
436         fargmentedPackets[i] = fargmented;
437         fargmented = NULL;
438     }
439     *frameCount = count;
440 
441     return fargmentedPackets;
442 }
443 
HciSendSinglePacket(uint16_t connectionHandle,Packet * packet)444 static int HciSendSinglePacket(uint16_t connectionHandle, Packet *packet)
445 {
446     int result = BT_SUCCESS;
447     if (g_numOfAclDataPackets > 0) {
448         result = HciAclPushToTxQueue(packet);
449         if (result == BT_SUCCESS) {
450             g_numOfAclDataPackets--;
451             HciAddTxAclPacket(connectionHandle);
452         }
453     } else {
454         MutexLock(g_aclDataCacheLock);
455         ListAddLast(g_aclDataCache, packet);
456         MutexUnlock(g_aclDataCacheLock);
457     }
458     return result;
459 }
460 
HciFargmentAndSendData(uint16_t handle,uint8_t flushable,Packet * packet)461 static int HciFargmentAndSendData(uint16_t handle, uint8_t flushable, Packet *packet)
462 {
463     int result = BT_SUCCESS;
464 
465     size_t totalLength = PacketSize(packet);
466     if (totalLength > g_aclDataPacketLength) {
467         int count = 0;
468         Packet **fargmentedPackets = HciFargment(handle, flushable, packet, g_aclDataPacketLength, &count);
469         if (fargmentedPackets != NULL) {
470             MutexLock(g_numOfAclDataPacketsLock);
471             for (int i = 0; i < count; i++) {
472                 HciSendSinglePacket(handle, fargmentedPackets[i]);
473             }
474             MutexUnlock(g_numOfAclDataPacketsLock);
475 
476             MEM_MALLOC.free(fargmentedPackets);
477         } else {
478             result = BT_NO_MEMORY;
479         }
480     } else {
481         Packet *aclPacket = PacketInheritMalloc(packet, sizeof(HciAclDataHeader), 0);
482         Buffer *headerBuffer = PacketHead(aclPacket);
483         HciAclDataHeader *header = BufferPtr(headerBuffer);
484         if (header != NULL) {
485             header->handle = handle;
486             header->pbFlag = (flushable == NON_FLUSHABLE_PACKET) ?
487                 PACKET_BOUNDARY_FIRST_NON_FLUSHABLE : PACKET_BOUNDARY_FIRST_FLUSHABLE;
488             header->bcFlag = BROADCAST_POINT_TO_POINT;
489             header->dataTotalLength = PacketPayloadSize(aclPacket);
490         }
491         MutexLock(g_numOfAclDataPacketsLock);
492         result = HciSendSinglePacket(handle, aclPacket);
493         MutexUnlock(g_numOfAclDataPacketsLock);
494     }
495 
496     return result;
497 }
498 
HciSendLeSinglePacket(uint16_t connectionHandle,Packet * packet)499 static int HciSendLeSinglePacket(uint16_t connectionHandle, Packet *packet)
500 {
501     int result = BT_SUCCESS;
502     if (g_numOfLeDataPackets > 0) {
503         result = HciAclPushToTxQueue(packet);
504         if (result == BT_SUCCESS) {
505             g_numOfLeDataPackets--;
506             HciAddTxLePacket(connectionHandle);
507         }
508     } else {
509         MutexLock(g_leAclDataCacheLock);
510         ListAddLast(g_leAclDataCache, packet);
511         MutexUnlock(g_leAclDataCacheLock);
512     }
513     return result;
514 }
515 
HciFargmentAndSendLeData(uint16_t handle,uint8_t flushable,Packet * packet)516 static int HciFargmentAndSendLeData(uint16_t handle, uint8_t flushable, Packet *packet)
517 {
518     int result = BT_SUCCESS;
519 
520     size_t totalLength = PacketSize(packet);
521     if (totalLength > g_leAclDataPacketLength) {
522         int count = 0;
523         Packet **fargmentedPackets = HciFargment(handle, flushable, packet, g_leAclDataPacketLength, &count);
524         if (fargmentedPackets != NULL) {
525             MutexLock(g_numOfLeDataPacketsLock);
526             for (int i = 0; i < count; i++) {
527                 HciSendLeSinglePacket(handle, fargmentedPackets[i]);
528             }
529             MutexUnlock(g_numOfLeDataPacketsLock);
530 
531             MEM_MALLOC.free(fargmentedPackets);
532         } else {
533             result = BT_NO_MEMORY;
534         }
535     } else {
536         Packet *aclPacket = PacketInheritMalloc(packet, sizeof(HciAclDataHeader), 0);
537         Buffer *headerBuffer = PacketHead(aclPacket);
538         HciAclDataHeader *header = BufferPtr(headerBuffer);
539         if (header != NULL) {
540             header->handle = handle;
541             header->pbFlag = (flushable == NON_FLUSHABLE_PACKET) ?
542                 PACKET_BOUNDARY_FIRST_NON_FLUSHABLE : PACKET_BOUNDARY_FIRST_FLUSHABLE;
543             header->bcFlag = BROADCAST_POINT_TO_POINT;
544             header->dataTotalLength = PacketPayloadSize(aclPacket);
545         }
546         MutexLock(g_numOfLeDataPacketsLock);
547         result = HciSendLeSinglePacket(handle, aclPacket);
548         MutexUnlock(g_numOfLeDataPacketsLock);
549     }
550 
551     return result;
552 }
553 
HCI_SendAclData(uint16_t handle,uint8_t flushable,Packet * packet)554 int HCI_SendAclData(uint16_t handle, uint8_t flushable, Packet *packet)
555 {
556     HciConnectionHandleBlock *block = NULL;
557 
558     uint8_t transport = 0;
559 
560     MutexLock(g_connectionHandleListLock);
561 
562     block = HciFindConnectionHandleBlock(handle);
563     if (block != NULL) {
564         transport = block->transport;
565     }
566 
567     int result;
568 
569     switch (transport) {
570         case TRANSPORT_BREDR:
571             result = HciFargmentAndSendData(handle, flushable, packet);
572             break;
573         case TRANSPORT_LE:
574             if (g_sharedDataBuffers) {
575                 result = HciFargmentAndSendData(handle, flushable, packet);
576             } else {
577                 result = HciFargmentAndSendLeData(handle, flushable, packet);
578             }
579             break;
580         default:
581             result = BT_OPERATION_FAILED;
582             break;
583     }
584 
585     MutexUnlock(g_connectionHandleListLock);
586 
587     return result;
588 }
589 
HciOnAclData(Packet * packet)590 void HciOnAclData(Packet *packet)
591 {
592     HciAclDataHeader header;
593     PacketExtractHead(packet, (uint8_t *)&header, sizeof(header));
594 
595     MutexLock(g_hciAclCallbackListLock);
596 
597     HciAclCallbacks *callback = NULL;
598     ListNode *node = ListGetFirstNode(g_hciAclCallbackList);
599     while (node != NULL) {
600         callback = ListGetNodeData(node);
601         if (callback != NULL) {
602             if (callback->onAclData != NULL) {
603                 callback->onAclData(header.handle, header.pbFlag & 0x3, header.bcFlag & 0x3, packet);
604             }
605         }
606         node = ListGetNextNode(node);
607     }
608 
609     MutexUnlock(g_hciAclCallbackListLock);
610 }
611 
HciSendCachedAclPackets()612 static void HciSendCachedAclPackets()
613 {
614     Packet *packet = NULL;
615     ListNode *node = NULL;
616 
617     while (g_numOfAclDataPackets > 0) {
618         MutexLock(g_aclDataCacheLock);
619         node = ListGetFirstNode(g_aclDataCache);
620         if (node != NULL) {
621             packet = ListGetNodeData(node);
622             ListRemoveNode(g_aclDataCache, packet);
623         } else {
624             packet = NULL;
625         }
626         MutexUnlock(g_aclDataCacheLock);
627         if (packet != NULL) {
628             uint16_t handle = HciGetAclHandleFromPacket(packet);
629             int result = HciAclPushToTxQueue(packet);
630             if (result == BT_SUCCESS) {
631                 g_numOfAclDataPackets--;
632                 HciAddTxAclPacket(handle);
633             } else {
634                 PacketFree(packet);
635             }
636         } else {
637             break;
638         }
639     }
640 }
641 
HciAclOnPacketCompleted(const HciNumberOfCompletedPackets * completedPackets)642 static void HciAclOnPacketCompleted(const HciNumberOfCompletedPackets *completedPackets)
643 {
644     MutexLock(g_numOfAclDataPacketsLock);
645     g_numOfAclDataPackets += completedPackets->numOfCompletedPackets;
646     HciOnAclPacketComplete(completedPackets->connectionHandle, completedPackets->numOfCompletedPackets);
647 
648     HciSendCachedAclPackets();
649 
650     MutexUnlock(g_numOfAclDataPacketsLock);
651 }
652 
HciSendCachedLePackets()653 static void HciSendCachedLePackets()
654 {
655     Packet *packet = NULL;
656     ListNode *node = NULL;
657 
658     while (g_numOfLeDataPackets > 0) {
659         MutexLock(g_leAclDataCacheLock);
660         node = ListGetFirstNode(g_leAclDataCache);
661         if (node != NULL) {
662             packet = ListGetNodeData(node);
663             ListRemoveNode(g_leAclDataCache, packet);
664         } else {
665             packet = NULL;
666         }
667         MutexUnlock(g_leAclDataCacheLock);
668         if (packet != NULL) {
669             uint16_t handle = HciGetAclHandleFromPacket(packet);
670             int result = HciAclPushToTxQueue(packet);
671             if (result == BT_SUCCESS) {
672                 g_numOfLeDataPackets--;
673                 HciAddTxLePacket(handle);
674             } else {
675                 PacketFree(packet);
676             }
677         } else {
678             break;
679         }
680     }
681 }
682 
HciAclOnLePacketCompleted(const HciNumberOfCompletedPackets * completedPackets)683 static void HciAclOnLePacketCompleted(const HciNumberOfCompletedPackets *completedPackets)
684 {
685     if (g_sharedDataBuffers) {
686         HciAclOnPacketCompleted(completedPackets);
687     } else {
688         MutexLock(g_numOfLeDataPacketsLock);
689         g_numOfLeDataPackets += completedPackets->numOfCompletedPackets;
690         HciOnLePacketComplete(completedPackets->connectionHandle, completedPackets->numOfCompletedPackets);
691 
692         HciSendCachedLePackets();
693 
694         MutexUnlock(g_numOfLeDataPacketsLock);
695     }
696 }
697 
HciAclOnNumberOfCompletedPacket(uint8_t numberOfHandles,const HciNumberOfCompletedPackets * list)698 void HciAclOnNumberOfCompletedPacket(uint8_t numberOfHandles, const HciNumberOfCompletedPackets *list)
699 {
700     for (int i = 0; i < numberOfHandles; i++) {
701         uint8_t transport = HciAclGetTransport(list[i].connectionHandle);
702         switch (transport) {
703             case TRANSPORT_BREDR:
704                 HciAclOnPacketCompleted(&list[i]);
705                 break;
706             case TRANSPORT_LE:
707                 HciAclOnLePacketCompleted(&list[i]);
708                 break;
709             default:
710                 break;
711         }
712     }
713 }
714 
HciAclOnConnectionComplete(uint16_t connectionHandle,uint8_t transport)715 void HciAclOnConnectionComplete(uint16_t connectionHandle, uint8_t transport)
716 {
717     HciConnectionHandleBlock *block = HciAllocConnectionHandleBlock(connectionHandle, transport);
718     if (block != NULL) {
719         MutexLock(g_connectionHandleListLock);
720         ListAddLast(g_connectionHandleList, block);
721         MutexUnlock(g_connectionHandleListLock);
722     }
723 }
724 
HciCleanupCacheByAclHandle(uint16_t connectionHandle)725 static void HciCleanupCacheByAclHandle(uint16_t connectionHandle)
726 {
727     Packet *packet = NULL;
728     Buffer *buffer = NULL;
729     HciAclDataHeader *header = NULL;
730     ListNode *node = NULL;
731 
732     MutexLock(g_aclDataCacheLock);
733 
734     node = ListGetFirstNode(g_aclDataCache);
735     while (node != NULL) {
736         packet = ListGetNodeData(node);
737         node = ListGetNextNode(node);
738         buffer = PacketHead(packet);
739         if (buffer != NULL) {
740             header = BufferPtr(buffer);
741             if ((header != NULL) && (header->handle == connectionHandle)) {
742                 ListRemoveNode(g_aclDataCache, packet);
743                 PacketFree(packet);
744             }
745         }
746     }
747 
748     MutexUnlock(g_aclDataCacheLock);
749 }
750 
HciCleanupLeCacheByAclHandle(uint16_t connectionHandle)751 static void HciCleanupLeCacheByAclHandle(uint16_t connectionHandle)
752 {
753     Packet *packet = NULL;
754     Buffer *buffer = NULL;
755     HciAclDataHeader *header = NULL;
756     ListNode *node = NULL;
757 
758     MutexLock(g_leAclDataCacheLock);
759 
760     node = ListGetFirstNode(g_leAclDataCache);
761     while (node != NULL) {
762         packet = ListGetNodeData(node);
763         node = ListGetNextNode(node);
764         buffer = PacketHead(packet);
765         if (buffer != NULL) {
766             header = BufferPtr(buffer);
767             if (header != NULL && header->handle == connectionHandle) {
768                 ListRemoveNode(g_leAclDataCache, packet);
769                 PacketFree(packet);
770             }
771         }
772     }
773 
774     MutexUnlock(g_leAclDataCacheLock);
775 }
776 
HciAclCleanCacheOnDisconnect(uint16_t connectionHandle,uint16_t transport)777 static void HciAclCleanCacheOnDisconnect(uint16_t connectionHandle, uint16_t transport)
778 {
779     if (transport == TRANSPORT_BREDR) {
780         HciCleanupCacheByAclHandle(connectionHandle);
781     } else if (transport == TRANSPORT_LE) {
782         if (g_sharedDataBuffers) {
783             HciCleanupCacheByAclHandle(connectionHandle);
784         } else {
785             HciCleanupLeCacheByAclHandle(connectionHandle);
786         }
787     }
788 }
789 
HciRecoveryNumOfAclDataPackets(uint16_t connectionHandle)790 static void HciRecoveryNumOfAclDataPackets(uint16_t connectionHandle)
791 {
792     MutexLock(g_numOfAclDataPacketsLock);
793 
794     HciTxPackets *entity = FindTxPacketsEntityByConnectionHandle(connectionHandle);
795     if (entity != NULL) {
796         g_numOfAclDataPackets += entity->count;
797         ListRemoveNode(g_txAclPackets, entity);
798     }
799 
800     MutexUnlock(g_numOfAclDataPacketsLock);
801 }
802 
HciRecoveryNumOfLeDataPackets(uint16_t connectionHandle)803 static void HciRecoveryNumOfLeDataPackets(uint16_t connectionHandle)
804 {
805     MutexLock(g_numOfLeDataPacketsLock);
806 
807     HciTxPackets *entity = FindLeTxPacketsEntityByConnectionHandle(connectionHandle);
808     if (entity != NULL) {
809         g_numOfLeDataPackets += entity->count;
810         ListRemoveNode(g_txAclPackets, entity);
811     }
812 
813     MutexUnlock(g_numOfLeDataPacketsLock);
814 }
815 
HciAclOnDisconnect(uint16_t connectionHandle)816 static void HciAclOnDisconnect(uint16_t connectionHandle)
817 {
818     HciConnectionHandleBlock *block = NULL;
819 
820     uint8_t transport = 0;
821 
822     MutexLock(g_connectionHandleListLock);
823 
824     block = HciFindConnectionHandleBlock(connectionHandle);
825     if (block != NULL) {
826         transport = block->transport;
827         ListRemoveNode(g_connectionHandleList, block);
828     }
829 
830     MutexUnlock(g_connectionHandleListLock);
831 
832     HciAclCleanCacheOnDisconnect(connectionHandle, transport);
833 
834     if (transport == TRANSPORT_BREDR) {
835         HciRecoveryNumOfAclDataPackets(connectionHandle);
836     } else if (transport == TRANSPORT_LE) {
837         if (g_sharedDataBuffers) {
838             HciRecoveryNumOfAclDataPackets(connectionHandle);
839         } else {
840             HciRecoveryNumOfLeDataPackets(connectionHandle);
841         }
842     }
843 }
844 
HciAclOnDisconnectStatus(uint16_t connectionHandle)845 void HciAclOnDisconnectStatus(uint16_t connectionHandle)
846 {
847     HciAclOnDisconnect(connectionHandle);
848 }
849 
HciAclOnDisconnectComplete(uint16_t connectionHandle)850 void HciAclOnDisconnectComplete(uint16_t connectionHandle)
851 {
852     HciAclOnDisconnect(connectionHandle);
853 }