• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "l2cap_le_if.h"
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include "../btm/btm_thread.h"
23 #include "l2cap_cmn.h"
24 #include "l2cap_le.h"
25 
26 typedef struct {
27     uint16_t lpsm;
28     L2capLeService svc;
29     void *context;
30     void (*cb)(uint16_t lpsm, int result);
31 } L2cifLeRegisterServiceContext;
32 
L2cifLeRegisterService(const void * context)33 static void L2cifLeRegisterService(const void *context)
34 {
35     L2cifLeRegisterServiceContext *ctx = NULL;
36     int result;
37 
38     ctx = (L2cifLeRegisterServiceContext *)context;
39 
40     result = L2CAP_LeRegisterService(ctx->lpsm, &(ctx->svc), ctx->context);
41     if (ctx->cb != NULL) {
42         ctx->cb(ctx->lpsm, result);
43     }
44 
45     L2capFree(ctx);
46     return;
47 }
48 
L2CIF_LeRegisterService(uint16_t lpsm,const L2capLeService * svc,void * context,void (* cb)(uint16_t lpsm,int result))49 int L2CIF_LeRegisterService(
50     uint16_t lpsm, const L2capLeService *svc, void *context, void (*cb)(uint16_t lpsm, int result))
51 {
52     L2cifLeRegisterServiceContext *ctx = NULL;
53 
54     if (svc == NULL) {
55         return BT_BAD_PARAM;
56     }
57 
58     ctx = L2capAlloc(sizeof(L2cifLeRegisterServiceContext));
59     if (ctx == NULL) {
60         return BT_NO_MEMORY;
61     }
62 
63     ctx->lpsm = lpsm;
64     (void)memcpy_s(&(ctx->svc), sizeof(L2capLeService), svc, sizeof(L2capLeService));
65     ctx->context = context;
66     ctx->cb = cb;
67 
68     L2capAsynchronousProcess(L2cifLeRegisterService, L2capFree, ctx);
69     return BT_SUCCESS;
70 }
71 
72 typedef struct {
73     uint16_t lpsm;
74     void (*cb)(uint16_t lpsm, int result);
75 } L2cifLeDeregisterServiceContext;
76 
L2cifLeDeregisterService(const void * context)77 static void L2cifLeDeregisterService(const void *context)
78 {
79     L2cifLeDeregisterServiceContext *ctx = NULL;
80     int result;
81 
82     ctx = (L2cifLeDeregisterServiceContext *)context;
83 
84     result = L2CAP_LeDeregisterService(ctx->lpsm);
85     if (ctx->cb != NULL) {
86         ctx->cb(ctx->lpsm, result);
87     }
88 
89     L2capFree(ctx);
90     return;
91 }
92 
L2CIF_LeDeregisterService(uint16_t lpsm,void (* cb)(uint16_t lpsm,int result))93 void L2CIF_LeDeregisterService(uint16_t lpsm, void (*cb)(uint16_t lpsm, int result))
94 {
95     L2cifLeDeregisterServiceContext *ctx = NULL;
96 
97     ctx = L2capAlloc(sizeof(L2cifLeDeregisterServiceContext));
98     if (ctx == NULL) {
99         LOG_WARN("malloc failed");
100         return;
101     }
102 
103     ctx->lpsm = lpsm;
104     ctx->cb = cb;
105 
106     L2capAsynchronousProcess(L2cifLeDeregisterService, L2capFree, ctx);
107     return;
108 }
109 
110 typedef struct {
111     BtAddr addr;
112     uint16_t lpsm;
113     uint16_t rpsm;
114     L2capLeConfigInfo cfg;
115     void (*cb)(const BtAddr *addr, uint16_t lcid, int result);
116 } L2cifLeCreditBasedConnectionReqContext;
117 
L2cifLeCreditBasedConnectionReq(const void * context)118 static void L2cifLeCreditBasedConnectionReq(const void *context)
119 {
120     L2cifLeCreditBasedConnectionReqContext *ctx = NULL;
121     uint16_t lcid = 0;
122     int result;
123 
124     ctx = (L2cifLeCreditBasedConnectionReqContext *)context;
125 
126     result = L2CAP_LeCreditBasedConnectionReq(&(ctx->addr), ctx->lpsm, ctx->rpsm, &(ctx->cfg), &lcid);
127     if (ctx->cb != NULL) {
128         ctx->cb(&(ctx->addr), lcid, result);
129     }
130 
131     L2capFree(ctx);
132     return;
133 }
134 
L2CIF_LeCreditBasedConnectionReq(const BtAddr * addr,uint16_t lpsm,uint16_t rpsm,const L2capLeConfigInfo * cfg,void (* cb)(const BtAddr * addr,uint16_t lcid,int result))135 int L2CIF_LeCreditBasedConnectionReq(const BtAddr *addr, uint16_t lpsm, uint16_t rpsm, const L2capLeConfigInfo *cfg,
136     void (*cb)(const BtAddr *addr, uint16_t lcid, int result))
137 {
138     L2cifLeCreditBasedConnectionReqContext *ctx = NULL;
139 
140     if ((addr == NULL) || (cfg == NULL)) {
141         return BT_BAD_PARAM;
142     }
143 
144     ctx = L2capAlloc(sizeof(L2cifLeCreditBasedConnectionReqContext));
145     if (ctx == NULL) {
146         return BT_NO_MEMORY;
147     }
148 
149     (void)memcpy_s(&(ctx->addr), sizeof(BtAddr), addr, sizeof(BtAddr));
150     ctx->lpsm = lpsm;
151     ctx->rpsm = rpsm;
152     (void)memcpy_s(&(ctx->cfg), sizeof(L2capLeConfigInfo), cfg, sizeof(L2capLeConfigInfo));
153     ctx->cb = cb;
154 
155     L2capAsynchronousProcess(L2cifLeCreditBasedConnectionReq, L2capFree, ctx);
156     return BT_SUCCESS;
157 }
158 
159 typedef struct {
160     uint16_t lcid;
161     uint8_t id;
162     L2capLeConfigInfo cfg;
163     uint16_t result;
164     void (*cb)(uint16_t lcid, int result);
165 } L2cifLeCreditBasedConnectionRspContext;
166 
L2cifLeCreditBasedConnectionRsp(const void * context)167 static void L2cifLeCreditBasedConnectionRsp(const void *context)
168 {
169     L2cifLeCreditBasedConnectionRspContext *ctx = NULL;
170     int result;
171 
172     ctx = (L2cifLeCreditBasedConnectionRspContext *)context;
173 
174     result = L2CAP_LeCreditBasedConnectionRsp(ctx->lcid, ctx->id, &(ctx->cfg), ctx->result);
175     if (ctx->cb != NULL) {
176         ctx->cb(ctx->lcid, result);
177     }
178 
179     L2capFree(ctx);
180     return;
181 }
182 
L2CIF_LeCreditBasedConnectionRsp(uint16_t lcid,uint8_t id,const L2capLeConfigInfo * cfg,uint16_t result,void (* cb)(uint16_t lcid,int result))183 int L2CIF_LeCreditBasedConnectionRsp(
184     uint16_t lcid, uint8_t id, const L2capLeConfigInfo *cfg, uint16_t result, void (*cb)(uint16_t lcid, int result))
185 {
186     L2cifLeCreditBasedConnectionRspContext *ctx = NULL;
187 
188     if (cfg == NULL) {
189         return BT_BAD_PARAM;
190     }
191 
192     ctx = L2capAlloc(sizeof(L2cifLeCreditBasedConnectionRspContext));
193     if (ctx == NULL) {
194         return BT_NO_MEMORY;
195     }
196 
197     ctx->lcid = lcid;
198     ctx->id = id;
199     (void)memcpy_s(&(ctx->cfg), sizeof(L2capLeConfigInfo), cfg, sizeof(L2capLeConfigInfo));
200     ctx->result = result;
201     ctx->cb = cb;
202 
203     L2capAsynchronousProcess(L2cifLeCreditBasedConnectionRsp, L2capFree, ctx);
204     return BT_SUCCESS;
205 }
206 
207 typedef struct {
208     uint16_t lcid;
209     void (*cb)(uint16_t lcid, int result);
210 } L2cifLeDisconnectionReqContext;
211 
L2cifLeDisconnectionReq(const void * context)212 static void L2cifLeDisconnectionReq(const void *context)
213 {
214     L2cifLeDisconnectionReqContext *ctx = NULL;
215     int result;
216 
217     ctx = (L2cifLeDisconnectionReqContext *)context;
218 
219     result = L2CAP_LeDisconnectionReq(ctx->lcid);
220     if (ctx->cb != NULL) {
221         ctx->cb(ctx->lcid, result);
222     }
223 
224     L2capFree(ctx);
225     return;
226 }
227 
L2CIF_LeDisconnectionReq(uint16_t lcid,void (* cb)(uint16_t lcid,int result))228 void L2CIF_LeDisconnectionReq(uint16_t lcid, void (*cb)(uint16_t lcid, int result))
229 {
230     L2cifLeDisconnectionReqContext *ctx = NULL;
231 
232     ctx = L2capAlloc(sizeof(L2cifLeDisconnectionReqContext));
233     if (ctx == NULL) {
234         LOG_WARN("malloc failed");
235         return;
236     }
237 
238     ctx->lcid = lcid;
239     ctx->cb = cb;
240 
241     L2capAsynchronousProcess(L2cifLeDisconnectionReq, L2capFree, ctx);
242     return;
243 }
244 
245 typedef struct {
246     uint16_t lcid;
247     uint8_t id;
248     void (*cb)(uint16_t lcid, int result);
249 } L2cifLeDisconnectionRspContext;
250 
L2cifLeDisconnectionRsp(const void * context)251 static void L2cifLeDisconnectionRsp(const void *context)
252 {
253     L2cifLeDisconnectionRspContext *ctx = NULL;
254     int result;
255 
256     ctx = (L2cifLeDisconnectionRspContext *)context;
257 
258     result = L2CAP_LeDisconnectionRsp(ctx->lcid, ctx->id);
259     if (ctx->cb != NULL) {
260         ctx->cb(ctx->lcid, result);
261     }
262 
263     L2capFree(ctx);
264     return;
265 }
266 
L2CIF_LeDisconnectionRsp(uint16_t lcid,uint8_t id,void (* cb)(uint16_t lcid,int result))267 void L2CIF_LeDisconnectionRsp(uint16_t lcid, uint8_t id, void (*cb)(uint16_t lcid, int result))
268 {
269     L2cifLeDisconnectionRspContext *ctx = NULL;
270 
271     ctx = L2capAlloc(sizeof(L2cifLeDisconnectionRspContext));
272     if (ctx == NULL) {
273         LOG_WARN("malloc failed");
274         return;
275     }
276 
277     ctx->lcid = lcid;
278     ctx->id = id;
279     ctx->cb = cb;
280 
281     L2capAsynchronousProcess(L2cifLeDisconnectionRsp, L2capFree, ctx);
282     return;
283 }
284 
285 typedef struct {
286     uint16_t lcid;
287     Packet *pkt;
288     void (*cb)(uint16_t lcid, int result);
289 } L2cifLeSendDataContext;
290 
L2cifLeSendDataContextDestroy(void * context)291 static void L2cifLeSendDataContextDestroy(void *context)
292 {
293     L2cifLeSendDataContext *ctx = NULL;
294 
295     ctx = context;
296 
297     PacketFree(ctx->pkt);
298     L2capFree(ctx);
299     return;
300 }
301 
L2cifLeSendData(const void * context)302 static void L2cifLeSendData(const void *context)
303 {
304     L2cifLeSendDataContext *ctx = NULL;
305     int result;
306 
307     ctx = (L2cifLeSendDataContext *)context;
308 
309     result = L2CAP_LeSendData(ctx->lcid, ctx->pkt);
310     if (ctx->cb != NULL) {
311         ctx->cb(ctx->lcid, result);
312     }
313 
314     L2cifLeSendDataContextDestroy(ctx);
315     return;
316 }
317 
L2CIF_LeSendData(uint16_t lcid,const Packet * pkt,void (* cb)(uint16_t lcid,int result))318 int L2CIF_LeSendData(uint16_t lcid, const Packet *pkt, void (*cb)(uint16_t lcid, int result))
319 {
320     L2cifLeSendDataContext *ctx = NULL;
321 
322     if (pkt == NULL) {
323         return BT_BAD_PARAM;
324     }
325 
326     ctx = L2capAlloc(sizeof(L2cifLeSendDataContext));
327     if (ctx == NULL) {
328         return BT_NO_MEMORY;
329     }
330 
331     ctx->lcid = lcid;
332     ctx->pkt = PacketRefMalloc(pkt);
333     ctx->cb = cb;
334 
335     L2capAsynchronousProcess(L2cifLeSendData, L2cifLeSendDataContextDestroy, ctx);
336     return BT_SUCCESS;
337 }
338 
339 typedef struct {
340     uint16_t cid;
341     L2capLeFixChannel chan;
342     void (*cb)(uint16_t cid, int result);
343 } L2cifLeRegisterFixChannelContext;
344 
L2cifLeRegisterFixChannel(const void * context)345 static void L2cifLeRegisterFixChannel(const void *context)
346 {
347     L2cifLeRegisterFixChannelContext *ctx = NULL;
348     int result;
349 
350     ctx = (L2cifLeRegisterFixChannelContext *)context;
351 
352     result = L2CAP_LeRegisterFixChannel(ctx->cid, &(ctx->chan));
353     if (ctx->cb != NULL) {
354         ctx->cb(ctx->cid, result);
355     }
356 
357     L2capFree(ctx);
358     return;
359 }
360 
L2CIF_LeRegisterFixChannel(uint16_t cid,const L2capLeFixChannel * chan,void (* cb)(uint16_t cid,int result))361 int L2CIF_LeRegisterFixChannel(uint16_t cid, const L2capLeFixChannel *chan, void (*cb)(uint16_t cid, int result))
362 {
363     L2cifLeRegisterFixChannelContext *ctx = NULL;
364 
365     if (chan == NULL) {
366         return BT_BAD_PARAM;
367     }
368 
369     ctx = L2capAlloc(sizeof(L2cifLeRegisterFixChannelContext));
370     if (ctx == NULL) {
371         return BT_NO_MEMORY;
372     }
373 
374     ctx->cid = cid;
375     (void)memcpy_s(&(ctx->chan), sizeof(L2capLeFixChannel), chan, sizeof(L2capLeFixChannel));
376     ctx->cb = cb;
377 
378     L2capAsynchronousProcess(L2cifLeRegisterFixChannel, L2capFree, ctx);
379     return BT_SUCCESS;
380 }
381 
382 typedef struct {
383     uint16_t cid;
384     void (*cb)(uint16_t cid, int result);
385 } L2cifLeDeregisterFixChannelContext;
386 
L2cifLeDeregisterFixChannel(const void * context)387 static void L2cifLeDeregisterFixChannel(const void *context)
388 {
389     L2cifLeDeregisterFixChannelContext *ctx = NULL;
390     int result;
391 
392     ctx = (L2cifLeDeregisterFixChannelContext *)context;
393 
394     result = L2CAP_LeDeregisterFixChannel(ctx->cid);
395     if (ctx->cb != NULL) {
396         ctx->cb(ctx->cid, result);
397     }
398 
399     L2capFree(ctx);
400     return;
401 }
402 
L2CIF_LeDeregisterFixChannel(uint16_t cid,void (* cb)(uint16_t cid,int result))403 void L2CIF_LeDeregisterFixChannel(uint16_t cid, void (*cb)(uint16_t cid, int result))
404 {
405     L2cifLeDeregisterFixChannelContext *ctx = NULL;
406 
407     ctx = L2capAlloc(sizeof(L2cifLeDeregisterFixChannelContext));
408     if (ctx == NULL) {
409         LOG_WARN("malloc failed");
410         return;
411     }
412 
413     ctx->cid = cid;
414     ctx->cb = cb;
415 
416     L2capAsynchronousProcess(L2cifLeDeregisterFixChannel, L2capFree, ctx);
417     return;
418 }
419 
420 typedef struct {
421     BtAddr addr;
422     L2capLeConnectionParameter param;
423     void (*cb)(const BtAddr *addr, int result);
424 } L2cifLeConnectContext;
425 
L2cifLeConnect(const void * context)426 static void L2cifLeConnect(const void *context)
427 {
428     L2cifLeConnectContext *ctx = NULL;
429     int result;
430 
431     ctx = (L2cifLeConnectContext *)context;
432 
433     result = L2CAP_LeConnect(&(ctx->addr), &(ctx->param));
434     if (ctx->cb != NULL) {
435         ctx->cb(&(ctx->addr), result);
436     }
437 
438     L2capFree(ctx);
439     return;
440 }
441 
L2CIF_LeConnect(const BtAddr * addr,const L2capLeConnectionParameter * param,void (* cb)(const BtAddr * addr,int result))442 int L2CIF_LeConnect(
443     const BtAddr *addr, const L2capLeConnectionParameter *param, void (*cb)(const BtAddr *addr, int result))
444 {
445     L2cifLeConnectContext *ctx = NULL;
446 
447     if (addr == NULL) {
448         return BT_BAD_PARAM;
449     }
450 
451     ctx = L2capAlloc(sizeof(L2cifLeConnectContext));
452     if (ctx == NULL) {
453         return BT_NO_MEMORY;
454     }
455 
456     (void)memcpy_s(&(ctx->addr), sizeof(BtAddr), addr, sizeof(BtAddr));
457     if (param != NULL) {
458         (void)memcpy_s(&(ctx->param), sizeof(L2capLeConnectionParameter), param, sizeof(L2capLeConnectionParameter));
459     }
460 
461     ctx->cb = cb;
462 
463     L2capAsynchronousProcess(L2cifLeConnect, L2capFree, ctx);
464     return BT_SUCCESS;
465 }
466 
467 typedef struct {
468     BtAddr addr;
469 } L2cifLeConnectCancelContext;
470 
L2cifLeConnectCancel(const void * context)471 static void L2cifLeConnectCancel(const void *context)
472 {
473     L2cifLeConnectCancelContext *ctx = NULL;
474 
475     ctx = (L2cifLeConnectCancelContext *)context;
476 
477     L2CAP_LeConnectCancel(&(ctx->addr));
478 
479     L2capFree(ctx);
480     return;
481 }
482 
L2CIF_LeConnectCancel(const BtAddr * addr)483 int L2CIF_LeConnectCancel(const BtAddr *addr)
484 {
485     L2cifLeConnectCancelContext *ctx = NULL;
486 
487     if (addr == NULL) {
488         return BT_BAD_PARAM;
489     }
490 
491     ctx = L2capAlloc(sizeof(L2cifLeConnectCancelContext));
492     if (ctx == NULL) {
493         return BT_NO_MEMORY;
494     }
495 
496     (void)memcpy_s(&(ctx->addr), sizeof(BtAddr), addr, sizeof(BtAddr));
497     L2capAsynchronousProcess(L2cifLeConnectCancel, L2capFree, ctx);
498     return BT_SUCCESS;
499 }
500 
501 typedef struct {
502     uint16_t aclHandle;
503     void (*cb)(uint16_t aclHandle, int result);
504 } L2cifLeDisconnectContext;
505 
L2cifLeDisconnect(const void * context)506 static void L2cifLeDisconnect(const void *context)
507 {
508     L2cifLeDisconnectContext *ctx = NULL;
509     int result;
510 
511     ctx = (L2cifLeDisconnectContext *)context;
512 
513     result = L2CAP_LeDisconnect(ctx->aclHandle);
514     if (ctx->cb != NULL) {
515         ctx->cb(ctx->aclHandle, result);
516     }
517 
518     L2capFree(ctx);
519     return;
520 }
521 
L2CIF_LeDisconnect(uint16_t aclHandle,void (* cb)(uint16_t aclHandle,int result))522 void L2CIF_LeDisconnect(uint16_t aclHandle, void (*cb)(uint16_t aclHandle, int result))
523 {
524     L2cifLeDisconnectContext *ctx = NULL;
525 
526     ctx = L2capAlloc(sizeof(L2cifLeDisconnectContext));
527     if (ctx == NULL) {
528         LOG_WARN("malloc failed");
529         return;
530     }
531 
532     ctx->aclHandle = aclHandle;
533     ctx->cb = cb;
534 
535     L2capAsynchronousProcess(L2cifLeDisconnect, L2capFree, ctx);
536     return;
537 }
538 
539 typedef struct {
540     uint16_t aclHandle;
541     uint16_t cid;
542     Packet *pkt;
543     void (*cb)(uint16_t aclHandle, int result);
544 } L2cifLeSendFixChannelDataContext;
545 
L2cifLeSendFixChannelDataContextDestroy(void * context)546 static void L2cifLeSendFixChannelDataContextDestroy(void *context)
547 {
548     L2cifLeSendFixChannelDataContext *ctx = NULL;
549 
550     ctx = context;
551     if (ctx == NULL) {
552         LOG_WARN("malloc failed");
553         return;
554     }
555 
556     PacketFree(ctx->pkt);
557     L2capFree(ctx);
558     return;
559 }
560 
L2cifLeSendFixChannelData(const void * context)561 static void L2cifLeSendFixChannelData(const void *context)
562 {
563     L2cifLeSendFixChannelDataContext *ctx = NULL;
564     int result;
565 
566     ctx = (L2cifLeSendFixChannelDataContext *)context;
567 
568     result = L2CAP_LeSendFixChannelData(ctx->aclHandle, ctx->cid, ctx->pkt);
569     if (ctx->cb != NULL) {
570         ctx->cb(ctx->aclHandle, result);
571     }
572 
573     L2cifLeSendFixChannelDataContextDestroy(ctx);
574     return;
575 }
576 
L2CIF_LeSendFixChannelData(uint16_t aclHandle,uint16_t cid,Packet * pkt,void (* cb)(uint16_t aclHandle,int result))577 int L2CIF_LeSendFixChannelData(
578     uint16_t aclHandle, uint16_t cid, Packet *pkt, void (*cb)(uint16_t aclHandle, int result))
579 {
580     L2cifLeSendFixChannelDataContext *ctx = NULL;
581 
582     if (pkt == NULL) {
583         return BT_BAD_PARAM;
584     }
585 
586     ctx = L2capAlloc(sizeof(L2cifLeSendFixChannelDataContext));
587     if (ctx == NULL) {
588         return BT_NO_MEMORY;
589     }
590 
591     ctx->aclHandle = aclHandle;
592     ctx->cid = cid;
593     ctx->pkt = PacketRefMalloc((Packet *)pkt);
594     ctx->cb = cb;
595 
596     L2capAsynchronousProcess(L2cifLeSendFixChannelData, L2cifLeSendFixChannelDataContextDestroy, ctx);
597     return BT_SUCCESS;
598 }
599 
600 typedef struct {
601     L2capLeConnectionParameterUpdate cb;
602     void *context;
603 } L2cifLeRegisterConnectionParameterUpdateContext;
604 
L2cifLeRegisterConnectionParameterUpdate(const void * context)605 static void L2cifLeRegisterConnectionParameterUpdate(const void *context)
606 {
607     L2cifLeRegisterConnectionParameterUpdateContext *ctx = NULL;
608 
609     ctx = (L2cifLeRegisterConnectionParameterUpdateContext *)context;
610 
611     L2CAP_LeRegisterConnectionParameterUpdate(&(ctx->cb), ctx->context);
612 
613     L2capFree(ctx);
614     return;
615 }
616 
L2CIF_LeRegisterConnectionParameterUpdate(const L2capLeConnectionParameterUpdate * cb,void * context)617 int L2CIF_LeRegisterConnectionParameterUpdate(const L2capLeConnectionParameterUpdate *cb, void *context)
618 {
619     L2cifLeRegisterConnectionParameterUpdateContext *ctx = NULL;
620 
621     if (cb == NULL) {
622         return BT_BAD_PARAM;
623     }
624 
625     ctx = L2capAlloc(sizeof(L2cifLeRegisterConnectionParameterUpdateContext));
626     if (ctx == NULL) {
627         return BT_NO_MEMORY;
628     }
629 
630     (void)memcpy_s(&(ctx->cb), sizeof(L2capLeConnectionParameterUpdate), cb, sizeof(L2capLeConnectionParameterUpdate));
631     ctx->context = context;
632 
633     L2capAsynchronousProcess(L2cifLeRegisterConnectionParameterUpdate, L2capFree, ctx);
634     return BT_SUCCESS;
635 }
636 
L2cifLeDeregisterConnectionParameterUpdate(const void * context)637 static void L2cifLeDeregisterConnectionParameterUpdate(const void *context)
638 {
639     L2CAP_LeDeregisterConnectionParameterUpdate();
640     return;
641 }
642 
L2CIF_LeDeregisterConnectionParameterUpdate()643 void L2CIF_LeDeregisterConnectionParameterUpdate()
644 {
645     L2capAsynchronousProcess(L2cifLeDeregisterConnectionParameterUpdate, NULL, NULL);
646     return;
647 }
648 
649 typedef struct {
650     uint16_t aclHandle;
651     L2capLeConnectionParameter param;
652     void (*cb)(uint16_t aclHandle, int result);
653 } L2cifLeConnectionParameterUpdateReqContext;
654 
L2cifLeConnectionParameterUpdateReq(const void * context)655 static void L2cifLeConnectionParameterUpdateReq(const void *context)
656 {
657     L2cifLeConnectionParameterUpdateReqContext *ctx = NULL;
658     int result;
659 
660     ctx = (L2cifLeConnectionParameterUpdateReqContext *)context;
661 
662     result = L2CAP_LeConnectionParameterUpdateReq(ctx->aclHandle, &(ctx->param));
663     if (ctx->cb != NULL) {
664         ctx->cb(ctx->aclHandle, result);
665     }
666 
667     L2capFree(ctx);
668     return;
669 }
670 
L2CIF_LeConnectionParameterUpdateReq(uint16_t aclHandle,const L2capLeConnectionParameter * param,void (* const cb)(uint16_t aclHandle,int result))671 int L2CIF_LeConnectionParameterUpdateReq(
672     uint16_t aclHandle, const L2capLeConnectionParameter *param, void (*const cb)(uint16_t aclHandle, int result))
673 {
674     L2cifLeConnectionParameterUpdateReqContext *ctx = NULL;
675 
676     if (param == NULL) {
677         return BT_BAD_PARAM;
678     }
679 
680     ctx = L2capAlloc(sizeof(L2cifLeConnectionParameterUpdateReqContext));
681     if (ctx == NULL) {
682         return BT_NO_MEMORY;
683     }
684 
685     ctx->aclHandle = aclHandle;
686     (void)memcpy_s(&(ctx->param), sizeof(L2capLeConnectionParameter), param, sizeof(L2capLeConnectionParameter));
687 
688     L2capAsynchronousProcess(L2cifLeConnectionParameterUpdateReq, L2capFree, ctx);
689     return BT_SUCCESS;
690 }
691 
692 typedef struct {
693     uint16_t aclHandle;
694     uint8_t id;
695     uint16_t result;
696     void (*cb)(uint16_t aclHandle, int result);
697 } L2cifLeConnectionParameterUpdateRspContext;
698 
L2cifLeConnectionParameterUpdateRsp(const void * context)699 static void L2cifLeConnectionParameterUpdateRsp(const void *context)
700 {
701     L2cifLeConnectionParameterUpdateRspContext *ctx = NULL;
702     int result;
703 
704     ctx = (L2cifLeConnectionParameterUpdateRspContext *)context;
705 
706     result = L2CAP_LeConnectionParameterUpdateRsp(ctx->aclHandle, ctx->id, ctx->result);
707     if (ctx->cb != NULL) {
708         ctx->cb(ctx->aclHandle, result);
709     }
710 
711     L2capFree(ctx);
712     return;
713 }
714 
L2CIF_LeConnectionParameterUpdateRsp(uint16_t aclHandle,uint8_t id,uint16_t result,void (* const cb)(uint16_t aclHandle,int result))715 void L2CIF_LeConnectionParameterUpdateRsp(
716     uint16_t aclHandle, uint8_t id, uint16_t result, void (*const cb)(uint16_t aclHandle, int result))
717 {
718     L2cifLeConnectionParameterUpdateRspContext *ctx = NULL;
719 
720     ctx = L2capAlloc(sizeof(L2cifLeConnectionParameterUpdateRspContext));
721     if (ctx == NULL) {
722         LOG_WARN("malloc failed");
723         return;
724     }
725     ctx->aclHandle = aclHandle;
726     ctx->id = id;
727     ctx->result = result;
728 
729     L2capAsynchronousProcess(L2cifLeConnectionParameterUpdateRsp, L2capFree, ctx);
730     return;
731 }