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_le.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "l2cap_cmn.h"
23 #include "list.h"
24 #include "log.h"
25
26 #define L2CAP_LE_DEFAULT_CREDIT 0x08
27
28 #define L2CAP_LE_CHANNEL_CREDIT_NOT_FULL 0x00
29 #define L2CAP_LE_CHANNEL_CREDIT_FULL 0x01
30
31 typedef struct {
32 uint16_t lpsm;
33 L2capLeService service;
34
35 void *ctx;
36 } L2capLePsm;
37
38 typedef struct {
39 uint16_t lcid;
40 uint16_t rcid;
41
42 uint16_t lpsm;
43 uint16_t rpsm;
44
45 uint8_t connIdentifier;
46 uint8_t state;
47
48 uint8_t busyState;
49
50 L2capLeConfigInfo lcfg;
51 L2capLeConfigInfo rcfg;
52
53 List *txList;
54 Packet *rxSarPacket;
55 } L2capLeChannel;
56
57 typedef struct {
58 uint16_t aclHandle;
59 BtAddr addr;
60
61 uint8_t nextIdentifier;
62 uint8_t role;
63
64 List *chanList; // Pack struct L2capLeChannel
65
66 List *pendingList; // Pack struct L2capPendingRequest
67 } L2capLeConnection;
68
69 typedef struct {
70 L2capLeConnectionParameterUpdate cb;
71 void *ctx;
72 } L2capLeConnectionParameterUpdateContext;
73
74 typedef struct {
75 uint16_t nextLcid;
76
77 L2capLeFixChannel chanAtt;
78 L2capLeFixChannel chanSm;
79
80 L2capLeConnectionParameterUpdateContext connParamUpdate;
81
82 List *psmList; // Pack struct L2capLePsm
83 List *connList; // Pack struct L2capLeConnection
84 } L2capLeInstance;
85
86 L2capLeInstance g_l2capLeInst;
87
L2capLeInitialized()88 static int L2capLeInitialized()
89 {
90 L2capLeInstance *inst = &g_l2capLeInst;
91
92 if (inst->connList != NULL) {
93 return BT_SUCCESS;
94 }
95
96 return BT_BAD_STATUS;
97 }
98
L2capLeGetPsm(uint16_t lpsm)99 static L2capLePsm *L2capLeGetPsm(uint16_t lpsm)
100 {
101 L2capLeInstance *inst = &g_l2capLeInst;
102 L2capLePsm *lepsm = NULL;
103 ListNode *node = NULL;
104
105 node = ListGetFirstNode(inst->psmList);
106 while (node != NULL) {
107 lepsm = ListGetNodeData(node);
108 if (lepsm->lpsm == lpsm) {
109 return lepsm;
110 }
111
112 node = ListGetNextNode(node);
113 }
114
115 return NULL;
116 }
117
L2capLeGetConnection(uint16_t aclHandle)118 static L2capLeConnection *L2capLeGetConnection(uint16_t aclHandle)
119 {
120 L2capLeInstance *inst = &g_l2capLeInst;
121 L2capLeConnection *leconn = NULL;
122 ListNode *node = NULL;
123
124 node = ListGetFirstNode(inst->connList);
125 while (node != NULL) {
126 leconn = ListGetNodeData(node);
127 if (leconn->aclHandle == aclHandle) {
128 return leconn;
129 }
130
131 node = ListGetNextNode(node);
132 }
133
134 return NULL;
135 }
136
L2capLeGetConnection2(const BtAddr * addr)137 static L2capLeConnection *L2capLeGetConnection2(const BtAddr *addr)
138 {
139 L2capLeInstance *inst = &g_l2capLeInst;
140 L2capLeConnection *conn = NULL;
141 ListNode *node = NULL;
142
143 node = ListGetFirstNode(inst->connList);
144 while (node != NULL) {
145 conn = ListGetNodeData(node);
146 if (memcmp(&(conn->addr), addr, sizeof(BtAddr)) == 0) {
147 return conn;
148 }
149
150 node = ListGetNextNode(node);
151 }
152
153 return NULL;
154 }
155
L2capLeGetChannel(L2capLeConnection * conn,int16_t lcid)156 static L2capLeChannel *L2capLeGetChannel(L2capLeConnection *conn, int16_t lcid)
157 {
158 L2capLeChannel *lechan = NULL;
159 ListNode *node = NULL;
160
161 node = ListGetFirstNode(conn->chanList);
162 while (node != NULL) {
163 lechan = ListGetNodeData(node);
164 if (lechan->lcid == lcid) {
165 return lechan;
166 }
167
168 node = ListGetNextNode(node);
169 }
170
171 return NULL;
172 }
173
L2capLeGetChannel2(uint16_t lcid,L2capLeConnection ** conn,L2capLeChannel ** chan)174 static void L2capLeGetChannel2(uint16_t lcid, L2capLeConnection **conn, L2capLeChannel **chan)
175 {
176 L2capLeInstance *inst = &g_l2capLeInst;
177 ListNode *node = NULL;
178
179 node = ListGetFirstNode(inst->connList);
180 while (node != NULL) {
181 *conn = ListGetNodeData(node);
182 *chan = L2capLeGetChannel(*conn, lcid);
183 if ((*chan) != NULL) {
184 break;
185 }
186
187 node = ListGetNextNode(node);
188 }
189
190 return;
191 }
192
L2capLeGetChannel3(uint16_t aclHandle,uint16_t lcid,L2capLeConnection ** conn,L2capLeChannel ** chan)193 static void L2capLeGetChannel3(uint16_t aclHandle, uint16_t lcid, L2capLeConnection **conn, L2capLeChannel **chan)
194 {
195 *conn = L2capLeGetConnection(aclHandle);
196 if ((*conn) == NULL) {
197 return;
198 }
199
200 *chan = L2capLeGetChannel(*conn, lcid);
201 return;
202 }
203
L2capLeGetChannel4(L2capLeConnection * conn,int16_t ident)204 static L2capLeChannel *L2capLeGetChannel4(L2capLeConnection *conn, int16_t ident)
205 {
206 L2capLeChannel *chan = NULL;
207 ListNode *node = NULL;
208
209 node = ListGetFirstNode(conn->chanList);
210 while (node != NULL) {
211 chan = ListGetNodeData(node);
212 if (chan->connIdentifier == ident) {
213 return chan;
214 }
215
216 node = ListGetNextNode(node);
217 }
218
219 return NULL;
220 }
221
L2capLeGetNewLcid()222 static uint16_t L2capLeGetNewLcid()
223 {
224 L2capLeInstance *inst = &g_l2capLeInst;
225 uint16_t lcid = L2CAP_LE_MIN_CID;
226
227 if (inst->nextLcid == 0) {
228 L2capLeConnection *conn = NULL;
229 L2capLeChannel *chan = NULL;
230
231 while (1) {
232 L2capLeGetChannel2(lcid, &conn, &chan);
233 if (chan == NULL) {
234 break;
235 }
236
237 lcid += 1;
238 }
239 } else {
240 lcid = inst->nextLcid;
241
242 if (lcid == L2CAP_LE_MAX_CID) {
243 inst->nextLcid = 0;
244 } else {
245 inst->nextLcid += 1;
246 }
247 }
248
249 return lcid;
250 }
251
L2capLeNewChannel(L2capLeConnection * conn,uint16_t lpsm,uint16_t rpsm)252 static L2capLeChannel *L2capLeNewChannel(L2capLeConnection *conn, uint16_t lpsm, uint16_t rpsm)
253 {
254 L2capLeChannel *chan = NULL;
255
256 chan = L2capAlloc(sizeof(L2capLeChannel));
257 if (chan == NULL) {
258 return NULL;
259 }
260
261 chan->lcid = L2capLeGetNewLcid();
262 chan->lpsm = lpsm;
263 chan->rpsm = rpsm;
264 chan->lcfg.mps = L2capGetRxBufferSize() - L2CAP_SIZE_6;
265 chan->lcfg.credit = L2CAP_LE_DEFAULT_CREDIT;
266 chan->state = L2CAP_CHANNEL_IDLE;
267 chan->rxSarPacket = NULL;
268
269 ListAddLast(conn->chanList, chan);
270 return chan;
271 }
272
L2capLeDestroyChannel(L2capLeChannel * chan)273 static void L2capLeDestroyChannel(L2capLeChannel *chan)
274 {
275 if (chan->txList != NULL) {
276 ListNode *node = NULL;
277 Packet *pkt = NULL;
278
279 while (1) {
280 node = ListGetFirstNode(chan->txList);
281 if (node == NULL) {
282 break;
283 }
284
285 pkt = ListGetNodeData(node);
286 ListRemoveNode(chan->txList, pkt);
287 PacketFree(pkt);
288 }
289
290 ListDelete(chan->txList);
291 }
292
293 if (chan->rxSarPacket != NULL) {
294 PacketFree(chan->rxSarPacket);
295 chan->rxSarPacket = NULL;
296 }
297
298 L2capFree(chan);
299 return;
300 }
301
L2capLeDeleteChannel(L2capLeConnection * conn,L2capLeChannel * chan,uint16_t removeAcl)302 static void L2capLeDeleteChannel(L2capLeConnection *conn, L2capLeChannel *chan, uint16_t removeAcl)
303 {
304 ListRemoveNode(conn->chanList, chan);
305 L2capLeDestroyChannel(chan);
306
307 if (removeAcl) {
308 if (ListGetFirstNode(conn->chanList) == NULL) {
309 // Reason: REMOTE USER TERMINATED CONNECTION
310 L2capDisconnect(conn->aclHandle, 0x13);
311 }
312 }
313
314 return;
315 }
316
L2capLeNewConnection(const BtAddr * addr,uint16_t aclHandle,uint8_t role)317 static L2capLeConnection *L2capLeNewConnection(const BtAddr *addr, uint16_t aclHandle, uint8_t role)
318 {
319 L2capLeInstance *inst = &g_l2capLeInst;
320 L2capLeConnection *conn = NULL;
321
322 conn = L2capAlloc(sizeof(L2capLeConnection));
323 if (conn == NULL) {
324 return NULL;
325 }
326
327 (void)memcpy_s(&(conn->addr), sizeof(BtAddr), addr, sizeof(BtAddr));
328 conn->aclHandle = aclHandle;
329 conn->nextIdentifier = L2CAP_MIN_IDENTIFIER;
330 conn->role = role;
331
332 conn->chanList = ListCreate(NULL);
333 conn->pendingList = ListCreate(NULL);
334 ListAddFirst(inst->connList, conn);
335 return conn;
336 }
337
L2capLeDeleteConnection(L2capLeConnection * conn)338 static void L2capLeDeleteConnection(L2capLeConnection *conn)
339 {
340 L2capLeInstance *inst = &g_l2capLeInst;
341 ListNode *node = NULL;
342
343 if (conn->chanList != NULL) {
344 L2capLeChannel *chan = NULL;
345
346 while (1) {
347 node = ListGetFirstNode(conn->chanList);
348 if (node == NULL) {
349 break;
350 }
351
352 chan = ListGetNodeData(node);
353 ListRemoveNode(conn->chanList, chan);
354 L2capLeDestroyChannel(chan);
355 }
356
357 ListDelete(conn->chanList);
358 }
359
360 if (conn->pendingList != NULL) {
361 L2capClearPendingRequest(conn->pendingList);
362 ListDelete(conn->pendingList);
363 }
364
365 ListRemoveNode(inst->connList, conn);
366 L2capFree(conn);
367
368 // if no connection exists, reset nextLcid value
369 if (ListGetFirstNode(inst->connList) == NULL) {
370 inst->nextLcid = L2CAP_LE_MIN_CID;
371 }
372
373 return;
374 }
375
L2capLeGetNewIdentifier(L2capLeConnection * leconn)376 static uint8_t L2capLeGetNewIdentifier(L2capLeConnection *leconn)
377 {
378 uint8_t ident;
379
380 ident = leconn->nextIdentifier;
381 if (ident == L2CAP_MAX_IDENTIFIER) {
382 leconn->nextIdentifier = L2CAP_MIN_IDENTIFIER;
383 } else {
384 leconn->nextIdentifier += 1;
385 }
386
387 return ident;
388 }
389
L2capLeResponseTimeout(const void * parameter)390 static void L2capLeResponseTimeout(const void *parameter)
391 {
392 L2capLeInstance *inst = &g_l2capLeInst;
393 L2capLeConnection *conn = NULL;
394 L2capPendingRequest *lereq = NULL;
395 ListNode *node = NULL;
396
397 if (inst->connList == NULL) {
398 return;
399 }
400
401 node = ListGetFirstNode(inst->connList);
402 while (node != NULL) {
403 conn = ListGetNodeData(node);
404 lereq = L2capGetPendingRequest2(conn->pendingList, parameter);
405 if (lereq != NULL) {
406 ListRemoveNode(conn->pendingList, lereq);
407 break;
408 }
409
410 node = ListGetNextNode(node);
411 }
412
413 if (lereq == NULL) {
414 return;
415 }
416
417 if (lereq->lcid > 0) {
418 L2capLeChannel *chan = NULL;
419 L2capLePsm *psm = NULL;
420
421 chan = L2capLeGetChannel(conn, lereq->lcid);
422 if (chan != NULL) {
423 psm = L2capLeGetPsm(chan->lpsm);
424 if (psm != NULL) {
425 LOG_DEBUG(
426 "L2capCallback leDisconnectAbnormal:%{public}d begin, cid = 0x%04X, reason = 0", __LINE__, lereq->lcid);
427 psm->service.leDisconnectAbnormal(lereq->lcid, 0, psm->ctx);
428 LOG_DEBUG("L2capCallback leDisconnectAbnormal:%{public}d end", __LINE__);
429 }
430
431 L2capLeDeleteChannel(conn, chan, 1);
432 }
433 }
434
435 AlarmDelete(lereq->timer);
436 L2capFree(lereq);
437
438 return;
439 }
440
L2capLeResponseTimeoutCallback(void * parameter)441 static void L2capLeResponseTimeoutCallback(void *parameter)
442 {
443 L2capAsynchronousProcess(L2capLeResponseTimeout, NULL, parameter);
444 return;
445 }
446
L2capSendCreditBasedConnectionReq(L2capLeConnection * conn,L2capLeChannel * chan)447 static int L2capSendCreditBasedConnectionReq(L2capLeConnection *conn, L2capLeChannel *chan)
448 {
449 Packet *pkt = NULL;
450 uint8_t buff[10] = {0};
451 L2capSignalHeader signal = {0};
452
453 L2capCpuToLe16(buff + 0, chan->rpsm);
454 L2capCpuToLe16(buff + L2CAP_OFFSET_2, chan->lcid);
455 L2capCpuToLe16(buff + L2CAP_OFFSET_4, chan->lcfg.mtu);
456 L2capCpuToLe16(buff + L2CAP_OFFSET_6, chan->lcfg.mps);
457 L2capCpuToLe16(buff + L2CAP_OFFSET_8, chan->lcfg.credit);
458
459 signal.code = L2CAP_LE_CREDIT_BASED_CONNECTION_REQUEST;
460 signal.identifier = L2capLeGetNewIdentifier(conn);
461 signal.length = sizeof(buff);
462
463 chan->connIdentifier = signal.identifier;
464 pkt = L2capBuildSignalPacket(L2CAP_LE_SIGNALING_CHANNEL, &signal, buff);
465 L2capCreatePendingRequest(
466 conn->pendingList, chan->lcid, &signal, L2CAP_DEFAULT_RTX, L2capLeResponseTimeoutCallback);
467 return L2capLeSendPacket(conn->aclHandle, pkt);
468 }
469
L2capSendCreditBasedConnectionRsp(L2capLeConnection * conn,L2capLeChannel * chan,uint8_t ident,uint16_t result)470 static int L2capSendCreditBasedConnectionRsp(
471 L2capLeConnection *conn, L2capLeChannel *chan, uint8_t ident, uint16_t result)
472 {
473 Packet *pkt = NULL;
474 uint8_t buff[10] = {0};
475 L2capSignalHeader signal = {0};
476
477 L2capCpuToLe16(buff + 0, chan->lcid);
478 L2capCpuToLe16(buff + L2CAP_OFFSET_2, chan->lcfg.mtu);
479 L2capCpuToLe16(buff + L2CAP_OFFSET_4, chan->lcfg.mps);
480 L2capCpuToLe16(buff + L2CAP_OFFSET_6, chan->lcfg.credit);
481 L2capCpuToLe16(buff + L2CAP_OFFSET_8, result);
482
483 signal.code = L2CAP_LE_CREDIT_BASED_CONNECTION_RESPONSE;
484 signal.identifier = ident;
485 signal.length = sizeof(buff);
486
487 pkt = L2capBuildSignalPacket(L2CAP_LE_SIGNALING_CHANNEL, &signal, buff);
488 return L2capLeSendPacket(conn->aclHandle, pkt);
489 }
490
L2capLeSendDisconnectionReq(L2capLeConnection * conn,const L2capLeChannel * chan)491 static int L2capLeSendDisconnectionReq(L2capLeConnection *conn, const L2capLeChannel *chan)
492 {
493 Packet *pkt = NULL;
494 uint8_t buff[4] = {0};
495 L2capSignalHeader signal = {0};
496
497 L2capCpuToLe16(buff + 0, chan->rcid);
498 L2capCpuToLe16(buff + L2CAP_OFFSET_2, chan->lcid);
499
500 signal.code = L2CAP_DISCONNECTION_REQUEST;
501 signal.identifier = L2capLeGetNewIdentifier(conn);
502 signal.length = sizeof(buff);
503
504 pkt = L2capBuildSignalPacket(L2CAP_LE_SIGNALING_CHANNEL, &signal, buff);
505 L2capCreatePendingRequest(
506 conn->pendingList, chan->lcid, &signal, L2CAP_DEFAULT_RTX, L2capLeResponseTimeoutCallback);
507 return L2capLeSendPacket(conn->aclHandle, pkt);
508 }
509
L2capLeSendDisconnectionRsp(const L2capLeConnection * conn,const L2capLeChannel * chan,uint8_t ident)510 static int L2capLeSendDisconnectionRsp(const L2capLeConnection *conn, const L2capLeChannel *chan, uint8_t ident)
511 {
512 Packet *pkt = NULL;
513 uint8_t buff[4] = {0};
514 L2capSignalHeader signal = {0};
515
516 L2capCpuToLe16(buff + 0, chan->lcid);
517 L2capCpuToLe16(buff + L2CAP_OFFSET_2, chan->rcid);
518
519 signal.code = L2CAP_DISCONNECTION_RESPONSE;
520 signal.identifier = ident;
521 signal.length = sizeof(buff);
522
523 pkt = L2capBuildSignalPacket(L2CAP_LE_SIGNALING_CHANNEL, &signal, buff);
524 return L2capLeSendPacket(conn->aclHandle, pkt);
525 }
526
L2capLeSendFlowControlCredit(L2capLeConnection * conn,const L2capLeChannel * chan,uint16_t credit)527 static int L2capLeSendFlowControlCredit(L2capLeConnection *conn, const L2capLeChannel *chan, uint16_t credit)
528 {
529 Packet *pkt = NULL;
530 uint8_t buff[4] = {0};
531 L2capSignalHeader signal = {0};
532
533 L2capCpuToLe16(buff + 0, chan->lcid);
534 L2capCpuToLe16(buff + L2CAP_OFFSET_2, credit);
535
536 signal.code = L2CAP_LE_FLOW_CONTROL_CREDIT;
537 signal.identifier = L2capLeGetNewIdentifier(conn);
538 signal.length = sizeof(buff);
539
540 pkt = L2capBuildSignalPacket(L2CAP_LE_SIGNALING_CHANNEL, &signal, buff);
541 return L2capLeSendPacket(conn->aclHandle, pkt);
542 }
543
L2capLeTxWithCredit(const L2capLeConnection * conn,L2capLeChannel * chan)544 static void L2capLeTxWithCredit(const L2capLeConnection *conn, L2capLeChannel *chan)
545 {
546 ListNode *node = NULL;
547 Packet *pkt = NULL;
548
549 while (1) {
550 if (chan->rcfg.credit == 0) {
551 break;
552 }
553
554 node = ListGetFirstNode(chan->txList);
555 if (node == NULL) {
556 break;
557 }
558
559 pkt = ListGetNodeData(node);
560
561 ListRemoveNode(chan->txList, pkt);
562 L2capLeSendPacket(conn->aclHandle, pkt);
563
564 chan->rcfg.credit -= 1;
565 }
566
567 if (chan->rcfg.credit == 0) {
568 if (chan->busyState == L2CAP_LE_CHANNEL_CREDIT_NOT_FULL) {
569 L2capLePsm *psm = NULL;
570
571 chan->busyState = L2CAP_LE_CHANNEL_CREDIT_FULL;
572 psm = L2capLeGetPsm(chan->lpsm);
573 if (psm != NULL) {
574 LOG_DEBUG("L2capCallback leRemoteBusy:%{public}d begin, cid = 0x%04X, busyState = %hhu",
575 __LINE__,
576 chan->lcid,
577 chan->busyState);
578 psm->service.leRemoteBusy(chan->lcid, chan->busyState, psm->ctx);
579 LOG_DEBUG("L2capCallback leRemoteBusy:%{public}d end", __LINE__);
580 }
581 }
582 } else {
583 if (chan->busyState == L2CAP_LE_CHANNEL_CREDIT_FULL) {
584 L2capLePsm *psm = NULL;
585
586 chan->busyState = L2CAP_LE_CHANNEL_CREDIT_NOT_FULL;
587 psm = L2capLeGetPsm(chan->lpsm);
588 if (psm != NULL) {
589 LOG_DEBUG("L2capCallback leRemoteBusy:%{public}d begin, cid = 0x%04X, busyState = %hhu",
590 __LINE__,
591 chan->lcid,
592 chan->busyState);
593 psm->service.leRemoteBusy(chan->lcid, chan->busyState, psm->ctx);
594 LOG_DEBUG("L2capCallback leRemoteBusy:%{public}d end", __LINE__);
595 }
596 }
597 }
598
599 return;
600 }
601
L2capLeSegmentPacketWithCredit(const L2capLeChannel * chan,Packet * pkt)602 static void L2capLeSegmentPacketWithCredit(const L2capLeChannel *chan, Packet *pkt)
603 {
604 Packet *frag = NULL;
605 Packet *fragPkt = NULL;
606 uint16_t totalLength;
607 uint8_t *header = NULL;
608 uint16_t headerLength;
609
610 totalLength = PacketSize(pkt);
611 headerLength = L2CAP_HEADER_LENGTH + L2CAP_SIZE_2;
612 while (1) {
613 frag = PacketMalloc(0, 0, 0);
614 int remainLength = PacketFragment(pkt, frag, chan->rcfg.mps);
615
616 fragPkt = PacketInheritMalloc(frag, headerLength, 0);
617 PacketFree(frag);
618
619 header = BufferPtr(PacketHead(fragPkt));
620 L2capCpuToLe16(header + 0, PacketSize(fragPkt) - L2CAP_HEADER_LENGTH);
621 L2capCpuToLe16(header + L2CAP_OFFSET_2, chan->rcid);
622
623 if (headerLength > L2CAP_HEADER_LENGTH) {
624 L2capCpuToLe16(header + L2CAP_OFFSET_4, totalLength);
625 }
626
627 ListAddLast(chan->txList, fragPkt);
628 if (remainLength == 0) {
629 break;
630 }
631
632 headerLength = L2CAP_HEADER_LENGTH;
633 }
634
635 return;
636 }
637
L2capLeProcessConnectionParameterUpdateReq(uint16_t aclHandle,L2capSignalHeader * signal,const uint8_t * data)638 static void L2capLeProcessConnectionParameterUpdateReq(
639 uint16_t aclHandle, L2capSignalHeader *signal, const uint8_t *data)
640 {
641 L2capLeInstance *inst = &g_l2capLeInst;
642 L2capLeConnection *conn = NULL;
643 L2capLeConnectionParameter param = {0};
644
645 conn = L2capLeGetConnection(aclHandle);
646 if (conn == NULL) {
647 return;
648 }
649
650 if (conn->role == L2CAP_LE_ROLE_SLAVE) {
651 L2capSendCommandReject(
652 aclHandle, L2CAP_LE_SIGNALING_CHANNEL, signal->identifier, L2CAP_COMMAND_NOT_UNDERSTOOD, NULL);
653 return;
654 }
655
656 param.connIntervalMin = L2capLe16ToCpu(data + 0);
657 param.connIntervalMax = L2capLe16ToCpu(data + L2CAP_OFFSET_2);
658 param.connLatency = L2capLe16ToCpu(data + L2CAP_OFFSET_4);
659 param.supervisionTimeout = L2capLe16ToCpu(data + L2CAP_OFFSET_6);
660
661 if (inst->connParamUpdate.cb.recvLeConnectionParameterUpdateReq != NULL) {
662 LOG_DEBUG("L2capCallback recvLeConnectionParameterUpdateReq:%{public}d begin", __LINE__);
663 inst->connParamUpdate.cb.recvLeConnectionParameterUpdateReq(
664 aclHandle, signal->identifier, ¶m, inst->connParamUpdate.ctx);
665 LOG_DEBUG("L2capCallback recvLeConnectionParameterUpdateReq:%{public}d end", __LINE__);
666 }
667
668 return;
669 }
670
L2capLeProcessConnectionParameterUpdateRsp(uint16_t aclHandle,L2capSignalHeader * signal,const uint8_t * data)671 static void L2capLeProcessConnectionParameterUpdateRsp(
672 uint16_t aclHandle, L2capSignalHeader *signal, const uint8_t *data)
673 {
674 L2capLeInstance *inst = &g_l2capLeInst;
675 L2capLeConnection *conn = NULL;
676 uint16_t result;
677
678 conn = L2capLeGetConnection(aclHandle);
679 if (conn == NULL) {
680 return;
681 }
682
683 L2capDestroyPendingRequest(conn->pendingList, signal->identifier);
684 result = L2capLe16ToCpu(data + 0);
685
686 if (inst->connParamUpdate.cb.recvLeConnectionParameterUpdateRsp != NULL) {
687 LOG_DEBUG("L2capCallback recvLeConnectionParameterUpdateRsp:%{public}d begin", __LINE__);
688 inst->connParamUpdate.cb.recvLeConnectionParameterUpdateRsp(aclHandle, result, inst->connParamUpdate.ctx);
689 LOG_DEBUG("L2capCallback recvLeConnectionParameterUpdateRsp:%{public}d end", __LINE__);
690 }
691
692 return;
693 }
694
L2capLeProcessCreditBasedConnectionReq(uint16_t aclHandle,const L2capSignalHeader * signal,const uint8_t * data)695 static void L2capLeProcessCreditBasedConnectionReq(
696 uint16_t aclHandle, const L2capSignalHeader *signal, const uint8_t *data)
697 {
698 L2capLeConnection *conn = NULL;
699 L2capLeChannel *chan = NULL;
700 L2capLePsm *psm = NULL;
701 uint16_t lpsm;
702 uint16_t rcid;
703 L2capLeConfigInfo cfg = {0};
704 L2capConnectionInfo connInfo = {0};
705
706 conn = L2capLeGetConnection(aclHandle);
707 if (conn == NULL) {
708 return;
709 }
710
711 lpsm = L2capLe16ToCpu(data + 0);
712 rcid = L2capLe16ToCpu(data + L2CAP_OFFSET_2);
713 cfg.mtu = L2capLe16ToCpu(data + L2CAP_OFFSET_4);
714 cfg.mps = L2capLe16ToCpu(data + L2CAP_OFFSET_6);
715 cfg.credit = L2capLe16ToCpu(data + L2CAP_OFFSET_8);
716
717 psm = L2capLeGetPsm(lpsm);
718 if (psm == NULL) {
719 L2capLeChannel tchan = {0};
720
721 tchan.lcid = 0;
722 (void)memcpy_s(&(tchan.lcfg), sizeof(L2capLeConfigInfo), &cfg, sizeof(L2capLeConfigInfo));
723 L2capSendCreditBasedConnectionRsp(conn, &tchan, signal->identifier, L2CAP_LE_PSM_NOT_SUPPORTED);
724 return;
725 }
726
727 chan = L2capLeNewChannel(conn, lpsm, lpsm);
728 chan->rcid = rcid;
729 chan->connIdentifier = signal->identifier;
730
731 chan->rcfg.mtu = cfg.mtu;
732 chan->rcfg.mps = cfg.mps;
733 chan->rcfg.credit = cfg.credit;
734 if (chan->rcfg.mps > (L2capLeGetTxBufferSize() - L2CAP_SIZE_6)) {
735 chan->rcfg.mps = L2capLeGetTxBufferSize() - L2CAP_SIZE_6;
736 }
737
738 chan->state = L2CAP_CHANNEL_CONNECT_IN_REQ;
739
740 LOG_DEBUG(
741 "L2capCallback recvLeCreditBasedConnectionReq:%{public}d begin, aclHandle = %hu, cid = 0x%04X, id = %hhu, lpsm = %hu",
742 __LINE__,
743 aclHandle,
744 chan->lcid,
745 signal->identifier,
746 psm->lpsm);
747
748 connInfo.handle = aclHandle;
749 (void)memcpy_s(&(connInfo.addr), sizeof(BtAddr), &(conn->addr), sizeof(BtAddr));
750 psm->service.recvLeCreditBasedConnectionReq(chan->lcid, signal->identifier, &connInfo, &cfg, psm->ctx);
751 LOG_DEBUG("L2capCallback recvLeCreditBasedConnectionReq:%{public}d end", __LINE__);
752
753 return;
754 }
755
L2capLeProcessCreditBasedConnectionRsp(uint16_t aclHandle,const L2capSignalHeader * signal,const uint8_t * data)756 static void L2capLeProcessCreditBasedConnectionRsp(
757 uint16_t aclHandle, const L2capSignalHeader *signal, const uint8_t *data)
758 {
759 L2capLeConnection *conn = NULL;
760 L2capLeChannel *chan = NULL;
761 L2capLePsm *psm = NULL;
762 uint16_t lcid = 0;
763 uint16_t rcid;
764 uint16_t result;
765 L2capLeConfigInfo cfg = {0};
766 L2capConnectionInfo connInfo = {0};
767
768 conn = L2capLeGetConnection(aclHandle);
769 if (conn == NULL) {
770 return;
771 }
772
773 L2capDestroyPendingRequest(conn->pendingList, signal->identifier);
774
775 rcid = L2capLe16ToCpu(data + 0);
776 cfg.mtu = L2capLe16ToCpu(data + L2CAP_OFFSET_2);
777 cfg.mps = L2capLe16ToCpu(data + L2CAP_OFFSET_4);
778 cfg.credit = L2capLe16ToCpu(data + L2CAP_OFFSET_6);
779 result = L2capLe16ToCpu(data + L2CAP_OFFSET_8);
780
781 chan = L2capLeGetChannel4(conn, signal->identifier);
782 if (chan == NULL) {
783 return;
784 }
785
786 chan->rcid = rcid;
787 lcid = chan->lcid;
788
789 chan->rcfg.mtu = cfg.mtu;
790 chan->rcfg.mps = cfg.mps;
791 chan->rcfg.credit = cfg.credit;
792 if (chan->rcfg.mps > (L2capLeGetTxBufferSize() - L2CAP_SIZE_6)) {
793 chan->rcfg.mps = L2capLeGetTxBufferSize() - L2CAP_SIZE_6;
794 }
795
796 psm = L2capLeGetPsm(chan->lpsm);
797
798 if (result == L2CAP_LE_CONNECTION_SUCCESSFUL) {
799 chan->state = L2CAP_CHANNEL_CONNECTED;
800 } else {
801 L2capLeDeleteChannel(conn, chan, 1);
802 }
803
804 if (psm != NULL) {
805 LOG_DEBUG("L2capCallback recvLeCreditBasedConnectionRsp:begin, cid = 0x%04X, result = %hu", lcid, result);
806
807 connInfo.handle = aclHandle;
808 (void)memcpy_s(&(connInfo.addr), sizeof(BtAddr), &(conn->addr), sizeof(BtAddr));
809 psm->service.recvLeCreditBasedConnectionRsp(lcid, &connInfo, &cfg, result, psm->ctx);
810 LOG_DEBUG("L2capCallback recvLeCreditBasedConnectionRsp:%{public}d end", __LINE__);
811 }
812
813 return;
814 }
815
L2capLeProcessDisconnectionReq(uint16_t aclHandle,const L2capSignalHeader * signal,const uint8_t * data)816 static void L2capLeProcessDisconnectionReq(uint16_t aclHandle, const L2capSignalHeader *signal, const uint8_t *data)
817 {
818 L2capLeConnection *conn = NULL;
819 L2capLeChannel *chan = NULL;
820 uint16_t lcid;
821 uint16_t rcid;
822 L2capLePsm *psm = NULL;
823
824 conn = L2capLeGetConnection(aclHandle);
825 if (conn == NULL) {
826 return;
827 }
828
829 lcid = L2capLe16ToCpu(data + 0);
830 rcid = L2capLe16ToCpu(data + L2CAP_OFFSET_2);
831
832 chan = L2capLeGetChannel(conn, lcid);
833 if (chan == NULL) {
834 uint16_t rejCid[L2CAP_SIZE_2] = {lcid, rcid};
835
836 L2capSendCommandReject(
837 aclHandle, L2CAP_LE_SIGNALING_CHANNEL, signal->identifier, L2CAP_INVALID_CID_IN_REQUEST, rejCid);
838 return;
839 }
840
841 // this case is for both side call disconnect at same time
842 if (chan->state == L2CAP_CHANNEL_DISCONNECT_OUT_REQ) {
843 L2capLeSendDisconnectionRsp(conn, chan, signal->identifier);
844 return;
845 }
846
847 chan->state = L2CAP_CHANNEL_DISCONNECT_IN_REQ;
848
849 psm = L2capLeGetPsm(chan->lpsm);
850 if (psm != NULL) {
851 LOG_DEBUG("L2capCallback recvLeDisconnectionReq:%{public}d begin, cid = 0x%04X, id = %hhu",
852 __LINE__,
853 lcid,
854 signal->identifier);
855 psm->service.recvLeDisconnectionReq(lcid, signal->identifier, psm->ctx);
856 LOG_DEBUG("L2capCallback recvLeDisconnectionReq:%{public}d end", __LINE__);
857 }
858
859 return;
860 }
861
L2capLeProcessDisconnectionRsp(uint16_t aclHandle,const L2capSignalHeader * signal,const uint8_t * data)862 static void L2capLeProcessDisconnectionRsp(uint16_t aclHandle, const L2capSignalHeader *signal, const uint8_t *data)
863 {
864 L2capLeConnection *conn = NULL;
865 L2capLeChannel *chan = NULL;
866 L2capLePsm *psm = NULL;
867 uint16_t lcid;
868 uint16_t rcid;
869
870 conn = L2capLeGetConnection(aclHandle);
871 if (conn == NULL) {
872 return;
873 }
874
875 L2capDestroyPendingRequest(conn->pendingList, signal->identifier);
876
877 rcid = L2capLe16ToCpu(data + 0);
878 lcid = L2capLe16ToCpu(data + L2CAP_OFFSET_2);
879
880 chan = L2capLeGetChannel(conn, lcid);
881 if (chan == NULL) {
882 return;
883 }
884
885 if (chan->rcid != rcid) {
886 return;
887 }
888
889 psm = L2capLeGetPsm(chan->lpsm);
890
891 L2capLeDeleteChannel(conn, chan, 1);
892
893 if (psm != NULL) {
894 LOG_DEBUG("L2capCallback recvLeDisconnectionRsp:%{public}d begin, cid = 0x%04X", __LINE__, lcid);
895 psm->service.recvLeDisconnectionRsp(lcid, psm->ctx);
896 LOG_DEBUG("L2capCallback recvLeDisconnectionRsp:%{public}d end", __LINE__);
897 }
898
899 return;
900 }
901
L2capLeProcessFlowControlCredit(uint16_t aclHandle,const L2capSignalHeader * signal,const uint8_t * data)902 static void L2capLeProcessFlowControlCredit(uint16_t aclHandle, const L2capSignalHeader *signal, const uint8_t *data)
903 {
904 L2capLeConnection *conn = NULL;
905 L2capLeChannel *chan = NULL;
906 uint16_t lcid;
907 uint16_t credit;
908
909 conn = L2capLeGetConnection(aclHandle);
910 if (conn == NULL) {
911 return;
912 }
913
914 lcid = L2capLe16ToCpu(data + 0);
915 credit = L2capLe16ToCpu(data + L2CAP_OFFSET_2);
916
917 chan = L2capLeGetChannel(conn, lcid);
918 if (chan == NULL) {
919 return;
920 }
921
922 if (chan->rcfg.credit > (UINT16_MAX - credit)) {
923 L2capLeSendDisconnectionReq(conn, chan);
924 return;
925 }
926
927 chan->rcfg.credit += credit;
928
929 L2capLeTxWithCredit(conn, chan);
930 return;
931 }
932
L2capLeSignal(uint16_t aclHandle,L2capSignalHeader * signal,const uint8_t * data)933 static void L2capLeSignal(uint16_t aclHandle, L2capSignalHeader *signal, const uint8_t *data)
934 {
935 switch (signal->code) {
936 case L2CAP_LE_CREDIT_BASED_CONNECTION_REQUEST:
937 L2capLeProcessCreditBasedConnectionReq(aclHandle, signal, data);
938 break;
939 case L2CAP_LE_CREDIT_BASED_CONNECTION_RESPONSE:
940 L2capLeProcessCreditBasedConnectionRsp(aclHandle, signal, data);
941 break;
942 case L2CAP_DISCONNECTION_REQUEST:
943 L2capLeProcessDisconnectionReq(aclHandle, signal, data);
944 break;
945 case L2CAP_DISCONNECTION_RESPONSE:
946 L2capLeProcessDisconnectionRsp(aclHandle, signal, data);
947 break;
948 case L2CAP_LE_FLOW_CONTROL_CREDIT:
949 L2capLeProcessFlowControlCredit(aclHandle, signal, data);
950 break;
951 case L2CAP_CONNECTION_PARAMETER_UPDATE_REQUEST:
952 L2capLeProcessConnectionParameterUpdateReq(aclHandle, signal, data);
953 break;
954 case L2CAP_CONNECTION_PARAMETER_UPDATE_RESPONSE:
955 L2capLeProcessConnectionParameterUpdateRsp(aclHandle, signal, data);
956 break;
957 case L2CAP_COMMAND_REJECT:
958 break;
959 default:
960 L2capSendCommandReject(
961 aclHandle, L2CAP_LE_SIGNALING_CHANNEL, signal->identifier, L2CAP_COMMAND_NOT_UNDERSTOOD, NULL);
962 break;
963 }
964 return;
965 }
966
L2capLeProcessSignal(uint16_t aclHandle,const Packet * pkt)967 static void L2capLeProcessSignal(uint16_t aclHandle, const Packet *pkt)
968 {
969 uint8_t buff[L2CAP_SIGNAL_MTU] = {0};
970 uint16_t length;
971 L2capSignalHeader signal = {0};
972
973 length = PacketSize(pkt);
974 if (length > L2CAP_SIGNAL_MTU) {
975 PacketRead(pkt, buff, 0, L2CAP_SIGNAL_HEADER_LENGTH);
976 L2capSendCommandReject(aclHandle, L2CAP_LE_SIGNALING_CHANNEL, buff[1], L2CAP_SIGNAL_MTU_EXCEEDED, NULL);
977 return;
978 }
979
980 if (length < L2CAP_SIGNAL_HEADER_LENGTH) {
981 PacketRead(pkt, buff, 0, L2CAP_SIGNAL_HEADER_LENGTH);
982 L2capSendCommandReject(aclHandle, L2CAP_LE_SIGNALING_CHANNEL, buff[1], L2CAP_COMMAND_NOT_UNDERSTOOD, NULL);
983 return;
984 }
985
986 PacketRead(pkt, buff, 0, length);
987 signal.code = buff[0];
988 signal.identifier = buff[1];
989 signal.length = L2capLe16ToCpu(buff + L2CAP_OFFSET_2);
990
991 if (signal.length != (length - L2CAP_SIGNAL_HEADER_LENGTH)) {
992 L2capSendCommandReject(
993 aclHandle, L2CAP_LE_SIGNALING_CHANNEL, signal.identifier, L2CAP_COMMAND_NOT_UNDERSTOOD, NULL);
994 return;
995 }
996
997 L2capLeSignal(aclHandle, &signal, buff + L2CAP_SIGNAL_HEADER_LENGTH);
998 return;
999 }
1000
L2capLeProcessFixChannelData(uint16_t aclHandle,uint16_t cid,const Packet * pkt)1001 static void L2capLeProcessFixChannelData(uint16_t aclHandle, uint16_t cid, const Packet *pkt)
1002 {
1003 L2capLeInstance *inst = &g_l2capLeInst;
1004 L2capLeConnection *conn = NULL;
1005
1006 conn = L2capLeGetConnection(aclHandle);
1007 if (conn == NULL) {
1008 LOG_ERROR("L2cap fix channel recvData but connection not found");
1009 return;
1010 }
1011
1012 LOG_DEBUG("L2capCallback fix channel recvData:%{public}d begin, cid = 0x%04X", __LINE__, cid);
1013 if (cid == L2CAP_LE_ATTRIBUTE_PROTOCOL) {
1014 if (inst->chanAtt.recvLeData != NULL) {
1015 inst->chanAtt.recvLeData(aclHandle, pkt);
1016 }
1017 } else if (cid == L2CAP_LE_SECURITY_MANAGER_PROTOCOL) {
1018 if (inst->chanSm.recvLeData != NULL) {
1019 inst->chanSm.recvLeData(aclHandle, pkt);
1020 }
1021 }
1022 LOG_DEBUG("L2capCallback fix channel recvData:%{public}d end", __LINE__);
1023
1024 return;
1025 }
1026
L2capLeDataCallback(const L2capLeChannel * chan,Packet * pkt)1027 static void L2capLeDataCallback(const L2capLeChannel *chan, Packet *pkt)
1028 {
1029 L2capLePsm *psm = NULL;
1030
1031 psm = L2capLeGetPsm(chan->lpsm);
1032 if (psm == NULL) {
1033 return;
1034 }
1035
1036 LOG_DEBUG("L2capCallback recvLeData:%{public}d begin, cid = 0x%04X", __LINE__, chan->lcid);
1037 psm->service.recvLeData(chan->lcid, pkt, psm->ctx);
1038 LOG_DEBUG("L2capCallback recvLeData:%{public}d end", __LINE__);
1039 return;
1040 }
1041
L2capLeProcessLeData(uint16_t aclHandle,uint16_t cid,Packet * pkt)1042 static void L2capLeProcessLeData(uint16_t aclHandle, uint16_t cid, Packet *pkt)
1043 {
1044 L2capLeConnection *conn = NULL;
1045 L2capLeChannel *chan = NULL;
1046 uint8_t header[2] = {0};
1047 uint16_t length;
1048
1049 L2capLeGetChannel3(aclHandle, cid, &conn, &chan);
1050 if (chan == NULL) {
1051 return;
1052 }
1053
1054 if (chan->state != L2CAP_CHANNEL_CONNECTED) {
1055 return;
1056 }
1057
1058 if (chan->rxSarPacket != NULL) {
1059 PacketAssemble(chan->rxSarPacket, pkt);
1060
1061 PacketRead(chan->rxSarPacket, header, 0, sizeof(header));
1062 length = L2capLe16ToCpu(header + 0);
1063 if (PacketSize(chan->rxSarPacket) == (size_t)(length + L2CAP_SIZE_2)) {
1064 PacketExtractHead(chan->rxSarPacket, header, sizeof(header));
1065
1066 L2capLeDataCallback(chan, chan->rxSarPacket);
1067 PacketFree(chan->rxSarPacket);
1068 chan->rxSarPacket = NULL;
1069 }
1070 } else {
1071 PacketRead(pkt, header, 0, sizeof(header));
1072 length = L2capLe16ToCpu(header + 0);
1073 if (PacketSize(pkt) == (size_t)(length + L2CAP_SIZE_2)) {
1074 PacketExtractHead(pkt, header, sizeof(header));
1075
1076 L2capLeDataCallback(chan, pkt);
1077 } else {
1078 chan->rxSarPacket = PacketRefMalloc(pkt);
1079 }
1080 }
1081
1082 L2capLeSendFlowControlCredit(conn, chan, 1);
1083 return;
1084 }
1085
L2capLeReceivePacket(uint16_t handle,uint16_t cid,Packet * pkt)1086 static int L2capLeReceivePacket(uint16_t handle, uint16_t cid, Packet *pkt)
1087 {
1088 uint8_t header[4] = {0};
1089
1090 if (L2capLeInitialized() != BT_SUCCESS) {
1091 return BT_BAD_STATUS;
1092 }
1093
1094 PacketExtractHead(pkt, header, sizeof(header));
1095 switch (cid) {
1096 case L2CAP_LE_SIGNALING_CHANNEL:
1097 L2capLeProcessSignal(handle, pkt);
1098 break;
1099 case L2CAP_LE_ATTRIBUTE_PROTOCOL: // dummy
1100 case L2CAP_LE_SECURITY_MANAGER_PROTOCOL:
1101 L2capLeProcessFixChannelData(handle, cid, pkt);
1102 break;
1103 default:
1104 L2capLeProcessLeData(handle, cid, pkt);
1105 break;
1106 }
1107
1108 return 0;
1109 }
1110
L2capLeCleanAllChannels(L2capLeConnection * conn,uint8_t status)1111 static void L2capLeCleanAllChannels(L2capLeConnection *conn, uint8_t status)
1112 {
1113 L2capLeChannel *chan = NULL;
1114 L2capLePsm *psm = NULL;
1115 ListNode *node = NULL;
1116
1117 while (1) {
1118 node = ListGetFirstNode(conn->chanList);
1119 if (node == NULL) {
1120 break;
1121 }
1122
1123 chan = ListGetNodeData(node);
1124
1125 psm = L2capLeGetPsm(chan->lpsm);
1126 if (psm != NULL) {
1127 LOG_DEBUG("L2capCallback leDisconnectAbnormal:%{public}d begin, cid = 0x%04X, reason = %hhu",
1128 __LINE__,
1129 chan->lcid,
1130 status);
1131 psm->service.leDisconnectAbnormal(chan->lcid, status, psm->ctx);
1132 LOG_DEBUG("L2capCallback leDisconnectAbnormal:%{public}d end", __LINE__);
1133 }
1134
1135 ListRemoveNode(conn->chanList, chan);
1136 L2capLeDestroyChannel(chan);
1137 }
1138
1139 return;
1140 }
1141
L2capLeAclDisconnectProcess(L2capLeConnection * conn,uint8_t status,uint8_t reason)1142 static void L2capLeAclDisconnectProcess(L2capLeConnection *conn, uint8_t status, uint8_t reason)
1143 {
1144 L2capLeInstance *inst = &g_l2capLeInst;
1145
1146 LOG_DEBUG("L2capCallback leDisconnected:%{public}d begin, aclHandle = 0x%04X, status = %hhu, reason = %hhu",
1147 __LINE__,
1148 conn->aclHandle,
1149 status,
1150 reason);
1151 if (inst->chanAtt.leDisconnected != NULL) {
1152 inst->chanAtt.leDisconnected(conn->aclHandle, status, reason);
1153 }
1154
1155 if (inst->chanSm.leDisconnected != NULL) {
1156 inst->chanSm.leDisconnected(conn->aclHandle, status, reason);
1157 }
1158 LOG_DEBUG("L2capCallback leDisconnected:%{public}d end", __LINE__);
1159
1160 if (status == 0) {
1161 L2capLeCleanAllChannels(conn, status);
1162 }
1163 return;
1164 }
1165
L2capLeAclConnectProcess(L2capLeConnection * conn)1166 static void L2capLeAclConnectProcess(L2capLeConnection *conn)
1167 {
1168 L2capLeChannel *chan = NULL;
1169 ListNode *node = NULL;
1170
1171 node = ListGetFirstNode(conn->chanList);
1172 while (node != NULL) {
1173 chan = ListGetNodeData(node);
1174 if (chan->state == L2CAP_CHANNEL_CONNECT_OUT_REQ) {
1175 L2capSendCreditBasedConnectionReq(conn, chan);
1176 }
1177
1178 node = ListGetNextNode(node);
1179 }
1180
1181 return;
1182 }
1183
L2capLeConnectComplete(const BtAddr * addr,uint16_t handle,uint8_t role,uint8_t status)1184 static int L2capLeConnectComplete(const BtAddr *addr, uint16_t handle, uint8_t role, uint8_t status)
1185 {
1186 L2capLeInstance *inst = &g_l2capLeInst;
1187 L2capLeConnection *conn = NULL;
1188
1189 if (L2capLeInitialized() != BT_SUCCESS) {
1190 return BT_BAD_STATUS;
1191 }
1192
1193 LOG_DEBUG("L2capCallback leConnected:%{public}d begin, aclHandle = 0x%04X, role = %hhu, status = %hhu",
1194 __LINE__,
1195 handle,
1196 role,
1197 status);
1198
1199 if (inst->chanAtt.leConnected != NULL) {
1200 inst->chanAtt.leConnected(addr, handle, role, status);
1201 }
1202
1203 if (inst->chanSm.leConnected != NULL) {
1204 inst->chanSm.leConnected(addr, handle, role, status);
1205 }
1206 LOG_DEBUG("L2capCallback leConnected:%{public}d end", __LINE__);
1207
1208 if (status != 0) {
1209 conn = L2capLeGetConnection2(addr);
1210 if (conn != NULL) {
1211 L2capLeCleanAllChannels(conn, status);
1212 L2capLeDeleteConnection(conn);
1213 }
1214
1215 return BT_BAD_STATUS;
1216 }
1217
1218 conn = L2capLeGetConnection2(addr);
1219 if (conn == NULL) {
1220 conn = L2capLeNewConnection(addr, handle, role);
1221 }
1222
1223 conn->aclHandle = handle;
1224 conn->role = role;
1225 L2capAddConnectionRef(handle);
1226 L2capLeAclConnectProcess(conn);
1227
1228 return BT_SUCCESS;
1229 }
1230
L2capLeDisconnectComplete(uint16_t handle,uint8_t status,uint8_t reason)1231 static int L2capLeDisconnectComplete(uint16_t handle, uint8_t status, uint8_t reason)
1232 {
1233 L2capLeConnection *conn = NULL;
1234
1235 if (L2capLeInitialized() != BT_SUCCESS) {
1236 return BT_BAD_STATUS;
1237 }
1238
1239 conn = L2capLeGetConnection(handle);
1240 if (conn == NULL) {
1241 LOG_ERROR("L2capLeDisconnectComplete but connection not found");
1242 return BT_BAD_PARAM;
1243 }
1244
1245 L2capLeAclDisconnectProcess(conn, status, reason);
1246
1247 if (status == 0) {
1248 L2capLeDeleteConnection(conn);
1249 }
1250
1251 return BT_SUCCESS;
1252 }
1253
L2CAP_LeCreditBasedConnectionReq(const BtAddr * addr,uint16_t lpsm,uint16_t rpsm,const L2capLeConfigInfo * cfg,uint16_t * lcid)1254 int L2CAP_LeCreditBasedConnectionReq(
1255 const BtAddr *addr, uint16_t lpsm, uint16_t rpsm, const L2capLeConfigInfo *cfg, uint16_t *lcid)
1256 {
1257 L2capLeConnection *conn = NULL;
1258 L2capLeChannel *chan = NULL;
1259 L2capLePsm *psm = NULL;
1260
1261 LOG_INFO("%{public}s:%{public}d enter, lpsm = 0x%04X, rpsm = 0x%04X", __FUNCTION__, __LINE__, lpsm, rpsm);
1262
1263 if (L2capLeInitialized() != BT_SUCCESS) {
1264 return BT_BAD_STATUS;
1265 }
1266
1267 if ((addr == NULL) || (lcid == NULL) || (cfg == NULL)) {
1268 return BT_BAD_PARAM;
1269 }
1270
1271 if (cfg->mtu < L2CAP_LE_MIN_MTU) {
1272 return BT_BAD_PARAM;
1273 }
1274
1275 psm = L2capLeGetPsm(lpsm);
1276 if (psm == NULL) {
1277 return BT_BAD_PARAM;
1278 }
1279
1280 conn = L2capLeGetConnection2(addr);
1281 if (conn == NULL) {
1282 conn = L2capLeNewConnection(addr, 0, 0);
1283 }
1284
1285 chan = L2capLeNewChannel(conn, lpsm, rpsm);
1286 chan->state = L2CAP_CHANNEL_CONNECT_OUT_REQ;
1287
1288 chan->lcfg.mtu = cfg->mtu;
1289 if (cfg->credit != 0) {
1290 chan->lcfg.credit = cfg->credit;
1291 }
1292 if (chan->lcfg.mps > cfg->mtu) {
1293 chan->lcfg.mps = cfg->mtu;
1294 }
1295
1296 *lcid = chan->lcid;
1297
1298 if (conn->aclHandle == 0) {
1299 int result;
1300
1301 result = L2capConnectLe(addr);
1302 if (result != BT_SUCCESS) {
1303 L2capLeDeleteConnection(conn);
1304 }
1305
1306 return result;
1307 }
1308
1309 L2capSendCreditBasedConnectionReq(conn, chan);
1310 return BT_SUCCESS;
1311 }
1312
L2CAP_LeCreditBasedConnectionRsp(uint16_t lcid,uint8_t id,const L2capLeConfigInfo * cfg,uint16_t result)1313 int L2CAP_LeCreditBasedConnectionRsp(uint16_t lcid, uint8_t id, const L2capLeConfigInfo *cfg, uint16_t result)
1314 {
1315 L2capLeConnection *conn = NULL;
1316 L2capLeChannel *chan = NULL;
1317
1318 LOG_INFO("%{public}s:%{public}d enter, lcid = 0x%04X, id = %hhu, result = %hu", __FUNCTION__, __LINE__, lcid, id, result);
1319
1320 if (L2capLeInitialized() != BT_SUCCESS) {
1321 return BT_BAD_STATUS;
1322 }
1323
1324 if (cfg == NULL) {
1325 return BT_BAD_PARAM;
1326 }
1327
1328 if (cfg->mtu < L2CAP_LE_MIN_MTU) {
1329 return BT_BAD_PARAM;
1330 }
1331
1332 L2capLeGetChannel2(lcid, &conn, &chan);
1333 if (chan == NULL) {
1334 return BT_BAD_PARAM;
1335 }
1336
1337 if (chan->state != L2CAP_CHANNEL_CONNECT_IN_REQ) {
1338 return BT_BAD_STATUS;
1339 }
1340
1341 chan->lcfg.mtu = cfg->mtu;
1342 if (cfg->credit != 0) {
1343 chan->lcfg.credit = cfg->credit;
1344 }
1345 if (chan->lcfg.mps > cfg->mtu) {
1346 chan->lcfg.mps = cfg->mtu;
1347 }
1348
1349 chan->state = L2CAP_CHANNEL_CONNECTED;
1350 L2capSendCreditBasedConnectionRsp(conn, chan, id, result);
1351
1352 if (result != L2CAP_LE_CONNECTION_SUCCESSFUL) {
1353 L2capLeDeleteChannel(conn, chan, 0);
1354 }
1355
1356 return BT_SUCCESS;
1357 }
1358
L2CAP_LeDisconnectionReq(uint16_t lcid)1359 int L2CAP_LeDisconnectionReq(uint16_t lcid)
1360 {
1361 L2capLeChannel *chan = NULL;
1362 L2capLeConnection *conn = NULL;
1363
1364 if (L2capLeInitialized() != BT_SUCCESS) {
1365 return BT_BAD_STATUS;
1366 }
1367
1368 L2capLeGetChannel2(lcid, &conn, &chan);
1369 if (chan == NULL) {
1370 return BT_BAD_PARAM;
1371 }
1372
1373 if (chan->state != L2CAP_CHANNEL_CONNECTED) {
1374 return BT_BAD_STATUS;
1375 }
1376
1377 chan->state = L2CAP_CHANNEL_DISCONNECT_OUT_REQ;
1378 L2capLeSendDisconnectionReq(conn, chan);
1379 return BT_SUCCESS;
1380 }
1381
L2CAP_LeDisconnectionRsp(uint16_t lcid,uint8_t id)1382 int L2CAP_LeDisconnectionRsp(uint16_t lcid, uint8_t id)
1383 {
1384 L2capLeConnection *conn = NULL;
1385 L2capLeChannel *chan = NULL;
1386
1387 if (L2capLeInitialized() != BT_SUCCESS) {
1388 return BT_BAD_STATUS;
1389 }
1390
1391 L2capLeGetChannel2(lcid, &conn, &chan);
1392 if (chan == NULL) {
1393 return BT_BAD_PARAM;
1394 }
1395
1396 if (chan->state != L2CAP_CHANNEL_DISCONNECT_IN_REQ) {
1397 return BT_BAD_STATUS;
1398 }
1399
1400 L2capLeSendDisconnectionRsp(conn, chan, id);
1401 return BT_SUCCESS;
1402 }
1403
L2CAP_LeSendData(uint16_t lcid,Packet * pkt)1404 int L2CAP_LeSendData(uint16_t lcid, Packet *pkt)
1405 {
1406 L2capLeConnection *conn = NULL;
1407 L2capLeChannel *chan = NULL;
1408 uint16_t length;
1409
1410 if (L2capLeInitialized() != BT_SUCCESS) {
1411 return BT_BAD_STATUS;
1412 }
1413
1414 L2capLeGetChannel2(lcid, &conn, &chan);
1415 if (chan == NULL) {
1416 return BT_BAD_PARAM;
1417 }
1418
1419 if (pkt == NULL) {
1420 return BT_BAD_PARAM;
1421 }
1422
1423 if (chan->state != L2CAP_CHANNEL_CONNECTED) {
1424 return BT_BAD_STATUS;
1425 }
1426
1427 length = PacketSize(pkt);
1428 if (length > chan->rcfg.mtu) {
1429 return BT_BAD_PARAM;
1430 }
1431
1432 if (chan->txList == NULL) {
1433 chan->txList = ListCreate(NULL);
1434 }
1435
1436 if (length > chan->rcfg.mps) {
1437 L2capLeSegmentPacketWithCredit(chan, pkt);
1438 } else {
1439 Packet *tpkt = NULL;
1440 uint8_t *header = NULL;
1441
1442 tpkt = PacketInheritMalloc(pkt, L2CAP_SIZE_6, 0);
1443 header = BufferPtr(PacketHead(tpkt));
1444
1445 L2capCpuToLe16(header + 0, length + L2CAP_SIZE_2);
1446 L2capCpuToLe16(header + L2CAP_OFFSET_2, chan->rcid);
1447 L2capCpuToLe16(header + L2CAP_OFFSET_4, length);
1448
1449 ListAddLast(chan->txList, tpkt);
1450 }
1451
1452 L2capLeTxWithCredit(conn, chan);
1453 return BT_SUCCESS;
1454 }
1455
L2CAP_LeRegisterService(uint16_t lpsm,const L2capLeService * svc,void * context)1456 int L2CAP_LeRegisterService(uint16_t lpsm, const L2capLeService *svc, void *context)
1457 {
1458 L2capLeInstance *inst = &g_l2capLeInst;
1459 L2capLePsm *psm = NULL;
1460
1461 LOG_INFO("%{public}s:%{public}d enter, psm = 0x%04X", __FUNCTION__, __LINE__, lpsm);
1462
1463 if (L2capLeInitialized() != BT_SUCCESS) {
1464 return BT_BAD_STATUS;
1465 }
1466
1467 if (svc == NULL) {
1468 return BT_BAD_PARAM;
1469 }
1470
1471 // check whether the psm is valid
1472 if (!(lpsm & 0x0001) || (lpsm & 0x0100)) {
1473 return BT_BAD_PARAM;
1474 }
1475
1476 psm = L2capLeGetPsm(lpsm);
1477 if (psm != NULL) {
1478 return BT_BAD_STATUS;
1479 }
1480
1481 psm = L2capAlloc(sizeof(L2capLePsm));
1482 if (psm == NULL) {
1483 return BT_NO_MEMORY;
1484 }
1485
1486 psm->lpsm = lpsm;
1487 psm->ctx = context;
1488 (void)memcpy_s(&(psm->service), sizeof(L2capLeService), svc, sizeof(L2capLeService));
1489 ListAddFirst(inst->psmList, psm);
1490
1491 return BT_SUCCESS;
1492 }
1493
L2CAP_LeDeregisterService(uint16_t lpsm)1494 int L2CAP_LeDeregisterService(uint16_t lpsm)
1495 {
1496 L2capLeInstance *inst = &g_l2capLeInst;
1497 L2capLePsm *psm = NULL;
1498 L2capLeConnection *conn = NULL;
1499 ListNode *nodeConnection = NULL;
1500
1501 LOG_INFO("%{public}s:%{public}d enter, psm = 0x%04X", __FUNCTION__, __LINE__, lpsm);
1502
1503 if (L2capLeInitialized() != BT_SUCCESS) {
1504 return BT_BAD_STATUS;
1505 }
1506
1507 psm = L2capLeGetPsm(lpsm);
1508 if (psm == NULL) {
1509 return BT_BAD_PARAM;
1510 }
1511
1512 nodeConnection = ListGetFirstNode(inst->connList);
1513 while (nodeConnection != NULL) {
1514 L2capLeChannel *chan = NULL;
1515 ListNode *nodeChannel = NULL;
1516
1517 conn = ListGetNodeData(nodeConnection);
1518 nodeChannel = ListGetFirstNode(conn->chanList);
1519 while (nodeChannel != NULL) {
1520 chan = ListGetNodeData(nodeChannel);
1521 // if any channel used the psm, return error
1522 if (chan->lpsm == lpsm) {
1523 return BT_BAD_STATUS;
1524 }
1525
1526 nodeChannel = ListGetNextNode(nodeChannel);
1527 }
1528
1529 nodeConnection = ListGetNextNode(nodeConnection);
1530 }
1531
1532 ListRemoveNode(inst->psmList, psm);
1533 L2capFree(psm);
1534 return BT_SUCCESS;
1535 }
1536
L2CAP_LeRegisterFixChannel(uint16_t cid,const L2capLeFixChannel * chan)1537 int L2CAP_LeRegisterFixChannel(uint16_t cid, const L2capLeFixChannel *chan)
1538 {
1539 L2capLeInstance *inst = &g_l2capLeInst;
1540
1541 LOG_INFO("%{public}s:%{public}d enter, cid = 0x%04X", __FUNCTION__, __LINE__, cid);
1542
1543 if (L2capLeInitialized() != BT_SUCCESS) {
1544 return BT_BAD_STATUS;
1545 }
1546
1547 if (cid == L2CAP_LE_ATT_CHANNEL) {
1548 inst->chanAtt.leConnected = chan->leConnected;
1549 inst->chanAtt.leDisconnected = chan->leDisconnected;
1550 inst->chanAtt.recvLeData = chan->recvLeData;
1551 } else if (cid == L2CAP_LE_SMP_CHANNEL) {
1552 inst->chanSm.leConnected = chan->leConnected;
1553 inst->chanSm.leDisconnected = chan->leDisconnected;
1554 inst->chanSm.recvLeData = chan->recvLeData;
1555 } else {
1556 return BT_BAD_PARAM;
1557 }
1558
1559 return BT_SUCCESS;
1560 }
1561
L2CAP_LeDeregisterFixChannel(uint16_t cid)1562 int L2CAP_LeDeregisterFixChannel(uint16_t cid)
1563 {
1564 L2capLeInstance *inst = &g_l2capLeInst;
1565
1566 LOG_INFO("%{public}s:%{public}d enter, cid = 0x%04X", __FUNCTION__, __LINE__, cid);
1567
1568 if (L2capLeInitialized() != BT_SUCCESS) {
1569 return BT_BAD_STATUS;
1570 }
1571
1572 if (cid == L2CAP_LE_ATT_CHANNEL) {
1573 inst->chanAtt.leConnected = NULL;
1574 inst->chanAtt.leDisconnected = NULL;
1575 inst->chanAtt.recvLeData = NULL;
1576 } else if (cid == L2CAP_LE_SMP_CHANNEL) {
1577 inst->chanSm.leConnected = NULL;
1578 inst->chanSm.leDisconnected = NULL;
1579 inst->chanSm.recvLeData = NULL;
1580 } else {
1581 return BT_BAD_PARAM;
1582 }
1583
1584 return BT_SUCCESS;
1585 }
1586
L2CAP_LeConnect(const BtAddr * addr,const L2capLeConnectionParameter * param)1587 int L2CAP_LeConnect(const BtAddr *addr, const L2capLeConnectionParameter *param)
1588 {
1589 LOG_INFO("%{public}s:%{public}d enter", __FUNCTION__, __LINE__);
1590
1591 if (L2capLeInitialized() != BT_SUCCESS) {
1592 return BT_BAD_STATUS;
1593 }
1594
1595 if (addr == NULL) {
1596 return BT_BAD_PARAM;
1597 }
1598
1599 return L2capConnectLe(addr);
1600 }
1601
L2CAP_LeConnectCancel(const BtAddr * addr)1602 int L2CAP_LeConnectCancel(const BtAddr *addr)
1603 {
1604 LOG_INFO("%{public}s:%{public}d enter", __FUNCTION__, __LINE__);
1605
1606 if (L2capLeInitialized() != BT_SUCCESS) {
1607 return BT_BAD_STATUS;
1608 }
1609
1610 return L2capConnectLeCancel(addr);
1611 }
1612
L2CAP_LeDisconnect(uint16_t aclHandle)1613 int L2CAP_LeDisconnect(uint16_t aclHandle)
1614 {
1615 LOG_INFO("%{public}s:%{public}d enter, handle = 0x%04X", __FUNCTION__, __LINE__, aclHandle);
1616
1617 if (L2capLeInitialized() != BT_SUCCESS) {
1618 return BT_BAD_STATUS;
1619 }
1620
1621 // Reason: REMOTE USER TERMINATED CONNECTION
1622 return L2capDisconnect(aclHandle, 0x13);
1623 }
1624
L2CAP_LeSendFixChannelData(uint16_t aclHandle,uint16_t cid,const Packet * pkt)1625 int L2CAP_LeSendFixChannelData(uint16_t aclHandle, uint16_t cid, const Packet *pkt)
1626 {
1627 L2capLeConnection *conn = NULL;
1628 uint16_t length;
1629 Packet *tpkt = NULL;
1630 uint8_t *header = NULL;
1631
1632 LOG_INFO("%{public}s:%{public}d enter, cid = 0x%04X, pktLength = %u", __FUNCTION__, __LINE__, cid, PacketSize(pkt));
1633
1634 if (L2capLeInitialized() != BT_SUCCESS) {
1635 return BT_BAD_STATUS;
1636 }
1637
1638 conn = L2capLeGetConnection(aclHandle);
1639 if (conn == NULL) {
1640 return BT_BAD_PARAM;
1641 }
1642
1643 length = PacketSize(pkt);
1644
1645 tpkt = PacketInheritMalloc(pkt, L2CAP_HEADER_LENGTH, 0);
1646 header = BufferPtr(PacketHead(tpkt));
1647
1648 L2capCpuToLe16(header + 0, length);
1649 L2capCpuToLe16(header + L2CAP_OFFSET_2, cid);
1650
1651 L2capLeSendPacket(aclHandle, tpkt);
1652
1653 return BT_SUCCESS;
1654 }
1655
L2CAP_LeRegisterConnectionParameterUpdate(const L2capLeConnectionParameterUpdate * cb,void * context)1656 int L2CAP_LeRegisterConnectionParameterUpdate(const L2capLeConnectionParameterUpdate *cb, void *context)
1657 {
1658 L2capLeInstance *inst = &g_l2capLeInst;
1659
1660 LOG_INFO("%{public}s:%{public}d enter", __FUNCTION__, __LINE__);
1661
1662 if (L2capLeInitialized() != BT_SUCCESS) {
1663 return BT_BAD_STATUS;
1664 }
1665
1666 if (cb == NULL) {
1667 return BT_BAD_PARAM;
1668 }
1669
1670 inst->connParamUpdate.ctx = context;
1671 (void)memcpy_s(&(inst->connParamUpdate.cb),
1672 sizeof(L2capLeConnectionParameterUpdate),
1673 cb,
1674 sizeof(L2capLeConnectionParameterUpdate));
1675
1676 return BT_SUCCESS;
1677 }
1678
L2CAP_LeDeregisterConnectionParameterUpdate()1679 int L2CAP_LeDeregisterConnectionParameterUpdate()
1680 {
1681 L2capLeInstance *inst = &g_l2capLeInst;
1682
1683 LOG_INFO("%{public}s:%{public}d enter", __FUNCTION__, __LINE__);
1684
1685 if (L2capLeInitialized() != BT_SUCCESS) {
1686 return BT_BAD_STATUS;
1687 }
1688
1689 (void)memset_s(&(inst->connParamUpdate),
1690 sizeof(L2capLeConnectionParameterUpdate),
1691 0,
1692 sizeof(L2capLeConnectionParameterUpdate));
1693 return BT_SUCCESS;
1694 }
1695
L2CAP_LeConnectionParameterUpdateReq(uint16_t aclHandle,const L2capLeConnectionParameter * param)1696 int L2CAP_LeConnectionParameterUpdateReq(uint16_t aclHandle, const L2capLeConnectionParameter *param)
1697 {
1698 L2capLeConnection *conn = NULL;
1699 uint8_t buff[8] = {0};
1700 L2capSignalHeader signal = {0};
1701 Packet *pkt = NULL;
1702
1703 LOG_INFO("%{public}s:%{public}d enter, handle = 0x%04X", __FUNCTION__, __LINE__, aclHandle);
1704
1705 if (L2capLeInitialized() != BT_SUCCESS) {
1706 return BT_BAD_STATUS;
1707 }
1708
1709 if ((param->connIntervalMin < 0x0006) || (param->connIntervalMin > 0x0C80)) {
1710 return BT_BAD_PARAM;
1711 }
1712
1713 if ((param->connIntervalMax < 0x0006) || (param->connIntervalMax > 0x0C80)) {
1714 return BT_BAD_PARAM;
1715 }
1716
1717 if ((param->supervisionTimeout < 0x000A) || (param->supervisionTimeout > 0x0C80)) {
1718 return BT_BAD_PARAM;
1719 }
1720
1721 if (param->connLatency > 0x01F3) {
1722 return BT_BAD_PARAM;
1723 }
1724
1725 if (param->connLatency > ((param->supervisionTimeout / (param->connIntervalMax * L2CAP_SIZE_2)) - 1)) {
1726 return BT_BAD_PARAM;
1727 }
1728
1729 conn = L2capLeGetConnection(aclHandle);
1730 if (conn == NULL) {
1731 return BT_BAD_PARAM;
1732 }
1733
1734 if (conn->role != L2CAP_LE_ROLE_SLAVE) {
1735 return BT_BAD_PARAM;
1736 }
1737
1738 L2capCpuToLe16(buff + 0, param->connIntervalMin);
1739 L2capCpuToLe16(buff + L2CAP_OFFSET_2, param->connIntervalMax);
1740 L2capCpuToLe16(buff + L2CAP_OFFSET_4, param->connLatency);
1741 L2capCpuToLe16(buff + L2CAP_OFFSET_6, param->supervisionTimeout);
1742
1743 signal.code = L2CAP_CONNECTION_PARAMETER_UPDATE_REQUEST;
1744 signal.identifier = L2capLeGetNewIdentifier(conn);
1745 signal.length = sizeof(buff);
1746
1747 pkt = L2capBuildSignalPacket(L2CAP_LE_SIGNALING_CHANNEL, &signal, buff);
1748 L2capCreatePendingRequest(conn->pendingList, 0, &signal, L2CAP_DEFAULT_RTX, L2capLeResponseTimeoutCallback);
1749 return L2capLeSendPacket(aclHandle, pkt);
1750 }
1751
L2CAP_LeConnectionParameterUpdateRsp(uint16_t aclHandle,uint8_t id,uint16_t result)1752 int L2CAP_LeConnectionParameterUpdateRsp(uint16_t aclHandle, uint8_t id, uint16_t result)
1753 {
1754 L2capLeConnection *conn = NULL;
1755 uint8_t buff[2] = {0};
1756 L2capSignalHeader signal = {0};
1757 Packet *pkt = NULL;
1758
1759 LOG_INFO("%{public}s:%{public}d enter, handle = 0x%04X", __FUNCTION__, __LINE__, aclHandle);
1760
1761 if (L2capLeInitialized() != BT_SUCCESS) {
1762 return BT_BAD_STATUS;
1763 }
1764
1765 conn = L2capLeGetConnection(aclHandle);
1766 if (conn == NULL) {
1767 return BT_BAD_PARAM;
1768 }
1769
1770 L2capCpuToLe16(buff + 0, result);
1771
1772 signal.code = L2CAP_CONNECTION_PARAMETER_UPDATE_RESPONSE;
1773 signal.identifier = id;
1774 signal.length = sizeof(buff);
1775
1776 pkt = L2capBuildSignalPacket(L2CAP_LE_SIGNALING_CHANNEL, &signal, buff);
1777
1778 return L2capLeSendPacket(aclHandle, pkt);
1779 }
1780
L2CAP_LeInitialize(int traceLevel)1781 void L2CAP_LeInitialize(int traceLevel)
1782 {
1783 L2capLeInstance *inst = &g_l2capLeInst;
1784 L2capLeCallback cmnCallback = {0};
1785
1786 LOG_INFO("%{public}s:%{public}d enter", __FUNCTION__, __LINE__);
1787
1788 cmnCallback.aclConnected = L2capLeConnectComplete;
1789 cmnCallback.aclDisconnected = L2capLeDisconnectComplete;
1790 cmnCallback.recvL2capPacket = L2capLeReceivePacket;
1791 L2capRegisterLe(&cmnCallback);
1792
1793 inst->psmList = ListCreate(NULL);
1794 inst->connList = ListCreate(NULL);
1795 inst->nextLcid = L2CAP_LE_MIN_CID;
1796 return;
1797 }
1798
L2CAP_LeFinalize()1799 void L2CAP_LeFinalize()
1800 {
1801 L2capLeInstance *leinst = &g_l2capLeInst;
1802 ListNode *node = NULL;
1803 L2capLeConnection *conn = NULL;
1804 void *psm = NULL;
1805
1806 LOG_INFO("%{public}s:%{public}d enter", __FUNCTION__, __LINE__);
1807
1808 node = ListGetFirstNode(leinst->connList);
1809 while (node != NULL) {
1810 conn = ListGetNodeData(node);
1811 L2capLeDeleteConnection(conn);
1812
1813 node = ListGetFirstNode(leinst->connList);
1814 }
1815
1816 ListDelete(leinst->connList);
1817 leinst->connList = NULL;
1818
1819 node = ListGetFirstNode(leinst->psmList);
1820 while (node != NULL) {
1821 psm = ListGetNodeData(node);
1822 ListRemoveNode(leinst->psmList, psm);
1823 L2capFree(psm);
1824
1825 node = ListGetFirstNode(leinst->psmList);
1826 }
1827
1828 ListDelete(leinst->psmList);
1829 leinst->psmList = NULL;
1830
1831 return;
1832 }
1833