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 #include "avctp_ctrl_l2cap.h"
16 #include "avctp_ctrl.h"
17 #include "avctp_ctrl_act.h"
18 #include "avctp_dev.h"
19 #include "avctp_gap.h"
20 #include "avctp_st.h"
21 #include "log.h"
22 #include "securec.h"
23 
24 /*************************************************************************************************
25  *  Functions Declare
26  *************************************************************************************************/
27 
28 /*****************************************************************************
29  * Globle Data  Define
30  ****************************************************************************/
31 /* L2CAP callback function structure */
32 const L2capService G_AVCT_L2C_SVR = {
33     AvctRecvConnectionReqCallback,
34     AvctRecvConnectionRspCallback,
35     AvctRecvConfigReqCallback,
36     AvctRecvConfigRspCallback,
37     AvctRecvDisconnectionReqCallback,
38     AvctRecvDisconnectionRspCallback,
39     AvctDisconnectAbnormalCallback,
40     AvctRecvDataCallback,
41     AvctRemoteBusyCallback
42     };
43 
44 /*****************************************************************************
45  * Function
46  ****************************************************************************/
47 /*
48  * Function     AvctRecvConnectionReqCallback
49  * Description  This function is called back when reveive connect req from peer. Only one
50  *              channel connection per PSM is used for this purpose between peer devices. Between two
51  *              devices, multiple AVCTP connections may exist. There shall be only one AVCTP
52  *              connection per PSM per ACL.
53  * Param[in]    aclHandle acl handle
54  * Param[in]    lcid   The link channel id.
55  * Param[in]    id
56  * Param[in]    lpsm
57  * Return       void
58  */
AvctRecvConnectionReqCallback(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t lpsm,void * ctx)59 void AvctRecvConnectionReqCallback(uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *ctx)
60 {
61     LOG_INFO("[AVCT] %{public}s:lcid(0x%x),lpsm(0x%x)", __func__, lcid, lpsm);
62     AvctRecvConnectionReqCallbackTskParam *param = malloc(sizeof(AvctRecvConnectionReqCallbackTskParam));
63     if (param == NULL) {
64         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
65         return;
66     }
67     (void)memset_s(
68         param, sizeof(AvctRecvConnectionReqCallbackTskParam), 0, sizeof(AvctRecvConnectionReqCallbackTskParam));
69     param->lcid = lcid;
70     param->id = id;
71     (void)memcpy_s(&param->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
72     param->lpsm = lpsm;
73     param->ctx = ctx;
74     if (AvctAsyncProcess(AvctRecvConnectionReqCallbackTsk, param)) {
75         free(param);
76     }
77     return;
78 }
79 
AvctRecvConnectionReqCallbackTsk(void * context)80 void AvctRecvConnectionReqCallbackTsk(void *context)
81 {
82     AvctRecvConnectionReqCallbackTskParam *param = (AvctRecvConnectionReqCallbackTskParam *)context;
83     AvctRecvConnectionReqCBack(param->lcid, param->id, &param->info, param->lpsm, param->ctx);
84     free(param);
85     return;
86 }
87 
AvctRecvConnectionReqCBack(uint16_t lcid,uint8_t id,const L2capConnectionInfo * info,uint16_t lpsm,void * ctx)88 void AvctRecvConnectionReqCBack(uint16_t lcid, uint8_t id, const L2capConnectionInfo *info, uint16_t lpsm, void *ctx)
89 {
90     if (lpsm == AVCT_PSM) {
91         AvctRequestSecurityBy(info->handle, info->addr, lcid, id, lpsm);
92     } else {
93         L2CIF_ConnectRsp(lcid, id, L2CAP_PSM_NOT_SUPPORTED, 0, NULL);
94     }
95     return;
96 }
97 
98 /*
99  * Function     AvctRecvConnectionReqAct
100  * Description  Receive Connection Request action func
101  * Param[in]    addr    address.
102  * Param[in]    aclHandle   acl handle.
103  * Param[in]    lcid    link channel id
104  * Param[in]    id      id
105  * Param[in]    psm     psm
106  * Return       void
107  */
AvctRecvConnectionReqAct(const BtAddr * addr,uint16_t aclHandle,uint16_t lcid,uint8_t id,uint16_t psm)108 void AvctRecvConnectionReqAct(const BtAddr *addr, uint16_t aclHandle, uint16_t lcid, uint8_t id, uint16_t psm)
109 {
110     LOG_INFO("[AVCT] %{public}s: lcid(0x%x) psm(0x%x)", __func__, lcid, psm);
111     AvctCbCh *cbCtrl = NULL;
112     uint16_t result = L2CAP_CONNECTION_SUCCESSFUL;
113     if (psm != AVCT_PSM) {
114         LOG_ERROR("[AVCT]The Psm is not Avct");
115         result = L2CAP_PSM_NOT_SUPPORTED;
116         /* send L2CAP connection response  */
117         L2CIF_ConnectRsp(lcid, id, result, 0, NULL);
118         return;
119     }
120     /* check the devcie connection is exist */
121     AvctCbDev *cbDev = AvctGetCbDevByAddress(addr);
122     if (cbDev == NULL) {
123         /* alloc ctrl resource */
124         cbDev = AvctCbDevAlloc(addr);
125         if (cbDev == NULL) {
126             result = L2CAP_NO_RESOURCES_AVAILABLE;
127         } else {
128             cbCtrl = AvctCbChAlloc();
129             if (cbCtrl == NULL) {
130                 result = L2CAP_NO_RESOURCES_AVAILABLE;
131             }
132         }
133     } else {
134         /* the connect is exist,return failed */
135         result = L2CAP_SOURCE_CID_ALREADY_ALLOCATED;
136     }
137     /* send L2CAP connection response  */
138     L2CIF_ConnectRsp(lcid, id, result, 0, NULL);
139     /* if connect success,send config requeset */
140     if (result == L2CAP_CONNECTION_SUCCESSFUL) {
141         cbCtrl->chId = lcid;
142         cbCtrl->chState = AVCT_CH_CFG;
143         cbDev->cbCtrl = cbCtrl;
144         cbDev->chLink |= AVCT_ALLOC_CTRL;
145         L2capConfigInfo cfg = {0};
146         cfg.mtu = g_avctMng.rxMtu;
147         cfg.flushTimeout = 0xFFFF;
148         if (L2CIF_ConfigReq(lcid, &cfg, NULL)) {
149             LOG_ERROR("[AVCT] %{public}s:L2CIF_ConfigReq failed.", __func__);
150         }
151     }
152     return;
153 }
154 
155 /*
156  * Function     AvctRecvConnectionRspCallback
157  * Description  This function is called back when reveived connection response. from peer.
158  * Param[in]    lcid The link channel id.
159  * Param[in]    result  the connection request result
160  * Param[in]    status
161  * Return       void
162  */
AvctRecvConnectionRspCallback(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * ctx)163 void AvctRecvConnectionRspCallback(
164     uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *ctx)
165 {
166     LOG_INFO("[AVCT] %{public}s: lcid(0x%x), result(%{public}d)", __func__, lcid, result);
167     AvctRecvConnectionRspCallbackTskParam *param = malloc(sizeof(AvctRecvConnectionRspCallbackTskParam));
168     if (param == NULL) {
169         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
170         return;
171     }
172     (void)memset_s(
173         param, sizeof(AvctRecvConnectionRspCallbackTskParam), 0, sizeof(AvctRecvConnectionRspCallbackTskParam));
174     param->lcid = lcid;
175     (void)memcpy_s(&param->info, sizeof(L2capConnectionInfo), info, sizeof(L2capConnectionInfo));
176     param->result = result;
177     param->status = status;
178     param->ctx = ctx;
179     if (AvctAsyncProcess(AvctRecvConnectionRspCallbackTsk, param)) {
180         free(param);
181     }
182     return;
183 }
184 
AvctRecvConnectionRspCallbackTsk(void * context)185 void AvctRecvConnectionRspCallbackTsk(void *context)
186 {
187     AvctRecvConnectionRspCallbackTskParam *param = (AvctRecvConnectionRspCallbackTskParam *)context;
188     AvctRecvConnectionRspCBack(param->lcid, &param->info, param->result, param->status, param->ctx);
189     free(param);
190     return;
191 }
192 
AvctRecvConnectionRspCBack(uint16_t lcid,const L2capConnectionInfo * info,uint16_t result,uint16_t status,void * ctx)193 void AvctRecvConnectionRspCBack(
194     uint16_t lcid, const L2capConnectionInfo *info, uint16_t result, uint16_t status, void *ctx)
195 {
196     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
197     if (cbDev == NULL) {
198         LOG_ERROR("[AVCT] %{public}s:AvctGetCbDevByChId(0x%x) failed.", __func__, lcid);
199         return;
200     }
201     if (cbDev->cbCtrl->stState == AVCT_CH_CONN) {
202         if (result == L2CAP_CONNECTION_PENDING) {
203             LOG_INFO("[AVCT] %{public}s: Connect RSP result is pending, do nothing!", __func__);
204             return;
205         }
206         if (result == L2CAP_CONNECTION_SUCCESSFUL) {
207             cbDev->cbCtrl->chState = AVCT_CH_CFG;
208             /* connect success ,send config request */
209             L2capConfigInfo cfg = {0};
210             cfg.mtu = g_avctMng.rxMtu;
211             cfg.flushTimeout = 0xFFFF;
212             if (L2CIF_ConfigReq(lcid, &cfg, NULL)) {
213                 LOG_ERROR("[AVCT] %{public}s:L2CIF_ConfigReq failed.", __func__);
214             }
215         } else {
216             /* connect failed,send event to up app */
217             AvctEvtData evtData;
218             evtData.result = result;
219             AvctCbCtrlEvt(cbDev, AVCT_REV_DISCONN_EVT, &evtData);
220         }
221     }
222     return;
223 }
224 
225 /*
226  * Function     AvctRecvConfigReqCallback
227  * Description  This function is called back when reveived config request from peer.
228  * Param[in]    lcid The link channel id.
229  * Param[in]    id
230  * Param[in]    cfg the point of config
231  * Return       void
232  */
AvctRecvConfigReqCallback(uint16_t lcid,uint8_t id,const L2capConfigInfo * cfg,void * ctx)233 void AvctRecvConfigReqCallback(uint16_t lcid, uint8_t id, const L2capConfigInfo *cfg, void *ctx)
234 {
235     LOG_INFO("[AVCT] %{public}s: lcid(0x%x), mtu(%x)", __func__, lcid, cfg->mtu);
236     AvctRecvConfigReqCallbackTskParam *param = malloc(sizeof(AvctRecvConfigReqCallbackTskParam));
237     if (param == NULL) {
238         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
239         return;
240     }
241     (void)memset_s(param, sizeof(AvctRecvConfigReqCallbackTskParam), 0, sizeof(AvctRecvConfigReqCallbackTskParam));
242     param->lcid = lcid;
243     param->id = id;
244     (void)memcpy_s(&param->cfg, sizeof(L2capConfigInfo), cfg, sizeof(L2capConfigInfo));
245     param->ctx = ctx;
246     if (AvctAsyncProcess(AvctRecvConfigReqCallbackTsk, param)) {
247         free(param);
248     }
249     return;
250 }
251 
AvctRecvConfigReqCallbackTsk(void * context)252 void AvctRecvConfigReqCallbackTsk(void *context)
253 {
254     AvctRecvConfigReqCallbackTskParam *param = (AvctRecvConfigReqCallbackTskParam *)context;
255     AvctRecvConfigReqCBack(param->lcid, param->id, &param->cfg, param->ctx);
256     free(param);
257     return;
258 }
259 
AvctRecvConfigReqCBack(uint16_t lcid,uint8_t id,const L2capConfigInfo * cfg,void * ctx)260 void AvctRecvConfigReqCBack(uint16_t lcid, uint8_t id, const L2capConfigInfo *cfg, void *ctx)
261 {
262     uint16_t result = L2CAP_SUCCESS;
263     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
264     if (cbDev == NULL) {
265         LOG_ERROR("[AVCT] %{public}s: Config REJECTED! By can't fine device by lcid(0x%x)", __func__, lcid);
266         L2CIF_ConfigRsp(lcid, id, cfg, L2CAP_REJECTED, NULL);
267         return;
268     }
269     if (cfg->rfc.mode == L2CAP_BASIC_MODE) {
270         /* send L2CAP configure response */
271         if (L2CIF_ConfigRsp(lcid, id, cfg, result, NULL)) {
272             LOG_ERROR("[AVCT] %{public}s:L2CIF_ConfigRsp failed.", __func__);
273         }
274         cbDev->cbCtrl->peerMtu = cfg->mtu;
275         cbDev->cbCtrl->chCfgSt |= AVCT_L2C_CFG_REQ;
276         /* There are two step of config process */
277         if (cbDev->cbCtrl->chCfgSt & AVCT_L2C_CFG_RSP) {
278             /* config req/rsp reveiced */
279             if (cbDev->cbCtrl->chResult == L2CAP_SUCCESS) {
280                 cbDev->cbCtrl->chState = AVCT_CH_OPENED;
281                 AvctEvtData evtData;
282                 evtData.result = AVCT_SUCCESS;
283                 AvctCbCtrlEvt(cbDev, AVCT_REV_CONN_EVT, &evtData);
284             }
285         }
286     } else {
287         LOG_WARN("[AVCT] %{public}s: Config UNACCEPT! By mode is not basemode", __func__);
288         L2capConfigInfo rspCfg = {0};
289         rspCfg.mtu = cfg->mtu;
290         rspCfg.flushTimeout = 0xFFFF;
291         rspCfg.fcs = 0x01;
292         rspCfg.rfc.mode = L2CAP_BASIC_MODE;
293         L2CIF_ConfigRsp(lcid, id, &rspCfg, L2CAP_UNACCEPTABLE_PARAMETERS, NULL);
294     }
295     return;
296 }
297 
298 /*
299  * Function     AvctRecvConfigRspCallback
300  * Description  This function is called back when reveived config response from peer.
301  * Param[in]    *addr   The address of the peer device.
302  * Param[in]    lcid    The link channel id.
303  * Param[in]    cfg   The point of config info
304  * Param[in]    result  the result of config request.
305  * Return       void
306  */
AvctRecvConfigRspCallback(uint16_t lcid,const L2capConfigInfo * cfg,uint16_t result,void * ctx)307 void AvctRecvConfigRspCallback(uint16_t lcid, const L2capConfigInfo *cfg, uint16_t result, void *ctx)
308 {
309     LOG_INFO("[AVCT] %{public}s: lcid(0x%x),result(%hu)", __func__, lcid, result);
310     AvctRecvConfigRspCallbackTskParam *param = malloc(sizeof(AvctRecvConfigRspCallbackTskParam));
311     if (param == NULL) {
312         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
313         return;
314     }
315     (void)memset_s(param, sizeof(AvctRecvConfigRspCallbackTskParam), 0, sizeof(AvctRecvConfigRspCallbackTskParam));
316     param->lcid = lcid;
317     (void)memcpy_s(&param->cfg, sizeof(L2capConfigInfo), cfg, sizeof(L2capConfigInfo));
318     param->result = result;
319     param->ctx = ctx;
320     if (AvctAsyncProcess(AvctRecvConfigRspCallbackTsk, param)) {
321         free(param);
322     }
323     return;
324 }
325 
AvctRecvConfigRspCallbackTsk(void * context)326 void AvctRecvConfigRspCallbackTsk(void *context)
327 {
328     AvctRecvConfigRspCallbackTskParam *param = (AvctRecvConfigRspCallbackTskParam *)context;
329     AvctRecvConfigRspCBack(param->lcid, &param->cfg, param->result, param->ctx);
330     free(param);
331     return;
332 }
333 
AvctRecvConfigRspCBack(uint16_t lcid,const L2capConfigInfo * cfg,uint16_t result,void * ctx)334 void AvctRecvConfigRspCBack(uint16_t lcid, const L2capConfigInfo *cfg, uint16_t result, void *ctx)
335 {
336     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
337     if (cbDev == NULL) {
338         LOG_ERROR("[AVCT] %{public}s:AvctGetCbDevByChId(0x%x) failed.", __func__, lcid);
339         return;
340     }
341     if (cbDev->cbCtrl->chState == AVCT_CH_CFG) {
342         if (result == L2CAP_PENDING) {
343             LOG_INFO("[AVCT] %{public}s: Config rsp result is pending, do nothing", __func__);
344             return;
345         }
346         if (result == L2CAP_SUCCESS) {
347             cbDev->cbCtrl->chCfgSt |= AVCT_L2C_CFG_RSP;
348             if (cbDev->cbCtrl->chCfgSt & AVCT_L2C_CFG_REQ) {
349                 /* config req/rsp reveiced */
350                 cbDev->cbCtrl->chState = AVCT_CH_OPENED;
351                 AvctEvtData evtData;
352                 evtData.result = AVCT_SUCCESS;
353                 AvctCbCtrlEvt(cbDev, AVCT_REV_CONN_EVT, &evtData);
354             }
355         } else {
356             /* result is Failed ,send disconnect req */
357             cbDev->cbCtrl->chResult = result;
358             L2CIF_DisconnectionReq(lcid, NULL);
359         }
360     }
361     return;
362 }
363 
364 /*
365  * Function     AvctRecvDisconnectionReqCallback
366  * Description  This function is called back when reveived disconnection request from peer.
367  * Param[in]    lcid    The link channel id.
368  * Param[in]    id
369  * Return       void
370  */
AvctRecvDisconnectionReqCallback(uint16_t lcid,uint8_t id,void * ctx)371 void AvctRecvDisconnectionReqCallback(uint16_t lcid, uint8_t id, void *ctx)
372 {
373     LOG_INFO("[AVCT] %{public}s: lcid(0x%x)", __func__, lcid);
374     AvctRecvDisconnectionReqCallbackTskParam *param = malloc(sizeof(AvctRecvDisconnectionReqCallbackTskParam));
375     if (param == NULL) {
376         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
377         return;
378     }
379     (void)memset_s(
380         param, sizeof(AvctRecvDisconnectionReqCallbackTskParam), 0, sizeof(AvctRecvDisconnectionReqCallbackTskParam));
381     param->lcid = lcid;
382     param->id = id;
383     param->ctx = ctx;
384     if (AvctAsyncProcess(AvctRecvDisconnectionReqCallbackTsk, param)) {
385         free(param);
386     }
387     return;
388 }
389 
AvctRecvDisconnectionReqCallbackTsk(void * context)390 void AvctRecvDisconnectionReqCallbackTsk(void *context)
391 {
392     AvctRecvDisconnectionReqCallbackTskParam *param = (AvctRecvDisconnectionReqCallbackTskParam *)context;
393     AvctRecvDisconnectionReqCBack(param->lcid, param->id, param->ctx);
394     free(param);
395     return;
396 }
397 
AvctRecvDisconnectionReqCBack(uint16_t lcid,uint8_t id,void * ctx)398 void AvctRecvDisconnectionReqCBack(uint16_t lcid, uint8_t id, void *ctx)
399 {
400     /* Send disconnect rep */
401     L2CIF_DisconnectionRsp(lcid, id, NULL);
402     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
403     if (cbDev != NULL) {
404         /* Send Close Event */
405         AvctEvtData evtData;
406         evtData.result = AVCT_SUCCESS;
407         AvctCbCtrlEvt(cbDev, AVCT_REV_DISCONN_EVT, &evtData);
408     }
409     return;
410 }
411 
412 /*
413  * Function     AvctRecvDisconnectionRspCallback
414  * Description  This function is called back when reveived disconnection response from peer.
415  * Param[in]    lcid    The link channel id.
416  * Return       void
417  */
AvctRecvDisconnectionRspCallback(uint16_t lcid,void * ctx)418 void AvctRecvDisconnectionRspCallback(uint16_t lcid, void *ctx)
419 {
420     LOG_INFO("[AVCT] %{public}s:lcid(0x%x)", __func__, lcid);
421     AvctRecvDisconnectionRspCallbackTskParam *param = malloc(sizeof(AvctRecvDisconnectionRspCallbackTskParam));
422     if (param == NULL) {
423         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
424         return;
425     }
426     (void)memset_s(
427         param, sizeof(AvctRecvDisconnectionRspCallbackTskParam), 0, sizeof(AvctRecvDisconnectionRspCallbackTskParam));
428     param->lcid = lcid;
429     param->ctx = ctx;
430     if (AvctAsyncProcess(AvctRecvDisconnectionRspCallbackTsk, param)) {
431         free(param);
432     }
433     return;
434 }
435 
AvctRecvDisconnectionRspCallbackTsk(void * context)436 void AvctRecvDisconnectionRspCallbackTsk(void *context)
437 {
438     AvctRecvDisconnectionRspCallbackTskParam *param = (AvctRecvDisconnectionRspCallbackTskParam *)context;
439     AvctRecvDisconnectionRspCBack(param->lcid, param->ctx);
440     free(param);
441     return;
442 }
443 
AvctRecvDisconnectionRspCBack(uint16_t lcid,void * ctx)444 void AvctRecvDisconnectionRspCBack(uint16_t lcid, void *ctx)
445 {
446     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
447     if (cbDev != NULL) {
448         /* Send Close Event */
449         AvctEvtData evtData;
450         evtData.result = cbDev->cbCtrl->chResult;
451         cbDev->cbCtrl->chResult = 0;
452         AvctCbCtrlEvt(cbDev, AVCT_REV_DISCONN_EVT, &evtData);
453     }
454     return;
455 }
456 
457 /*
458  * Function     AvctDisconnectAbnormalCallback
459  * Description  This function is called back when Disconnected abnormal, such as acl disconnected or link loss response
460  *              from peer.
461  * Param[in]    lcid    The link channel id.
462  * Param[in]    reason  abnormal reason
463  * Return       void
464  */
AvctDisconnectAbnormalCallback(uint16_t lcid,uint8_t reason,void * ctx)465 void AvctDisconnectAbnormalCallback(uint16_t lcid, uint8_t reason, void *ctx)
466 {
467     LOG_INFO("[AVCT] %{public}s: lcid(0x%x) reason(%hhu)", __func__, lcid, reason);
468     AvctDisconnectAbnormalCallbackTskParam *param = malloc(sizeof(AvctDisconnectAbnormalCallbackTskParam));
469     if (param == NULL) {
470         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
471         return;
472     }
473     (void)memset_s(
474         param, sizeof(AvctDisconnectAbnormalCallbackTskParam), 0, sizeof(AvctDisconnectAbnormalCallbackTskParam));
475     param->lcid = lcid;
476     param->reason = reason;
477     param->ctx = ctx;
478     if (AvctAsyncProcess(AvctDisconnectAbnormalCallbackTsk, param)) {
479         free(param);
480     }
481     return;
482 }
483 
AvctDisconnectAbnormalCallbackTsk(void * context)484 void AvctDisconnectAbnormalCallbackTsk(void *context)
485 {
486     AvctDisconnectAbnormalCallbackTskParam *param = (AvctDisconnectAbnormalCallbackTskParam *)context;
487     AvctDisconnectAbnormalCBack(param->lcid, param->reason, param->ctx);
488     free(param);
489     return;
490 }
491 
AvctDisconnectAbnormalCBack(uint16_t lcid,uint8_t reason,void * ctx)492 void AvctDisconnectAbnormalCBack(uint16_t lcid, uint8_t reason, void *ctx)
493 {
494     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
495     if (cbDev != NULL) {
496         if (reason == L2CAP_STATE_COLLISION) {
497             LOG_WARN("[AVCT] %{public}s:Connect Req failed! reason:L2CAP_STATE_COLLISION ", __func__);
498             /* Connect Req failed, Need connect retry */
499             cbDev->cbCtrl->chCfgSt = 0;
500             cbDev->cbCtrl->chState = AVCT_CH_IDLE;
501             cbDev->cbCtrl->stState = AVCT_IDLE_ST;
502             AvctCbCtrlEvt(cbDev, AVCT_BIND_EVT, NULL);
503         } else {
504             AvctEvtData evtData;
505             evtData.result = AVCT_FAILED;
506             AvctCbCtrlEvt(cbDev, AVCT_REV_DISCONN_EVT, &evtData);
507         }
508     }
509     return;
510 }
511 
512 /*
513  * Function     AvctRecvDataCallback
514  * Description  This function is called back when receive message from peer.
515  * Param[in]    lcid    The link channel id.
516  * Param[in]    *pkt  message data
517  * Return       void
518  */
AvctRecvDataCallback(uint16_t lcid,Packet * pkt,void * ctx)519 void AvctRecvDataCallback(uint16_t lcid, Packet *pkt, void *ctx)
520 {
521     LOG_INFO("[AVCT] %{public}s:lcid(0x%x),PacketSize(%u)", __func__, lcid, PacketSize(pkt));
522     AvctRecvDataCallbackTskParam *param = malloc(sizeof(AvctRecvDataCallbackTskParam));
523     if (param == NULL) {
524         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
525         return;
526     }
527     (void)memset_s(param, sizeof(AvctRecvDataCallbackTskParam), 0, sizeof(AvctRecvDataCallbackTskParam));
528     param->lcid = lcid;
529     param->pkt = PacketRefMalloc(pkt);
530     param->ctx = ctx;
531     if (AvctAsyncProcess(AvctRecvDataCallbackTsk, param)) {
532         PacketFree(param->pkt);
533         free(param);
534     }
535     return;
536 }
537 
AvctRecvDataCallbackTsk(void * context)538 void AvctRecvDataCallbackTsk(void *context)
539 {
540     AvctRecvDataCallbackTskParam *param = (AvctRecvDataCallbackTskParam *)context;
541     AvctRecvDataCBack(param->lcid, param->pkt, param->ctx);
542     PacketFree(param->pkt);
543     free(param);
544     return;
545 }
546 
AvctRecvDataCBack(uint16_t lcid,Packet * pkt,void * ctx)547 void AvctRecvDataCBack(uint16_t lcid, Packet *pkt, void *ctx)
548 {
549     AvctPktDataPrint(pkt);
550     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
551     if (cbDev != NULL) {
552         AvctEvtData evtData;
553         evtData.buf = pkt;
554         AvctCbCtrlEvt(cbDev, AVCT_REV_MSG_EVT, &evtData);
555     } else {
556         LOG_WARN("[AVCT] %{public}s:Can't find device by lcid(0x%x)", __func__, lcid);
557     }
558     return;
559 }
560 
561 /*
562  * Function     AvctRemoteBusyCallback
563  * Description  This function is called back when remote peer is busy in Enhanced mode.
564  * Param[in]    lcid    The link channel id.
565  * Param[in]    isBusy  busy/unbusy
566  * Return       void
567  */
AvctRemoteBusyCallback(uint16_t lcid,uint8_t isBusy,void * ctx)568 void AvctRemoteBusyCallback(uint16_t lcid, uint8_t isBusy, void *ctx)
569 {
570     LOG_INFO("[AVCT] %{public}s:lcid(0x%x),isBusy(%hhu)", __func__, lcid, isBusy);
571     AvctRemoteBusyCallbackTskParam *param = malloc(sizeof(AvctRemoteBusyCallbackTskParam));
572     if (param == NULL) {
573         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
574         return;
575     }
576     (void)memset_s(param, sizeof(AvctRemoteBusyCallbackTskParam), 0, sizeof(AvctRemoteBusyCallbackTskParam));
577     param->lcid = lcid;
578     param->isBusy = isBusy;
579     param->ctx = ctx;
580     if (AvctAsyncProcess(AvctRemoteBusyCallbackTsk, param)) {
581         free(param);
582     }
583     return;
584 }
585 
AvctRemoteBusyCallbackTsk(void * context)586 void AvctRemoteBusyCallbackTsk(void *context)
587 {
588     AvctRemoteBusyCallbackTskParam *param = (AvctRemoteBusyCallbackTskParam *)context;
589     AvctRemoteBusyCBack(param->lcid, param->isBusy, param->ctx);
590     free(param);
591     return;
592 }
593 
AvctRemoteBusyCBack(uint16_t lcid,uint8_t isBusy,void * ctx)594 void AvctRemoteBusyCBack(uint16_t lcid, uint8_t isBusy, void *ctx)
595 {
596     AvctCbDev *cbDev = AvctGetCbDevByChId(lcid);
597     if (cbDev != NULL) {
598         AvctEvtData evtData;
599         if (isBusy) {
600             cbDev->cbCtrl->chState = AVCT_CH_BUSY;
601             evtData.result = AVCT_BUSY_ST;
602             AvctCbCtrlEvt(cbDev, AVCT_REV_BUSY_EVT, &evtData);
603         } else {
604             if (cbDev->cbCtrl->chState == AVCT_CH_BUSY) {
605                 cbDev->cbCtrl->chState = AVCT_CH_OPENED;
606                 evtData.result = AVCT_OPENED_ST;
607                 AvctCbCtrlEvt(cbDev, AVCT_REV_BUSY_EVT, &evtData);
608             }
609         }
610     }
611     return;
612 }
613 
614 /*
615  * Function     AvctCtrlL2CIFConnectReqCallback
616  * Description  L2cap connect request check callback func.
617  * Param[in]    result Check result.
618  * Param[in]    lcid   lcid.
619  * Param[out]   addr   peer address
620  * Return       void
621  */
AvctCtrlL2CIFConnectReqCallback(const BtAddr * addr,uint16_t lcid,int result,void * context)622 void AvctCtrlL2CIFConnectReqCallback(const BtAddr *addr, uint16_t lcid, int result, void *context)
623 {
624     LOG_INFO("[AVCT] %{public}s: lcid(0x%x), result(%{public}d)", __func__, lcid, result);
625     AvctCtrlL2CIFConnectReqCallbackTskParam *param = malloc(sizeof(AvctCtrlL2CIFConnectReqCallbackTskParam));
626     if (param == NULL) {
627         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
628         return;
629     }
630     (void)memset_s(
631         param, sizeof(AvctCtrlL2CIFConnectReqCallbackTskParam), 0, sizeof(AvctCtrlL2CIFConnectReqCallbackTskParam));
632     (void)memcpy_s(&param->addr, sizeof(BtAddr), addr, sizeof(BtAddr));
633     param->lcid = lcid;
634     param->result = result;
635     param->context = context;
636     if (AvctAsyncProcess(AvctCtrlL2CIFConnectReqCallbackTsk, param)) {
637         free(param);
638     }
639     return;
640 }
641 
AvctCtrlL2CIFConnectReqCallbackTsk(void * context)642 void AvctCtrlL2CIFConnectReqCallbackTsk(void *context)
643 {
644     AvctCtrlL2CIFConnectReqCallbackTskParam *param = (AvctCtrlL2CIFConnectReqCallbackTskParam *)context;
645     AvctCtrlConnectResult(&param->addr, param->lcid, param->result, param->context);
646     free(param);
647     return;
648 }
649 
AvctCtrlConnectResult(const BtAddr * addr,uint16_t lcid,int result,void * context)650 void AvctCtrlConnectResult(const BtAddr *addr, uint16_t lcid, int result, void *context)
651 {
652     AvctCbDev *cbDev = AvctGetCbDevByAddress(addr);
653     if ((cbDev != NULL) && (cbDev->cbCtrl != NULL)) {
654         cbDev->cbCtrl->chId = lcid;
655         if (lcid == 0) {
656             /* connect req failed, send close event */
657             AvctEvtData evtData;
658             evtData.result = AVCT_FAILED;
659             AvctCbCtrlEvt(cbDev, AVCT_REV_DISCONN_EVT, &evtData);
660         }
661     } else {
662         LOG_WARN("[AVCT]%{public}s:Can't find control block by bdAddr((%02x:%02x:%02x:%02x:%02x:%02x)",
663             __func__,
664             BT_ADDR_FMT_DSC(addr->addr));
665     }
666     return;
667 }