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(¶m->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, ¶m->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(¶m->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, ¶m->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(¶m->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, ¶m->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(¶m->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, ¶m->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(¶m->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(¶m->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 }