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 }