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_api.h"
16 #include "avctp_br.h"
17 #include "avctp_conn.h"
18 #include "avctp_ctrl.h"
19 #include "avctp_dev.h"
20 #include "avctp_st.h"
21 #include "btm/btm_thread.h"
22 #include "log.h"
23 #include "securec.h"
24
25 /*****************************************************************************
26 * Globle Data Define
27 ****************************************************************************/
28 /*
29 * Function: AVCT_Register
30 * Description: This is the system level registration function for the AVCTP
31 * protocol. This function initializes AVCTP protocal and prepares
32 * the protocol stack for its use. This function must be called
33 * once by the system before the other functions of the API can be
34 * used.
35 * param[in] mtu max transcation unit for control
36 * param[in] mtuBr max transcation unit for browser
37 * param[in] role CT/TG
38 * Return: void
39 */
AVCT_Register(uint16_t mtu,uint16_t mtuBr,uint16_t role)40 void AVCT_Register(uint16_t mtu, uint16_t mtuBr, uint16_t role)
41 {
42 LOG_INFO("[AVCT] %{public}s: Regist mut(%hu) mtuBr(%hu) role(%hu)", __func__, mtu, mtuBr, role);
43 Event *event = EventCreate(true);
44 AvctRegisterTskParam *param = malloc(sizeof(AvctRegisterTskParam));
45 if (param == NULL) {
46 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
47 EventDelete(event);
48 return;
49 }
50 (void)memset_s(param, sizeof(AvctRegisterTskParam), 0, sizeof(AvctRegisterTskParam));
51 param->mtu = mtu;
52 param->mtuBr = mtuBr;
53 param->role = role;
54 param->event = event;
55 if (!AvctAsyncProcess(AvctRegisterTsk, param)) {
56 EventWait(event, WAIT_TIME);
57 }
58 free(param);
59 EventDelete(event);
60 return;
61 }
62
AvctRegisterTsk(void * context)63 void AvctRegisterTsk(void *context)
64 {
65 AvctRegisterTskParam *param = (AvctRegisterTskParam *)context;
66 AvctRegister(param->mtu, param->mtuBr, param->role);
67 EventSet(param->event);
68 return;
69 }
70
AvctRegister(uint16_t mtu,uint16_t mtuBr,uint16_t role)71 void AvctRegister(uint16_t mtu, uint16_t mtuBr, uint16_t role)
72 {
73 LOG_DEBUG("[AVCT] %{public}s: Regist mut(%hu) mtuBr(%hu) role(%hu)", __func__, mtu, mtuBr, role);
74 /* set receive MTU */
75 if (!g_avctMng.registered) {
76 g_avctMng.rxMtu = mtu;
77 g_avctMng.rxMtuBr = mtuBr;
78 g_avctMng.role = role;
79 g_avctMng.registered = true;
80 }
81 return;
82 }
83
84 /*
85 * Function AVCT_Deregister
86 * Description This function is called to deregister AVCTP protocol.
87 * It is called when AVCTP is no longer being used by any
88 * application in the system. All connections must be
89 * disconned in advance.
90 * Param[in] void
91 * Return void
92 */
AVCT_Deregister(void)93 void AVCT_Deregister(void)
94 {
95 LOG_INFO("[AVCT] %{public}s:", __func__);
96 Event *event = EventCreate(true);
97 AvctDeregisterTskParam *param = malloc(sizeof(AvctDeregisterTskParam));
98 if (param == NULL) {
99 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
100 EventDelete(event);
101 return;
102 }
103 (void)memset_s(param, sizeof(AvctDeregisterTskParam), 0, sizeof(AvctDeregisterTskParam));
104 param->event = event;
105 if (!AvctAsyncProcess(AvctDeregisterTsk, param)) {
106 EventWait(event, WAIT_TIME);
107 }
108 free(param);
109 EventDelete(event);
110 return;
111 }
112
AvctDeregisterTsk(void * context)113 void AvctDeregisterTsk(void *context)
114 {
115 AvctDeregisterTskParam *param = (AvctDeregisterTskParam *)context;
116 AvctDeregister();
117 EventSet(param->event);
118 return;
119 }
120
AvctDeregister(void)121 void AvctDeregister(void)
122 {
123 LOG_DEBUG("[AVCT] %{public}s:", __func__);
124 for (int i = 0; i < AVCT_MAX_CONNECTS; i++) {
125 if (g_avctMng.cbConn[i].status != AVCT_CONN_UNALLOC) {
126 AvctDisconnectReq(g_avctMng.cbConn[i].connId);
127 }
128 }
129 return;
130 }
131
132 /*
133 * Function AVCT_ConnectReq
134 * Description This function is called to create an avctp control connection
135 * for peer device.
136 * AVCT.ICS #Table 2/11 3/11 Connect Request
137 * AVCT.ICS #Table 3/9 Event register for connection request.
138 * AVCT Profile #11.2.1 #11.1
139 * Param[in] *connParam oint to the info of the connection request.
140 * Such as the Role、Profile ID、Callback func point.
141 * Param[in] peerAddr The peer address to be connected.
142 * Param[out] *connId Poit to the handle of the connected channel
143 * Return AVCT_SUCCESS if successful, otherwise error.
144 */
AVCT_ConnectReq(uint8_t * connId,const AvctConnectParam * connParam,const BtAddr * peerAddr)145 uint16_t AVCT_ConnectReq(uint8_t *connId, const AvctConnectParam *connParam, const BtAddr *peerAddr)
146 {
147 LOG_INFO("[AVCT] %{public}s: peerAddr is (%x:%x:%x:%x:%x:%x) role(%hhu)",
148 __func__,
149 BT_ADDR_FMT_ASC(peerAddr->addr),
150 connParam->role);
151 uint16_t ret = AVCT_FAILED;
152 Event *event = EventCreate(true);
153 AvctConnectReqTskParam *param = malloc(sizeof(AvctConnectReqTskParam));
154 if (param == NULL) {
155 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
156 EventDelete(event);
157 return ret;
158 }
159 (void)memset_s(param, sizeof(AvctConnectReqTskParam), 0, sizeof(AvctConnectReqTskParam));
160 param->event = event;
161 param->connId = *connId;
162 (void)memcpy_s(¶m->connParam, sizeof(AvctConnectParam), connParam, sizeof(AvctConnectParam));
163 (void)memcpy_s(¶m->peerAddr, sizeof(BtAddr), peerAddr, sizeof(BtAddr));
164 if (!AvctAsyncProcess(AvctConnectReqTsk, param)) {
165 EventWait(event, WAIT_TIME);
166 ret = param->ret;
167 }
168 free(param);
169 EventDelete(event);
170 return ret;
171 }
172
AvctConnectReqTsk(void * context)173 void AvctConnectReqTsk(void *context)
174 {
175 AvctConnectReqTskParam *param = (AvctConnectReqTskParam *)context;
176 param->ret = AvctConnectReq(¶m->connId, ¶m->connParam, ¶m->peerAddr);
177 EventSet(param->event);
178 return;
179 }
AvctConnectReq(uint8_t * connId,const AvctConnectParam * connParam,const BtAddr * peerAddr)180 uint16_t AvctConnectReq(uint8_t *connId, const AvctConnectParam *connParam, const BtAddr *peerAddr)
181 {
182 uint16_t ret = AVCT_SUCCESS;
183 if (connParam == NULL || peerAddr == NULL || connParam->chEvtCallback == NULL || connParam->msgCallback == NULL) {
184 ret = AVCT_ERR_PARAM;
185 return ret;
186 }
187 LOG_DEBUG("[AVCT] %{public}s: peerAddr is (%x:%x:%x:%x:%x:%x) role(%hhu)",
188 __func__,
189 BT_ADDR_FMT_ASC(peerAddr->addr),
190 connParam->role);
191 AvctCbConn *cbConn = AvctCbConnAlloc(connParam);
192 if (cbConn == NULL) {
193 LOG_ERROR("[AVCT]There is no connection resource for the connID(%hhu)!", *connId);
194 ret = AVCT_ERR_NO_RESOURCES;
195 return ret;
196 }
197 *connId = cbConn->connId;
198 if (cbConn->connParam.role == AVCT_INIT) {
199 ret = AvctConnectInitiate(cbConn, connParam, peerAddr);
200 }
201 return ret;
202 }
203
204 /*
205 * Function AVCT_DisconnectReq
206 * Description This function is called to disconnect the avctp control channel.
207 * AVCT.ICS #Table 2/12 3/12 Disconnect Request AVCT.ICS #Table
208 * 3/10 Event register for disconnection request. AVCT Profile
209 * #11.2.2 #11.2.3 #11.1
210 * Param[in] connId The id of the connection channel to be disconnected.
211 * Return AVCT_SUCCESS if successful, otherwise error.
212 */
AVCT_DisconnectReq(uint8_t connId)213 uint16_t AVCT_DisconnectReq(uint8_t connId)
214 {
215 LOG_INFO("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
216 uint16_t ret = AVCT_FAILED;
217 Event *event = EventCreate(true);
218 AvctDisconnectReqTskParam *param = malloc(sizeof(AvctDisconnectReqTskParam));
219 if (param == NULL) {
220 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
221 EventDelete(event);
222 return ret;
223 }
224 (void)memset_s(param, sizeof(AvctDisconnectReqTskParam), 0, sizeof(AvctDisconnectReqTskParam));
225 param->event = event;
226 param->connId = connId;
227 if (!AvctAsyncProcess(AvctDisconnectReqTsk, param)) {
228 EventWait(event, WAIT_TIME);
229 ret = param->ret;
230 }
231 free(param);
232 EventDelete(event);
233 return ret;
234 }
235
AvctDisconnectReqTsk(void * context)236 void AvctDisconnectReqTsk(void *context)
237 {
238 AvctDisconnectReqTskParam *param = (AvctDisconnectReqTskParam *)context;
239 param->ret = AvctDisconnectReq(param->connId);
240 EventSet(param->event);
241 return;
242 }
243
AvctDisconnectReq(uint8_t connId)244 uint16_t AvctDisconnectReq(uint8_t connId)
245 {
246 LOG_DEBUG("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
247 uint16_t ret = AvctDisconnect(connId, AVCT_CH_CTRL);
248 return ret;
249 }
250
251 /*
252 * Function AVCT_SendMsgReq
253 *
254 * Description This function is called to send an message to the channel.
255 * AVCT.ICS #Table 2/13 3/13 Send Message
256 * AVCT.ICS #Table 3/10 Event register for message reception.
257 * AVCT Profile #11.2.3 #11.2.4 #11.1
258 * Pram[in] connId The id of the connection channel which is the message to
259 * be send.
260 * Param[in] label Message label from application
261 * Param[in] cr command/response
262 * Param[in] msg Message data point
263 * Return AVCT_SUCCESS if successful, otherwise error.
264 */
AVCT_SendMsgReq(uint8_t connId,uint8_t label,uint8_t cr,const Packet * msg)265 uint16_t AVCT_SendMsgReq(uint8_t connId, uint8_t label, uint8_t cr, const Packet *msg)
266 {
267 LOG_INFO("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
268 uint16_t ret = AVCT_FAILED;
269 Event *event = EventCreate(true);
270 AvctSendMsgReqTskParam *param = malloc(sizeof(AvctSendMsgReqTskParam));
271 if (param == NULL) {
272 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
273 EventDelete(event);
274 return ret;
275 }
276 (void)memset_s(param, sizeof(AvctSendMsgReqTskParam), 0, sizeof(AvctSendMsgReqTskParam));
277 param->event = event;
278 param->connId = connId;
279 param->label = label;
280 param->cr = cr;
281 param->msg = PacketRefMalloc((Packet *)msg);
282 if (!AvctAsyncProcess(AvctSendMsgReqTsk, param)) {
283 EventWait(event, WAIT_TIME);
284 ret = param->ret;
285 }
286 PacketFree(param->msg);
287 free(param);
288 EventDelete(event);
289 return ret;
290 }
291
AvctSendMsgReqTsk(void * context)292 void AvctSendMsgReqTsk(void *context)
293 {
294 AvctSendMsgReqTskParam *param = (AvctSendMsgReqTskParam *)context;
295 param->ret = AvctSendMsgReq(param->connId, param->label, param->cr, param->msg);
296 EventSet(param->event);
297 return;
298 }
299
AvctSendMsgReq(uint8_t connId,uint8_t label,uint8_t cr,const Packet * msg)300 uint16_t AvctSendMsgReq(uint8_t connId, uint8_t label, uint8_t cr, const Packet *msg)
301 {
302 LOG_DEBUG("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
303 uint16_t ret;
304 AvctTxMsg txMsg = {0};
305 AvctCbConn *cbConn = AvctGetCbConnByConnId(connId);
306 if (msg == NULL) {
307 LOG_ERROR("[AVCT]The message point is NULL!");
308 ret = AVCT_ERR_PARAM;
309 return ret;
310 }
311 if (cbConn == NULL) {
312 LOG_ERROR("[AVCT]There is no connection for the ID(%hhu)!", connId);
313 ret = AVCT_ERR_CONN_BAD;
314 } else if ((cbConn->status == AVCT_CONN_ALLOC) ||
315 ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev->cbCtrl == NULL))) {
316 LOG_ERROR("[AVCT]The connection(%hhu) is not open!", connId);
317 ret = AVCT_ERR_CONN_NOT_OPEN;
318 } else {
319 /* send message */
320 txMsg.cr = cr;
321 txMsg.label = label;
322 txMsg.buf = (Packet *)msg;
323 txMsg.cbConn = cbConn;
324 AvctEvtData evtData;
325 evtData.txMsg = txMsg;
326 ret = AvctCbCtrlEvt(cbConn->cbDev, AVCT_SED_MSG_EVT, &evtData);
327 }
328 return ret;
329 }
330
331 /*
332 * Function AVCT_GetPeerMtu
333 *
334 * Description This function is called to get the mtu of the control channel.
335 * Param[in] connId The id of the connection channel.
336 * Return MTU size.
337 */
AVCT_GetPeerMtu(uint8_t connId)338 uint16_t AVCT_GetPeerMtu(uint8_t connId)
339 {
340 LOG_DEBUG("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
341 uint16_t peerMtu = 0;
342 AvctCbConn *cbConn = NULL;
343 if (connId < AVCT_MAX_CONNECTS) {
344 cbConn = &g_avctMng.cbConn[connId];
345 }
346 if ((cbConn != NULL) && (cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev->cbCtrl != NULL)) {
347 peerMtu = cbConn->cbDev->cbCtrl->peerMtu;
348 }
349 return peerMtu;
350 }
351
352 /*
353 * Function AVCT_BrConnectReq
354 * Description This function is called to create an avctp browser connection
355 * if the peer has.
356 * Param[in] connId The control channel id of the peer device.
357 * Param[in] role The connection role.
358 * Return AVCT_SUCCESS if successful, otherwise error.
359 */
AVCT_BrConnectReq(uint8_t connId,uint8_t role)360 uint16_t AVCT_BrConnectReq(uint8_t connId, uint8_t role)
361 {
362 LOG_INFO("[AVCT] %{public}s: Connid(0x%x)", __func__, connId);
363 uint16_t ret = AVCT_FAILED;
364 Event *event = EventCreate(true);
365 AvctBrConnectReqTskParam *param = malloc(sizeof(AvctBrConnectReqTskParam));
366 if (param == NULL) {
367 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
368 EventDelete(event);
369 return ret;
370 }
371 (void)memset_s(param, sizeof(AvctBrConnectReqTskParam), 0, sizeof(AvctBrConnectReqTskParam));
372 param->event = event;
373 param->connId = connId;
374 param->role = role;
375 if (!AvctAsyncProcess(AvctBrConnectReqTsk, param)) {
376 EventWait(event, WAIT_TIME);
377 ret = param->ret;
378 }
379 free(param);
380 EventDelete(event);
381 return ret;
382 }
383
AvctBrConnectReqTsk(void * context)384 void AvctBrConnectReqTsk(void *context)
385 {
386 AvctBrConnectReqTskParam *param = (AvctBrConnectReqTskParam *)context;
387 param->ret = AvctBrConnectReq(param->connId, param->role);
388 EventSet(param->event);
389 return;
390 }
391
AvctBrConnectReq(uint8_t connId,uint8_t role)392 uint16_t AvctBrConnectReq(uint8_t connId, uint8_t role)
393 {
394 LOG_DEBUG("[AVCT] %{public}s: Connid(0x%x)", __func__, connId);
395 uint16_t ret = AVCT_SUCCESS;
396 AvctCbConn *cbConn = AvctGetCbConnByConnId(connId);
397 if ((cbConn == NULL) || (cbConn->status != AVCT_CONN_BIND)) {
398 LOG_ERROR("[AVCT]There is no connection for the ID(%hhu)!", connId);
399 ret = AVCT_ERR_CONN_BAD;
400 return ret;
401 }
402 if (role == AVCT_INIT) {
403 ret = AvctBrConnectInitiate(cbConn);
404 }
405 return ret;
406 }
407
408 /*
409 * Function AVCT_BrDisconnectReq
410 * Description Remove an AVCTP browser connection. If this is the last
411 * connection to a peer the L2CAP channel for AVCTP will be closed.
412 * param[in] connId The connection channel id
413 * Return AVCT_SUCCESS if successful, otherwise error.
414 */
AVCT_BrDisconnectReq(uint8_t connId)415 uint16_t AVCT_BrDisconnectReq(uint8_t connId)
416 {
417 LOG_INFO("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
418 uint16_t ret = AVCT_FAILED;
419 Event *event = EventCreate(true);
420 AvctBrDisconnectReqTskParam *param = malloc(sizeof(AvctBrDisconnectReqTskParam));
421 if (param == NULL) {
422 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
423 EventDelete(event);
424 return ret;
425 }
426 (void)memset_s(param, sizeof(AvctBrDisconnectReqTskParam), 0, sizeof(AvctBrDisconnectReqTskParam));
427 param->event = event;
428 param->connId = connId;
429 if (!AvctAsyncProcess(AvctBrDisconnectReqTsk, param)) {
430 EventWait(event, WAIT_TIME);
431 ret = param->ret;
432 }
433 free(param);
434 EventDelete(event);
435 return ret;
436 }
437
AvctBrDisconnectReqTsk(void * context)438 void AvctBrDisconnectReqTsk(void *context)
439 {
440 AvctBrDisconnectReqTskParam *param = (AvctBrDisconnectReqTskParam *)context;
441 param->ret = AvctBrDisconnectReq(param->connId);
442 EventSet(param->event);
443 return;
444 }
445
AvctBrDisconnectReq(uint8_t connId)446 uint16_t AvctBrDisconnectReq(uint8_t connId)
447 {
448 LOG_DEBUG("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
449 uint16_t ret = AvctDisconnect(connId, AVCT_CH_BR);
450 return ret;
451 }
452
453 /*
454 * Function AVCT_BrSendMsgReq
455 * Description This function is called to send an message to the channel.
456 * AVCT.ICS #Table 2/13 3/13 Send Message
457 * AVCT.ICS #Table 3/10 Event register for message reception.
458 * AVCT Profile #11.2.3 #11.2.4 #11.1
459 * Param[in] connId The id of the connection channel which is the message to
460 * be send.
461 * Param[in] label Message label from application
462 * Param[in] cr command/response
463 * Param[in] msg Message data point
464 * Return AVCT_SUCCESS if successful, otherwise error.
465 */
AVCT_BrSendMsgReq(uint8_t connId,uint8_t label,uint8_t cr,const Packet * msg)466 uint16_t AVCT_BrSendMsgReq(uint8_t connId, uint8_t label, uint8_t cr, const Packet *msg)
467 {
468 LOG_INFO("[AVCT] %{public}s: Connid(0x%x)", __func__, connId);
469 uint16_t ret = AVCT_FAILED;
470 Event *event = EventCreate(true);
471 AvctBrSendMsgReqTskParam *param = malloc(sizeof(AvctBrSendMsgReqTskParam));
472 if (param == NULL) {
473 LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
474 EventDelete(event);
475 return ret;
476 }
477 (void)memset_s(param, sizeof(AvctBrSendMsgReqTskParam), 0, sizeof(AvctBrSendMsgReqTskParam));
478 param->event = event;
479 param->connId = connId;
480 param->label = label;
481 param->cr = cr;
482 param->msg = PacketRefMalloc((Packet *)msg);
483 if (!AvctAsyncProcess(AvctBrSendMsgReqTsk, param)) {
484 EventWait(event, WAIT_TIME);
485 ret = param->ret;
486 }
487 PacketFree(param->msg);
488 free(param);
489 EventDelete(event);
490 return ret;
491 }
492
AvctBrSendMsgReqTsk(void * context)493 void AvctBrSendMsgReqTsk(void *context)
494 {
495 AvctBrSendMsgReqTskParam *param = (AvctBrSendMsgReqTskParam *)context;
496 param->ret = AvctBrSendMsgReq(param->connId, param->label, param->cr, param->msg);
497 EventSet(param->event);
498 return;
499 }
500
AvctBrSendMsgReq(uint8_t connId,uint8_t label,uint8_t cr,const Packet * msg)501 uint16_t AvctBrSendMsgReq(uint8_t connId, uint8_t label, uint8_t cr, const Packet *msg)
502 {
503 LOG_DEBUG("[AVCT] %{public}s: Connid(0x%x)", __func__, connId);
504 uint16_t ret = AVCT_SUCCESS;
505 AvctTxMsg txMsg = {0};
506 AvctCbConn *cbConn = AvctGetCbConnByConnId(connId);
507 if (msg == NULL) {
508 ret = AVCT_ERR_PARAM;
509 return ret;
510 }
511 if (cbConn == NULL) {
512 LOG_ERROR("[AVCT]There is no connection for the ID(%hhu)!", connId);
513 ret = AVCT_ERR_CONN_BAD;
514 } else if ((cbConn->status == AVCT_CONN_ALLOC) ||
515 ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev->cbBr == NULL))) {
516 LOG_ERROR("[AVCT]The connection(%hhu) is not open!", connId);
517 ret = AVCT_ERR_CONN_NOT_OPEN;
518 } else {
519 /* send message */
520 txMsg.cr = cr;
521 txMsg.label = label;
522 txMsg.buf = (Packet *)msg;
523 txMsg.cbConn = cbConn;
524 AvctEvtData evtData;
525 evtData.txMsg = txMsg;
526 AvctCbBrEvt(cbConn->cbDev, AVCT_SED_MSG_EVT, &evtData);
527 }
528 return ret;
529 }
530
531 /*
532 * Function AVCT_BrGetPeerMtu
533 * Description This function is called to get the mtu of the browser channel.
534 * Pram[in] connId The id of the connection channel.
535 * Return MTU size.
536 */
AVCT_BrGetPeerMtu(uint8_t connId)537 uint16_t AVCT_BrGetPeerMtu(uint8_t connId)
538 {
539 LOG_DEBUG("[AVCT] %{public}s: Connid(0x%x)", __func__, connId);
540 uint16_t peerMtu = 0;
541 AvctCbConn *cbConn = NULL;
542 if (connId < AVCT_MAX_CONNECTS) {
543 cbConn = &g_avctMng.cbConn[connId];
544 }
545 if ((cbConn != NULL) && (cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev->cbBr != NULL)) {
546 peerMtu = cbConn->cbDev->cbBr->peerMtu;
547 }
548 return peerMtu;
549 }
550
551 /*
552 * Function AvctConnectInitiate
553 * Description Connect for initiate role
554 * Param[out] *cbConn connection
555 * Param[in] *connParam oint to the info of the connection request.
556 * Such as the Role、Profile ID、Callback func point.
557 * Param[in] peerAddr The peer address to be connected.
558 * Return AVCT_SUCCESS if successful, otherwise error.
559 */
AvctConnectInitiate(AvctCbConn * cbConn,const AvctConnectParam * connParam,const BtAddr * peerAddr)560 uint16_t AvctConnectInitiate(AvctCbConn *cbConn, const AvctConnectParam *connParam, const BtAddr *peerAddr)
561 {
562 uint16_t ret = AVCT_SUCCESS;
563 AvctCbCh *cbCtrl = NULL;
564 AvctCbDev *cbDev = AvctGetCbDevByAddress(peerAddr);
565 if (cbDev == NULL) {
566 cbDev = AvctCbDevAlloc(peerAddr);
567 if (cbDev == NULL) {
568 LOG_ERROR("[AVCT]AvctCbDevAlloc Failed!");
569 AvctCbConnDealloc(cbConn);
570 ret = AVCT_ERR_NO_RESOURCES;
571 } else {
572 cbCtrl = AvctCbChAlloc();
573 if (cbCtrl == NULL) {
574 LOG_ERROR("[AVCT]AvctCbChAlloc Failed!");
575 AvctCbConnDealloc(cbConn);
576 AvctCbDevDealloc(cbDev);
577 ret = AVCT_ERR_NO_RESOURCES;
578 }
579 }
580 } else {
581 /* check the connected ctrl channel has the same pid. */
582 if (AvctGetCbConnByPid(cbDev, connParam->pid)) {
583 LOG_ERROR("[AVCT]pid is in used !");
584 ret = AVCT_ERR_PID_USED;
585 }
586 }
587 if (ret == AVCT_SUCCESS) {
588 cbDev->cbCtrl = cbCtrl;
589 cbDev->chLink |= AVCT_ALLOC_CTRL;
590 cbConn->cbDev = cbDev;
591 cbConn->status = AVCT_CONN_BIND;
592 AvctEvtData evtData;
593 evtData.cbConn = cbConn;
594 ret = AvctCbCtrlEvt(cbConn->cbDev, AVCT_BIND_EVT, &evtData);
595 }
596 return ret;
597 }
598 /*
599 * Function AvctDisconnect
600 * Description Disconnet request
601 * Param[out] *cbConn connection
602 * Param[in] connId connection ID.
603 * Param[in] type connection type.
604 * Return AVCT_SUCCESS if successful, otherwise error.
605 */
AvctDisconnect(uint8_t connId,uint8_t type)606 uint16_t AvctDisconnect(uint8_t connId, uint8_t type)
607 {
608 LOG_INFO("[AVCT] %{public}s: ConnId(%hhu)", __func__, connId);
609 uint16_t ret = AVCT_SUCCESS;
610 AvctCbConn *cbConn = AvctGetCbConnByConnId(connId);
611 if (cbConn == NULL) {
612 LOG_ERROR("[AVCT]There is no connection for the ID(%hhu)!", connId);
613 ret = AVCT_ERR_CONN_BAD;
614 } else if (cbConn->cbDev == NULL) {
615 AvctCbConnDealloc(cbConn);
616 } else {
617 /* send unbind event */
618 AvctEvtData evtData;
619 evtData.cbConn = cbConn;
620 if (type == AVCT_CH_BR) {
621 ret = AvctCbBrEvt(cbConn->cbDev, AVCT_UNBIND_EVT, &evtData);
622 } else {
623 ret = AvctCbCtrlEvt(cbConn->cbDev, AVCT_UNBIND_EVT, &evtData);
624 }
625 }
626 return ret;
627 }
628
AvctAsyncProcess(void (* callback)(void * context),void * context)629 uint8_t AvctAsyncProcess(void (*callback)(void *context), void *context)
630 {
631 if (BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_AVCTP, callback, context)) {
632 return AVCT_FAILED;
633 }
634 return AVCT_SUCCESS;
635 }