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