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(&param->connParam, sizeof(AvctConnectParam), connParam, sizeof(AvctConnectParam));
163     (void)memcpy_s(&param->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(&param->connId, &param->connParam, &param->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 }