1 /*
2  * Copyright (C) 2021-2022 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 "avdtp_l2cap.h"
17 #include "avdtp_ctrl.h"
18 #include "avdtp_message.h"
19 #include "btm.h"
20 #include "btm/btm_interop.h"
21 #include "log.h"
22 #include "securec.h"
23 
24 /**
25  *  Function implement
26  */
27 const L2capService G_AVDT_L2C_APPL = {
28     AVDT_L2capConnectIndCallback,
29     AVDT_L2capConnectCfmCallback,
30     AVDT_L2capConfigIndCallback,
31     AVDT_L2capConfigCfmCallback,
32     AVDT_L2capDisconnectIndCallback,
33     AVDT_L2capDisconnectCfmCallback,
34     AVDT_L2capDisconnectAbnormalCallback,
35     AVDT_L2capReadDataIndCallback,
36     AVDT_L2capRemoteBusyCallback,
37 };
38 
39 /**
40  *
41  * @brief        AVDT_L2capConnectIndCallback
42  *
43  * @details      Acceptor receive the connect inication.
44  *
45  * @param[in]    addr: Address of peer device
46  *               lcid: L2CAP channel id
47  *               id: not used
48  *               psm: not used
49  *
50  * @return       void
51  *
52  */
AVDT_L2capConnectIndCallback(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t psm,void * ctx)53 void AVDT_L2capConnectIndCallback(uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t psm, void *ctx)
54 {
55     LOG_INFO("[AVDT]%{public}s: aclHandle(%hu), lcid(0x%x),addr(%02x:%02x:%02x:%02x:%02x:%02x)",
56         __func__,
57         info->handle,
58         lcid,
59         BT_ADDR_FMT_DSC(info->addr.addr));
60     AvdtL2capConnectIndCallbackTskParam *param = malloc(sizeof(AvdtL2capConnectIndCallbackTskParam));
61     if (param == NULL) {
62         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
63         return;
64     }
65     (void)memset_s(param, sizeof(AvdtL2capConnectIndCallbackTskParam), 0, sizeof(AvdtL2capConnectIndCallbackTskParam));
66     param->lcid = lcid;
67     param->id = id;
68     (void)memcpy_s(&param->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
69     param->psm = psm;
70     param->ctx = ctx;
71     if (AvdtAsyncProcess(AvdtL2capConnectIndCallbackTsk, param)) {
72         free(param);
73     }
74     return;
75 }
76 
AvdtL2capConnectIndCallbackTsk(void * context)77 void AvdtL2capConnectIndCallbackTsk(void *context)
78 {
79     AvdtL2capConnectIndCallbackTskParam *param = (AvdtL2capConnectIndCallbackTskParam *)context;
80     AvdtL2capConnectIndCallback(param->lcid, param->id, &param->info, param->psm, param->ctx);
81     free(context);
82     return;
83 }
84 
AvdtL2capConnectIndCallback(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t psm,void * ctx)85 void AvdtL2capConnectIndCallback(uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t psm, void *ctx)
86 {
87     LOG_DEBUG("[AVDT]%{public}s: aclHandle(%hu), lcid(0x%x),addr(%02x:%02x:%02x:%02x:%02x:%02x)",
88         __func__,
89         info->handle,
90         lcid,
91         BT_ADDR_FMT_DSC(info->addr.addr));
92     AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByAddr((BtAddr *)&(info->addr));
93     if (sigCtrl == NULL) {
94         AvdtConnectSignalingIndication(lcid, id, info);
95     } else {
96         AvdtConnectStreamIndication(lcid, id, info, sigCtrl);
97     }
98     return;
99 }
100 
101 /**
102  *
103  * @brief        AvdtConnectSignalingIndication
104  *
105  * @details      Process the signaling connect req.
106  *
107  * @param[in]    lcid: L2CAP channel id
108  *               id: not used
109  *               info: include address
110  *
111  * @return       void
112  *
113  */
AvdtConnectSignalingIndication(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info)114 void AvdtConnectSignalingIndication(uint16_t lcid, uint8_t id, const L2capConnectionInfo *info)
115 {
116     LOG_INFO("[AVDT]%{public}s", __func__);
117     GapSecChannel chlId = {0};
118     /* signaling channel process */
119     AvdtCreateSEP((BtAddr *)&(info->addr));
120     AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByAddr((BtAddr *)&(info->addr));
121     if (sigCtrl == NULL) {
122         /* Trace: No resources */
123         LOG_ERROR("[AVDT]%{public}s: There is no resource for alloce channel control block ", __func__);
124     } else {
125         sigCtrl->ia = AVDT_ACP;
126         sigCtrl->lcid = lcid;
127         /* security process:GAP authority */
128         chlId.l2capPsm = AVDT_PSM;
129         /* create transport table */
130         AvdtTransChannel *transTable = AvdtTransChTabAllocate(AVDT_CH_TYPE_SIG, sigCtrl, NULL);
131         if (transTable == NULL) {
132             /* Trace error: No transcation table resources */
133             LOG_ERROR("[AVDT]%{public}s: no resources for transcation channel ctrol block ", __func__);
134             return;
135         }
136         /* Interop check */
137         if (BtmInteropIsMatchedAddr(INTEROP_2MBPS_LINK_ONLY, (const BtAddr *)&(info->addr))) {
138             BTM_ChangeConnectionPacketType((const BtAddr *)&(info->addr),
139                 BTM_ACL_PACKET_TYPE_DEFAULT | BTM_ACL_PACKET_TYPE_NO_3_DH1 | BTM_ACL_PACKET_TYPE_NO_3_DH3 |
140                     BTM_ACL_PACKET_TYPE_NO_3_DH5);
141         }
142         /* save the information of table */
143         transTable->lcid = lcid;
144         transTable->id = id;
145         transTable->state = AVDT_TRANS_ST_SECURITY_ACP;
146         /* set security */
147         GapRequestSecurityParam param = {0};
148         param.callback = AvdtRevSecurityCheckCallback;
149         param.info.channelId = chlId;
150         param.info.protocolId = SEC_PROTOCOL_L2CAP;
151         param.info.direction = INCOMING;
152         param.info.serviceId = GAVDP_ACP;
153         param.context = transTable;
154         if (GAPIF_RequestSecurityAsync(&sigCtrl->peerAddress, &param)) {
155             LOG_ERROR("[AVCT] %{public}s:GAP_RequestSecurity failed!", __func__);
156         }
157     }
158     return;
159 }
160 
161 /**
162  *
163  * @brief        AvdtConnectStreamIndication
164  *
165  * @details      Process the meida connect req.
166  *
167  * @param[in]    lcid: L2CAP channel id
168  *               id: not used
169  *               info: include address
170  *               sigCtrl: control block
171  *
172  * @return       void
173  *
174  */
AvdtConnectStreamIndication(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,AvdtSigCtrl * sigCtrl)175 void AvdtConnectStreamIndication(uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, AvdtSigCtrl *sigCtrl)
176 {
177     LOG_INFO("[AVDT]%{public}s", __func__);
178     AvdtTransChannel *transTable = AvdtGetTransChTabByHandle(AVDT_CH_TYPE_SIG, sigCtrl->handle);
179     if (transTable != NULL && transTable->state == AVDT_TRANS_ST_CONNECTION) {
180         L2CIF_ConnectRsp(lcid, id, L2CAP_SOURCE_CID_ALREADY_ALLOCATED, 0, NULL);
181         return;
182     }
183     if (AvdtGetTransChTabByLcid(lcid)) {
184         L2CIF_ConnectRsp(lcid, id, L2CAP_NO_RESOURCES_AVAILABLE, 0, NULL);
185         return;
186     }
187     AvdtStreamCtrl *streamCtrl = AvdtGetStreamCtrlByHandle(sigCtrl->streamHandle);
188     if (streamCtrl == NULL) {
189         LOG_ERROR("[AVDT]%{public}s: AvdtGetStreamCtrlByHandle(%hu) Failed!", __func__, sigCtrl->streamHandle);
190         return;
191     }
192     transTable = AvdtTransChTabAllocate(AVDT_CH_TYPE_STREAM, sigCtrl, streamCtrl);
193     if (transTable != NULL) {
194         L2CIF_ConnectRsp(lcid, id, L2CAP_CONNECTION_SUCCESSFUL, 0, NULL);
195         transTable->lcid = lcid;
196         sigCtrl->ia = AVDT_ACP;
197         L2capConfigInfo cfg = {0};
198         cfg.mtu = AvdtGetMtu();
199         cfg.flushTimeout = 0xFFFF;
200         L2CIF_ConfigReq(transTable->lcid, &cfg, NULL);
201     } else {
202         LOG_ERROR("[AVDT]%{public}s: There is no resource for transTable ", __func__);
203         L2CIF_ConnectRsp(lcid, id, L2CAP_NO_RESOURCES_AVAILABLE, 0, NULL);
204     }
205     return;
206 }
207 
208 /**
209  *
210  * @brief         AVDT_L2capConnectCfmCallback
211  *
212  * @details       Initator receive the L2CAP connect respond.
213  *
214  * @param[in]     lcid:L2CAP channel id
215  *                result:Connect restult
216  *                status:Connect status
217  *
218  * @return        void
219  *
220  */
AVDT_L2capConnectCfmCallback(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * ctx)221 void AVDT_L2capConnectCfmCallback(
222     uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *ctx)
223 {
224     LOG_INFO("[AVDT]%{public}s: aclHandle(%hu), lcid(0x%x),addr(%02x:%02x:%02x:%02x:%02x:%02x)",
225         __func__,
226         info->handle,
227         lcid,
228         BT_ADDR_FMT_DSC(info->addr.addr));
229     AvdtL2capConnectCfmCallbackTskParam *param = malloc(sizeof(AvdtL2capConnectCfmCallbackTskParam));
230     if (param == NULL) {
231         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
232         return;
233     }
234     (void)memset_s(param, sizeof(AvdtL2capConnectCfmCallbackTskParam), 0, sizeof(AvdtL2capConnectCfmCallbackTskParam));
235     param->lcid = lcid;
236     (void)memcpy_s(&param->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
237     param->result = result;
238     param->status = status;
239     param->ctx = ctx;
240     if (AvdtAsyncProcess(AvdtL2capConnectCfmCallbackTsk, param)) {
241         free(param);
242     }
243     return;
244 }
245 
AvdtL2capConnectCfmCallbackTsk(void * context)246 void AvdtL2capConnectCfmCallbackTsk(void *context)
247 {
248     AvdtL2capConnectCfmCallbackTskParam *param = (AvdtL2capConnectCfmCallbackTskParam *)context;
249     AvdtL2capConnectCfmCallback(param->lcid, &param->info, param->result, param->status, param->ctx);
250     free(context);
251     return;
252 }
253 
AvdtL2capConnectCfmCallback(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * ctx)254 void AvdtL2capConnectCfmCallback(
255     uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *ctx)
256 {
257     LOG_DEBUG("[AVDT]%{public}s:lcid(0x%x), result(%hu),status(%hu),addr(%02x:%02x:%02x:%02x:%02x:%02x)",
258         __func__,
259         lcid,
260         result,
261         status,
262         BT_ADDR_FMT_DSC(info->addr.addr));
263     if (result == L2CAP_CONNECTION_PENDING) {
264         LOG_INFO("[AVDT]%{public}s: Connect RSP result is pending, do nothing!", __func__);
265         return;
266     }
267     /* Judge the result and status according to L2CAP API */
268     AvdtTransChannel *transTable = AvdtGetTransChTabByLcid(lcid);
269     if (transTable != NULL) {
270         if (result == AVDT_SUCCESS) {
271             transTable->state = AVDT_TRANS_ST_CFG;
272             L2capConfigInfo cfg = {0};
273             cfg.mtu = AvdtGetMtu();
274             cfg.flushTimeout = 0xFFFF;
275             L2CIF_ConfigReq(lcid, &cfg, NULL);
276             LOG_DEBUG("[AVDT]%{public}s:L2CIF_ConfigReq: signalling", __func__);
277         } else {
278             AvdtConnectConfirmError(transTable);
279         }
280     }
281     return;
282 }
283 
284 /**
285  *
286  * @brief         AvdtConnectConfirmError
287  *
288  * @details       Process the failure of L2CAP connect respond.
289  *
290  * @param[in]     transTable:Transport table
291  *
292  * @return        void
293  *
294  */
AvdtConnectConfirmError(const AvdtTransChannel * transTable)295 void AvdtConnectConfirmError(const AvdtTransChannel *transTable)
296 {
297     LOG_INFO("[AVDT]%{public}s ", __func__);
298     AvdtCtrlData confirmData = {0};
299     uint8_t event;
300     AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByHandle(transTable->sigHandle);
301     if (sigCtrl == NULL) {
302         LOG_ERROR("[AVDT]%{public}s:AvdtGetSigCtrlByHandle(%hu) Failed", __func__, transTable->sigHandle);
303         return;
304     }
305     LOG_DEBUG("[AVDT]%{public}s:Get sigCtrl info:transTable->sigHandle(%hu),transTable->type(%hhu),sigCtrl->role(%hhu)",
306         __func__,
307         transTable->sigHandle,
308         transTable->type,
309         sigCtrl->role);
310     confirmData.connectCfm.errCode = AVDT_FAILED;
311     switch (transTable->type) {
312         case AVDT_CH_TYPE_SIG:
313             event = AVDT_CONNECT_CFM_EVT;
314             AvdtCtrlEvtCallback(sigCtrl, sigCtrl->handle, &(sigCtrl->peerAddress), event, &confirmData, sigCtrl->role);
315             AvdtTransChDealloc(transTable->lcid);
316             AvdtFreeSigCtrlByHandle(sigCtrl->handle);
317             break;
318         case AVDT_CH_TYPE_STREAM: {
319             event = AVDT_OPEN_CFM_EVT;
320             AvdtCtrlEvtCallback(
321                 sigCtrl, transTable->streamHandle, &(sigCtrl->peerAddress), event, &confirmData, sigCtrl->role);
322             /* clear the local stream is used information */
323             AvdtStreamCtrlDeallocByHandle(sigCtrl, transTable->streamHandle);
324             AvdtTransChDealloc(transTable->lcid);
325             break;
326         }
327         default:
328             break;
329     }
330 }
331 
332 /**
333  *
334  * @brief         AVDT_L2capConfigIndCallback
335  *
336  * @details       Receive the l2cap configure req.
337  *
338  * @param[in]     lcid: L2CAP channel id
339  *                cfg:  L2CAP configure information
340  *                id:   L2CAP id
341  *
342  * @return        void
343  *
344  */
AVDT_L2capConfigIndCallback(uint16_t lcid,uint8_t id,const L2capConfigInfo * cfg,void * ctx)345 void AVDT_L2capConfigIndCallback(uint16_t lcid, uint8_t id, const L2capConfigInfo *cfg, void *ctx)
346 {
347     LOG_INFO("[AVDT]%{public}s: lcid(0x%x),id(0x%x)", __func__, lcid, id);
348     AvdtL2capConfigIndCallbackTskParam *param = malloc(sizeof(AvdtL2capConfigIndCallbackTskParam));
349     if (param == NULL) {
350         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
351         return;
352     }
353     (void)memset_s(param, sizeof(AvdtL2capConfigIndCallbackTskParam), 0, sizeof(AvdtL2capConfigIndCallbackTskParam));
354     param->lcid = lcid;
355     param->id = id;
356     (void)memcpy_s(&param->cfg, sizeof(L2capConfigInfo), cfg, sizeof(L2capConfigInfo));
357     param->ctx = ctx;
358     if (AvdtAsyncProcess(AvdtL2capConfigIndCallbackTsk, param)) {
359         free(param);
360     }
361     return;
362 }
363 
AvdtL2capConfigIndCallbackTsk(void * context)364 void AvdtL2capConfigIndCallbackTsk(void *context)
365 {
366     AvdtL2capConfigIndCallbackTskParam *param = (AvdtL2capConfigIndCallbackTskParam *)context;
367     AvdtL2capConfigIndCallback(param->lcid, param->id, &param->cfg, param->ctx);
368     free(context);
369     return;
370 }
371 
AvdtL2capConfigIndCallback(uint16_t lcid,uint8_t id,const L2capConfigInfo * cfg,void * ctx)372 void AvdtL2capConfigIndCallback(uint16_t lcid, uint8_t id, const L2capConfigInfo *cfg, void *ctx)
373 {
374     LOG_DEBUG("[AVDT]%{public}s: lcid(0x%x),id(0x%x)", __func__, lcid, id);
375     AvdtTransChannel *transTable = AvdtGetTransChTabByLcid(lcid);
376     if (transTable != NULL) {
377         AvdtConfigureIndication(lcid, id, cfg, transTable);
378     } else {
379         /* Trace: No resources */
380         LOG_INFO("[AVDT]%{public}s: Config REJECTED! By can't find the transTable by lcid(0x%x)", __func__, lcid);
381         L2CIF_ConfigRsp(lcid, id, cfg, L2CAP_REJECTED, NULL);
382     }
383     return;
384 }
385 
386 /**
387  *
388  * @brief         AvdtConfigureIndication
389  *
390  * @details       Receive the l2cap configure req.
391  *
392  * @param[in]     lcid: L2CAP channel id
393  *                cfg:  L2CAP configure information
394  *                id:   L2CAP id
395  *                transTable:Transport table
396  *
397  * @return        void
398  *
399  */
AvdtConfigureIndication(uint16_t lcid,uint8_t id,const L2capConfigInfo * cfg,AvdtTransChannel * transTable)400 void AvdtConfigureIndication(uint16_t lcid, uint8_t id, const L2capConfigInfo *cfg, AvdtTransChannel *transTable)
401 {
402     LOG_INFO("[AVDT]%{public}s ", __func__);
403     if (cfg->rfc.mode == L2CAP_BASIC_MODE) {
404         L2capConfigInfo l2capCfg = {0};
405         (void)memcpy_s(&l2capCfg, sizeof(L2capConfigInfo), cfg, sizeof(L2capConfigInfo));
406         if (cfg->mtu > AvdtGetMtu()) {
407             transTable->peerMtu = AvdtGetMtu();
408             l2capCfg.mtu = AvdtGetMtu();
409         } else {
410             transTable->peerMtu = cfg->mtu;
411         }
412         transTable->peerFlushTo = cfg->flushTimeout;
413         transTable->state = AVDT_TRANS_ST_CFG;
414         L2CIF_ConfigRsp(lcid, id, &l2capCfg, L2CAP_SUCCESS, NULL);
415         transTable->cfgFlags |= AVDT_CFG_IND;
416         if (transTable->cfgFlags == AVDT_CFG_END) {
417             AvdtConfigComplete(transTable);
418         }
419     } else {
420         LOG_WARN("[AVCT] %{public}s: Config UNACCEPT! By mode is not basemode", __func__);
421         L2capConfigInfo rspCfg = {0};
422         rspCfg.mtu = cfg->mtu;
423         rspCfg.flushTimeout = 0xFFFF;
424         rspCfg.fcs = 0x01;
425         rspCfg.rfc.mode = L2CAP_BASIC_MODE;
426         L2CIF_ConfigRsp(lcid, id, &rspCfg, L2CAP_UNACCEPTABLE_PARAMETERS, NULL);
427     }
428     return;
429 }
430 
431 /**
432  *
433  * @brief         AvdtConfigComplete
434  *
435  * @details       Config complete,nofify state to up app.
436  *
437  * @param[in]     transTable: transport table
438  *
439  * @return        void
440  *
441  */
AvdtConfigComplete(AvdtTransChannel * transTable)442 void AvdtConfigComplete(AvdtTransChannel *transTable)
443 {
444     uint8_t event = 0;
445     uint8_t stEvent;
446     AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByHandle(transTable->sigHandle);
447     if (sigCtrl == NULL) {
448         /* Trace: No resources */
449         LOG_ERROR("[AVDT]%{public}s: AvdtGetSigCtrlByHandle(%hu) Failed!", __func__, transTable->sigHandle);
450         return;
451     }
452     switch (transTable->type) {
453         case AVDT_CH_TYPE_SIG:
454             if (sigCtrl->ia == AVDT_ACP) {
455                 event = AVDT_CONNECT_IND_EVT;
456                 stEvent = AVDT_CONNECT_CMD_IND_EVENT;
457             } else {
458                 event = AVDT_CONNECT_CFM_EVT;
459                 stEvent = AVDT_CONNECT_CMD_CFM_EVENT;
460             }
461             AvdtSigProcEvent(sigCtrl, stEvent, NULL);
462             break;
463         case AVDT_CH_TYPE_STREAM:
464             if (sigCtrl->ia == AVDT_ACP) {
465                 event = AVDT_OPEN_IND_EVT;
466             } else {
467                 event = AVDT_OPEN_CFM_EVT;
468             }
469             AvdtStreamCtrl *streamCtrl = AvdtGetStreamCtrlByHandle(transTable->streamHandle);
470             if (streamCtrl != NULL) {
471                 AvdtStreamProcEvent(streamCtrl, AVDT_STREAM_OPEN_CMD_CFM_EVENT, NULL);
472             }
473             break;
474         default:
475             break;
476     }
477     transTable->state = AVDT_TRANS_ST_COMPLETE;
478     AvdtCtrlData confirmData = {0};
479     confirmData.connectCfm.errCode = AVDT_SUCCESS;
480     confirmData.connectCfm.mtu = transTable->peerMtu;
481     AvdtCtrlEvtCallback(sigCtrl, transTable->streamHandle, &sigCtrl->peerAddress, event, &confirmData, sigCtrl->role);
482     return;
483 }
484 /**
485  *
486  * @brief         AVDT_L2capConfigCfmCallback
487  *
488  * @details       Receive the l2cap configure respond.
489  *
490  * @param[in]     lcid: L2CAP channel id
491  *                cfg:  L2CAP configure information
492  *                id:   L2CAP id
493  *
494  * @return        void
495  *
496  */
AVDT_L2capConfigCfmCallback(uint16_t lcid,const L2capConfigInfo * cfg,uint16_t result,void * ctx)497 void AVDT_L2capConfigCfmCallback(uint16_t lcid, const L2capConfigInfo *cfg, uint16_t result, void *ctx)
498 {
499     LOG_INFO("[AVDT]%{public}s: lcid(0x%x),result(%hu)", __func__, lcid, result);
500     AvdtL2capConfigCfmCallbackTskParam *param = malloc(sizeof(AvdtL2capConfigCfmCallbackTskParam));
501     if (param == NULL) {
502         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
503         return;
504     }
505     (void)memset_s(param, sizeof(AvdtL2capConfigCfmCallbackTskParam), 0, sizeof(AvdtL2capConfigCfmCallbackTskParam));
506     param->lcid = lcid;
507     (void)memcpy_s(&param->cfg, sizeof(L2capConfigInfo), cfg, sizeof(L2capConfigInfo));
508     param->result = result;
509     param->ctx = ctx;
510     if (AvdtAsyncProcess(AvdtL2capConfigCfmCallbackTsk, param)) {
511         free(param);
512     }
513     return;
514 }
515 
AvdtL2capConfigCfmCallbackTsk(void * context)516 void AvdtL2capConfigCfmCallbackTsk(void *context)
517 {
518     AvdtL2capConfigCfmCallbackTskParam *param = (AvdtL2capConfigCfmCallbackTskParam *)context;
519     AvdtL2capConfigCfmCallback(param->lcid, &param->cfg, param->result, param->ctx);
520     free(context);
521     return;
522 }
523 
AvdtL2capConfigCfmCallback(uint16_t lcid,const L2capConfigInfo * cfg,uint16_t result,void * ctx)524 void AvdtL2capConfigCfmCallback(uint16_t lcid, const L2capConfigInfo *cfg, uint16_t result, void *ctx)
525 {
526     LOG_DEBUG("[AVDT]%{public}s: lcid(0x%x),result(%hu)", __func__, lcid, result);
527     AvdtTransChannel *transTable = AvdtGetTransChTabByLcid(lcid);
528     if (transTable != NULL) {
529         if (result == AVDT_SUCCESS) {
530             AvdtConfigureConfirm(transTable);
531         } else {
532             AvdtConnectConfirmError(transTable);
533         }
534     } else {
535         LOG_ERROR("[AVDT]%{public}s: can't find the transtable by lcid(0x%x)", __func__, lcid);
536     }
537     return;
538 }
539 
540 /**
541  *
542  * @brief         AvdtConfigureConfirm
543  *
544  * @details       Process the l2cap configure respond.
545  *
546  * @param[in]     transTable:   transport table
547  *
548  * @return        void
549  *
550  */
AvdtConfigureConfirm(AvdtTransChannel * transTable)551 void AvdtConfigureConfirm(AvdtTransChannel *transTable)
552 {
553     LOG_INFO("[AVDT]%{public}s: ", __func__);
554     transTable->state = AVDT_TRANS_ST_CFG;
555     transTable->cfgFlags |= AVDT_CFG_CFM;
556     if (transTable->cfgFlags == AVDT_CFG_END) {
557         AvdtConfigComplete(transTable);
558     }
559 }
560 
561 /**
562  *
563  * @brief         AVDT_L2capDisconnectIndCallback
564  *
565  * @details       Acceptor receive the l2cap disconnect indication.
566  *
567  * @param[in]     lcid: L2CAP channel id
568  *                cfg:  L2CAP configure information
569  *                id:   L2CAP id
570  *
571  * @return        void
572  *
573  */
AVDT_L2capDisconnectIndCallback(uint16_t lcid,uint8_t id,void * ctx)574 void AVDT_L2capDisconnectIndCallback(uint16_t lcid, uint8_t id, void *ctx)
575 {
576     LOG_INFO("[AVDT]%{public}s: lcid(0x%x),id(0x%x)", __func__, lcid, id);
577     AvdtL2capDisconnectIndCallbackTskParam *param = malloc(sizeof(AvdtL2capDisconnectIndCallbackTskParam));
578     if (param == NULL) {
579         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
580         return;
581     }
582     (void)memset_s(
583         param, sizeof(AvdtL2capDisconnectIndCallbackTskParam), 0, sizeof(AvdtL2capDisconnectIndCallbackTskParam));
584     param->lcid = lcid;
585     param->id = id;
586     param->ctx = ctx;
587     if (AvdtAsyncProcess(AvdtL2capDisconnectIndCallbackTsk, param)) {
588         free(param);
589     }
590     return;
591 }
592 
AvdtL2capDisconnectIndCallbackTsk(void * context)593 void AvdtL2capDisconnectIndCallbackTsk(void *context)
594 {
595     AvdtL2capDisconnectIndCallbackTskParam *param = (AvdtL2capDisconnectIndCallbackTskParam *)context;
596     AvdtL2capDisconnectIndCallback(param->lcid, param->id, param->ctx);
597     free(context);
598     return;
599 }
600 
AvdtL2capDisconnectIndCallback(uint16_t lcid,uint8_t id,void * ctx)601 void AvdtL2capDisconnectIndCallback(uint16_t lcid, uint8_t id, void *ctx)
602 {
603     LOG_DEBUG("[AVDT]%{public}s: lcid(0x%x),id(0x%x)", __func__, lcid, id);
604     AvdtTransChannel *transTable = AvdtGetTransChTabByLcid(lcid);
605     if (transTable == NULL) {
606         L2CIF_DisconnectionRsp(lcid, id, NULL);
607         /* Trace no resources */
608         return;
609     }
610     switch (transTable->type) {
611         case AVDT_CH_TYPE_SIG: {
612             AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByHandle(transTable->sigHandle);
613             if (sigCtrl != NULL) {
614                 AvdtSigProcEvent(sigCtrl, AVDT_DISCONNECT_CMD_IND_EVENT, NULL);
615             }
616             break;
617         }
618         case AVDT_CH_TYPE_STREAM: {
619             AvdtStreamCtrl *streamCtrl = AvdtGetStreamCtrlByHandle(transTable->streamHandle);
620             if (streamCtrl != NULL) {
621                 AvdtStreamProcEvent(streamCtrl, AVDT_STREAM_CLOSE_CMD_IND_EVENT, NULL);
622             }
623             break;
624         }
625         default:
626             break;
627     }
628     /* clear the tabel information */
629     L2CIF_DisconnectionRsp(lcid, id, NULL);
630     AvdtTransChDealloc(lcid);
631     return;
632 }
633 
634 /**
635  *
636  * @brief         AVDT_L2capDisconnectCfmCallback
637  *
638  * @details       Initatior receive the l2cap disconnect respond.
639  *
640  * @param[in]     lcid: L2CAP channel id
641  *                cfg:  L2CAP configure information
642  *                id:   L2CAP id
643  *
644  * @return        void
645  *
646  */
AVDT_L2capDisconnectCfmCallback(uint16_t lcid,void * ctx)647 void AVDT_L2capDisconnectCfmCallback(uint16_t lcid, void *ctx)
648 {
649     LOG_INFO("[AVDT]%{public}s: lcid(0x%x)", __func__, lcid);
650     AvdtL2capDisconnectCfmCallbackTskParam *param = malloc(sizeof(AvdtL2capDisconnectCfmCallbackTskParam));
651     if (param == NULL) {
652         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
653         return;
654     }
655     (void)memset_s(
656         param, sizeof(AvdtL2capDisconnectCfmCallbackTskParam), 0, sizeof(AvdtL2capDisconnectCfmCallbackTskParam));
657     param->lcid = lcid;
658     param->ctx = ctx;
659     if (AvdtAsyncProcess(AvdtL2capDisconnectCfmCallbackTsk, param)) {
660         free(param);
661     }
662     return;
663 }
664 
AvdtL2capDisconnectCfmCallbackTsk(void * context)665 void AvdtL2capDisconnectCfmCallbackTsk(void *context)
666 {
667     AvdtL2capDisconnectCfmCallbackTskParam *param = (AvdtL2capDisconnectCfmCallbackTskParam *)context;
668     AvdtL2capDisconnectCfmCallback(param->lcid, param->ctx);
669     free(context);
670     return;
671 }
672 
AvdtL2capDisconnectCfmCallback(uint16_t lcid,void * ctx)673 void AvdtL2capDisconnectCfmCallback(uint16_t lcid, void *ctx)
674 {
675     LOG_DEBUG("[AVDT]%{public}s: lcid(0x%x)", __func__, lcid);
676     AvdtTransChannel *transTable = AvdtGetTransChTabByLcid(lcid);
677     if (transTable == NULL) {
678         /* Trace no resources */
679         LOG_ERROR("[AVDT]%{public}s:AvdtGetTransChTabByLcid(0x%x) Failed!!", __func__, lcid);
680         return;
681     }
682     switch (transTable->type) {
683         case AVDT_CH_TYPE_SIG: {
684             AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByHandle(transTable->sigHandle);
685             if (sigCtrl != NULL) {
686                 AvdtSigProcEvent(sigCtrl, AVDT_DISCONNECT_CMD_CFM_EVENT, NULL);
687             }
688             break;
689         }
690         case AVDT_CH_TYPE_STREAM: {
691             AvdtStreamCtrl *streamCtrl = AvdtGetStreamCtrlByHandle(transTable->streamHandle);
692             if (streamCtrl != NULL) {
693                 AvdtStreamProcEvent(streamCtrl, AVDT_STREAM_CLOSE_CMD_CFM_EVENT, NULL);
694             }
695             break;
696         }
697         default:
698             break;
699     }
700     AvdtTransChDealloc(transTable->lcid);
701     return;
702 }
703 
704 /**
705  *
706  * @brief        AVDT_L2capReadDataIndCallback
707  *
708  * @details      Receive the l2cap indication to read data .
709  *
710  * @param[in]    lcid:      L2CAP channel id
711  *               packet:    data of signalling or media
712  *
713  * @return       void
714  *
715  */
AVDT_L2capReadDataIndCallback(uint16_t lcid,Packet * packet,void * ctx)716 void AVDT_L2capReadDataIndCallback(uint16_t lcid, Packet *packet, void *ctx)
717 {
718     LOG_INFO("[AVDT]%{public}s:lcid(0x%x) ,PacketSize(%u)", __func__, lcid, PacketSize(packet));
719     AvdtL2capReadDataIndCallbackTskParam *param = malloc(sizeof(AvdtL2capReadDataIndCallbackTskParam));
720     if (param == NULL) {
721         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
722         return;
723     }
724     (void)memset_s(
725         param, sizeof(AvdtL2capReadDataIndCallbackTskParam), 0, sizeof(AvdtL2capReadDataIndCallbackTskParam));
726     param->lcid = lcid;
727     param->packet = PacketRefMalloc(packet);
728     param->ctx = ctx;
729     if (AvdtAsyncProcess(AvdtL2capReadDataIndCallbackTsk, param)) {
730         PacketFree(param->packet);
731         free(param);
732     }
733     return;
734 }
735 
AvdtL2capReadDataIndCallbackTsk(void * context)736 void AvdtL2capReadDataIndCallbackTsk(void *context)
737 {
738     AvdtL2capReadDataIndCallbackTskParam *param = (AvdtL2capReadDataIndCallbackTskParam *)context;
739     AvdtL2capReadDataIndCallback(param->lcid, param->packet, param->ctx);
740     PacketFree(param->packet);
741     free(context);
742     return;
743 }
744 
AvdtL2capReadDataIndCallback(uint16_t lcid,Packet * packet,void * ctx)745 void AvdtL2capReadDataIndCallback(uint16_t lcid, Packet *packet, void *ctx)
746 {
747     if (packet == NULL) {
748         LOG_ERROR("[AVDT]%{public}s:packet is null!!", __func__);
749         return;
750     }
751     LOG_INFO("[AVDT]%{public}s:lcid(0x%x) ,PacketSize(%u)", __func__, lcid, PacketSize(packet));
752     AvdtTransChannel *transTable = AvdtGetTransChTabByLcid(lcid);
753     if (transTable == NULL) {
754         LOG_ERROR("[AVDT]%{public}s:AvdtGetTransChTabByLcid(0x%x) Failed!!", __func__, lcid);
755         return;
756     }
757     LOG_DEBUG("[AVDT]%{public}s:transTable->type(%hhu), transTable->streamHandle(%hu),transTable->sigHandle(%hu) ",
758         __func__,
759         transTable->type,
760         transTable->streamHandle,
761         transTable->sigHandle);
762     switch (transTable->type) {
763         case AVDT_CH_TYPE_SIG: {
764             AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByHandle(transTable->sigHandle);
765             if (sigCtrl != NULL) {
766                 /* debug log */
767                 AvdtPktDataPrint(packet);
768                 AvdtParseMsg(sigCtrl, packet);
769             } else {
770                 /* Trace: No resources */
771                 LOG_ERROR("[AVDT]%{public}s: AvdtGetSigCtrlByHandle(%hu) Failed!", __func__, transTable->sigHandle);
772             }
773             break;
774         }
775         case AVDT_CH_TYPE_STREAM: {
776             AvdtStreamCtrl *streamCtrl = AvdtGetStreamCtrlByHandle(transTable->streamHandle);
777             if (streamCtrl != NULL) {
778                 AvdtStreamDataProc(streamCtrl, packet);
779             } else {
780                 /* Trace: No resources */
781                 LOG_ERROR("[AVDT]%{public}s:AvdtGetStreamCtrlByHandle(%hu) Failed!",
782                     __func__, transTable->streamHandle);
783             }
784             break;
785         }
786         default:
787             break;
788     }
789     return;
790 }
791 
792 /**
793  *
794  * @brief        AvdtStreamDataProc
795  *
796  * @details      Stream Media packet data process.
797  *
798  * @param[in]    streamCtrl:    Stream Media channel control
799  *               packet:        data of media
800  *
801  * @return       void
802  *
803  */
AvdtStreamDataProc(AvdtStreamCtrl * streamCtrl,Packet * packet)804 void AvdtStreamDataProc(AvdtStreamCtrl *streamCtrl, Packet *packet)
805 {
806     uint8_t data = 0;
807     uint8_t ssrc[4] = {0};
808     PacketExtractHead(packet, &data, 1);
809     PacketExtractHead(packet, &data, 1);
810     uint8_t pktType = (data & 0xF7);
811     PacketExtractHead(packet, &data, 1);
812     PacketExtractHead(packet, &data, 1);
813     PacketExtractHead(packet, &data, 1);
814     uint32_t timeStamp = (data << AVDT_OFFSET_24BIT);
815     PacketExtractHead(packet, &data, 1);
816     timeStamp = (timeStamp | (data << AVDT_OFFSET_16BIT));
817     PacketExtractHead(packet, &data, 1);
818     timeStamp = (timeStamp | (data << AVDT_OFFSET_8BIT));
819     PacketExtractHead(packet, &data, 1);
820     timeStamp = (timeStamp | data);
821     /* extract ssrc data */
822     PacketExtractHead(packet, &ssrc[0], AVDT_4BYTE);
823     AvdtStreamConfig *streamConfig = AvdtGetSepConfigByCodecIndex(streamCtrl->codecIndex);
824     if ((streamConfig != NULL) && (streamConfig->sinkDataCback != NULL)) {
825         streamConfig->sinkDataCback(streamCtrl->handle, packet, timeStamp, pktType, streamCtrl->codecIndex);
826     }
827 }
828 
829 /**
830  *
831  * @brief         AvdtRevSecurityCheckCallback
832  *
833  * @details       Acp receive security check result.
834  *
835  * @return        void
836  *
837  */
AvdtRevSecurityCheckCallback(uint16_t result,GapServiceSecurityInfo security,void * context)838 void AvdtRevSecurityCheckCallback(uint16_t result, GapServiceSecurityInfo security, void *context)
839 {
840     LOG_INFO("[AVDT]%{public}s:result(%hu), l2capPsm(0x%x)", __func__, result, security.channelId.l2capPsm);
841     AvdtRevSecurityCheckTskParam *param = malloc(sizeof(AvdtRevSecurityCheckTskParam));
842     if (param == NULL) {
843         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
844         return;
845     }
846     (void)memset_s(param, sizeof(AvdtRevSecurityCheckTskParam), 0, sizeof(AvdtRevSecurityCheckTskParam));
847     param->result = result;
848     (void)memcpy_s(&param->security, sizeof(GapServiceSecurityInfo), &security, sizeof(GapServiceSecurityInfo));
849     param->context = context;
850     if (AvdtAsyncProcess(AvdtRevSecurityCheckTsk, param)) {
851         free(param);
852     }
853     return;
854 }
855 
AvdtRevSecurityCheckTsk(void * context)856 void AvdtRevSecurityCheckTsk(void *context)
857 {
858     AvdtRevSecurityCheckTskParam *param = (AvdtRevSecurityCheckTskParam *)context;
859     AvdtRevSecurityCheck(param->result, param->security, param->context);
860     free(context);
861     return;
862 }
863 
AvdtRevSecurityCheck(uint16_t result,GapServiceSecurityInfo security,void * context)864 void AvdtRevSecurityCheck(uint16_t result, GapServiceSecurityInfo security, void *context)
865 {
866     AvdtTransChannel *transTable = (AvdtTransChannel *)context;
867     LOG_DEBUG("[AVDT]%{public}s:result(%hu),lcid(0x%x), psm(0x%x)",
868         __func__, result, transTable->lcid, security.channelId.l2capPsm);
869     if (result == AVDT_SUCCESS) {
870         /* Call L2CAP connect respond API */
871         L2CIF_ConnectRsp(transTable->lcid, transTable->id, L2CAP_CONNECTION_SUCCESSFUL, 0, NULL);
872         L2capConfigInfo cfg = {0};
873         cfg.mtu = AvdtGetMtu();
874         cfg.flushTimeout = 0xFFFF;
875         L2CIF_ConfigReq(transTable->lcid, &cfg, NULL);
876     } else {
877         L2CIF_ConnectRsp(transTable->lcid, transTable->id, L2CAP_SECURITY_BLOCK, 0, NULL);
878     }
879     return;
880 }
881 
882 /**
883  *
884  * @brief         AVDT_L2capDisconnectAbnormalCallback
885  *
886  * @details       receive disconnect abnormal from l2cap.
887  *
888  * @return        void
889  *
890  */
AVDT_L2capDisconnectAbnormalCallback(uint16_t lcid,uint8_t reason,void * ctx)891 void AVDT_L2capDisconnectAbnormalCallback(uint16_t lcid, uint8_t reason, void *ctx)
892 {
893     LOG_INFO("[AVDT]%{public}s: lcid(0x%x) reason(%hhu)", __func__, lcid, reason);
894     AvdtL2capDisconnectAbnormalCallbackTskParam *param = malloc(sizeof(AvdtL2capDisconnectAbnormalCallbackTskParam));
895     if (param == NULL) {
896         LOG_ERROR("[AVDT] %{public}s: memory malloc failed", __func__);
897         return;
898     }
899     (void)memset_s(param,
900         sizeof(AvdtL2capDisconnectAbnormalCallbackTskParam),
901         0,
902         sizeof(AvdtL2capDisconnectAbnormalCallbackTskParam));
903     param->lcid = lcid;
904     param->reason = reason;
905     param->ctx = ctx;
906     if (AvdtAsyncProcess(AvdtL2capDisconnectAbnormalCallbackTsk, param)) {
907         free(param);
908     }
909     return;
910 }
911 
AvdtL2capDisconnectAbnormalCallbackTsk(void * context)912 void AvdtL2capDisconnectAbnormalCallbackTsk(void *context)
913 {
914     AvdtL2capDisconnectAbnormalCallbackTskParam *param = (AvdtL2capDisconnectAbnormalCallbackTskParam *)context;
915     AvdtL2capDisconnectAbnormalCallback(param->lcid, param->reason, param->ctx);
916     free(context);
917     return;
918 }
AvdtL2capDisconnectAbnormalCallback(uint16_t lcid,uint8_t reason,void * ctx)919 void AvdtL2capDisconnectAbnormalCallback(uint16_t lcid, uint8_t reason, void *ctx)
920 {
921     LOG_DEBUG("[AVDT]%{public}s: lcid(0x%x) reason(%hhu)", __func__, lcid, reason);
922     AvdtTransChannel *transTable = AvdtGetTransChTabByLcid(lcid);
923     if (transTable == NULL) {
924         /* Trace no resources */
925         LOG_ERROR("[AVDT]%{public}s: AvdtGetTransChTabByLcid(0x%x) Failed", __func__, lcid);
926         return;
927     }
928     switch (transTable->type) {
929         case AVDT_CH_TYPE_SIG: {
930             AvdtL2capDisconnectAbnormalSignle(transTable, reason);
931             break;
932         }
933         case AVDT_CH_TYPE_STREAM: {
934             AvdtL2capDisconnectAbnormalStream(transTable, reason);
935             break;
936         }
937         default:
938             break;
939     }
940     AvdtTransChDealloc(lcid);
941     return;
942 }
943 
AvdtL2capDisconnectAbnormalSignle(const AvdtTransChannel * transTable,uint8_t reason)944 void AvdtL2capDisconnectAbnormalSignle(const AvdtTransChannel *transTable, uint8_t reason)
945 {
946     AvdtSigCtrl *sigCtrl = AvdtGetSigCtrlByHandle(transTable->sigHandle);
947     if (sigCtrl == NULL) {
948         LOG_ERROR("[AVCT] %{public}s:AvdtGetSigCtrlByHandle(%hu) failed ", __func__, transTable->sigHandle);
949         return;
950     }
951 
952     if (reason == L2CAP_STATE_COLLISION) {
953         LOG_WARN("[AVCT] %{public}s:Connect Req failed! reason:L2CAP_STATE_COLLISION ", __func__);
954         /* Connect Req failed, Need connect retry */
955         sigCtrl->state = AVDT_SIG_IDLE_ST;
956         AvdtSigProcEvent(sigCtrl, AVDT_CONNECT_CMD_REQ_EVENT, NULL);
957         return;
958     }
959 
960     AvdtTransChannel *mediaTransTable = AvdtGetTransChTabByHandle(AVDT_CH_TYPE_STREAM, transTable->streamHandle);
961     if (mediaTransTable != NULL) {
962         LOG_INFO("[AVDT]%{public}s:Delete Media lcid(0x%x)", __func__, mediaTransTable->lcid);
963         AvdtStreamCtrl *streamCtrl = AvdtGetStreamCtrlByHandle(transTable->streamHandle);
964         if (streamCtrl != NULL) {
965             AvdtStreamProcEvent(streamCtrl, AVDT_STREAM_CLOSE_CMD_REQ_EVENT, NULL);
966         }
967     }
968 
969     if (sigCtrl->state == AVDT_SIG_CLOSING_ST) {
970         AvdtSigProcEvent(sigCtrl, AVDT_DISCONNECT_CMD_CFM_EVENT, NULL);
971     } else {
972         AvdtSigProcEvent(sigCtrl, AVDT_DISCONNECT_CMD_IND_EVENT, NULL);
973     }
974     return;
975 }
976 
AvdtL2capDisconnectAbnormalStream(const AvdtTransChannel * transTable,uint8_t reason)977 void AvdtL2capDisconnectAbnormalStream(const AvdtTransChannel *transTable, uint8_t reason)
978 {
979     AvdtStreamCtrl *streamCtrl = AvdtGetStreamCtrlByHandle(transTable->streamHandle);
980     if (streamCtrl == NULL) {
981         LOG_ERROR("[AVCT] %{public}s:AvdtGetStreamCtrlByHandle(%hu) failed ", __func__, transTable->sigHandle);
982         return;
983     }
984 
985     if (reason == L2CAP_STATE_COLLISION) {
986         LOG_WARN("[AVCT] %{public}s:Connect Req failed! reason:L2CAP_STATE_COLLISION ", __func__);
987         /* Connect Req failed, Need connect retry */
988         streamCtrl->state = AVDT_OPENING_ST;
989         AvdtStreamProcEvent(streamCtrl, AVDT_STREAM_OPEN_CMD_REQ_EVENT, NULL);
990     } else {
991         if (streamCtrl->state == AVDT_CLOSING_ST) {
992             AvdtStreamProcEvent(streamCtrl, AVDT_STREAM_CLOSE_CMD_CFM_EVENT, NULL);
993         } else {
994             AvdtStreamProcEvent(streamCtrl, AVDT_STREAM_CLOSE_CMD_IND_EVENT, NULL);
995         }
996     }
997     return;
998 }
AVDT_L2capRemoteBusyCallback(uint16_t lcid,uint8_t isBusy,void * ctx)999 void AVDT_L2capRemoteBusyCallback(uint16_t lcid, uint8_t isBusy, void *ctx)
1000 {
1001     LOG_INFO("[AVDT]%{public}s:lcid(0x%x),isBusy(%hhu)", __func__, lcid, isBusy);
1002     return;
1003 }
1004