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 
16 #include "avctp_ctrl_act.h"
17 #include "avctp_br.h"
18 #include "avctp_conn.h"
19 #include "avctp_ctrl.h"
20 #include "avctp_dev.h"
21 #include "avctp_gap.h"
22 #include "avctp_st.h"
23 #include "l2cap_if.h"
24 #include "log.h"
25 
26 /*****************************************************************************
27  * Globle Data  Define
28  ****************************************************************************/
29 /*****************************************************************************
30  * Function
31  ****************************************************************************/
32 Packet *AvctMakeFrgMsgHeadStart(uint8_t num, uint8_t label, uint8_t cr, uint16_t pid);
33 Packet *AvctMakeFrgMsgHeadContinueEnd(uint8_t label, uint8_t type, uint8_t cr);
34 
35 /*
36  * Function     AvctCbCtrlChConn
37  * Description  This function is called to Open control channel link.
38  * Param[in]    *cbDev  The point to the device block.
39  * Param[in]    *data  Event data
40  * Return       AVCT_SUCCESS. Others: Fail
41  */
AvctCbCtrlChConn(AvctCbDev * cbDev,const AvctEvtData * data)42 uint16_t AvctCbCtrlChConn(AvctCbDev *cbDev, const AvctEvtData *data)
43 {
44     LOG_DEBUG("[AVCT] %{public}s:", __func__);
45     GAP_Service serviceId;
46     /* Request servcie security */
47     if (g_avctMng.role == AVCT_CT) {
48         serviceId = AVRCP_CT;
49     } else {
50         serviceId = AVRCP_TG;
51     }
52     AvctRequestSecurity(cbDev, serviceId, AVCT_PSM);
53     return AVCT_SUCCESS;
54 }
55 
56 /*
57  * Function     AvctCbCtrlChConnFail
58  * Description  This function is called to Open control channel link failed.
59  * Param[in]    *cbDev  The point to the device block.
60  * Param[in]    *data  Event data
61  * Return       AVCT_SUCCESS. Others: Fail
62  */
AvctCbCtrlChConnFail(AvctCbDev * cbDev,const AvctEvtData * data)63 uint16_t AvctCbCtrlChConnFail(AvctCbDev *cbDev, const AvctEvtData *data)
64 {
65     LOG_DEBUG("[AVCT] %{public}s:", __func__);
66     AvctCbConn *cbConn = NULL;
67     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
68         cbConn = &g_avctMng.cbConn[i];
69         if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
70             AvctCbConnEvtCallback(cbConn, AVCT_CONNECT_CFM_EVT, data->result, &(cbConn->cbDev->peerAddr));
71             AvctCbConnDealloc(cbConn);
72         }
73     }
74     AvctCbDevDealloc(cbDev);
75     return AVCT_SUCCESS;
76 }
77 
78 /*
79  * Function     AvctCbCtrlChBind
80  * Description  This function is called when the control channel has been
81  *              created,and try to bind it.
82  * Param[in]    *cbDev  The point to the device block.
83  * Param[in]    *data  Event data
84  * Return       AVCT_SUCCESS. Others: Fail
85  */
AvctCbCtrlChBind(AvctCbDev * cbDev,const AvctEvtData * data)86 uint16_t AvctCbCtrlChBind(AvctCbDev *cbDev, const AvctEvtData *data)
87 {
88     LOG_DEBUG("[AVCT] %{public}s:", __func__);
89     data->cbConn->cbDev = cbDev;
90     cbDev->bindCnt++;
91     /* Send callback event to app */
92     AvctCbConnEvtCallback(data->cbConn, AVCT_CONNECT_CFM_EVT, AVCT_SUCCESS, &(data->cbConn->cbDev->peerAddr));
93     return AVCT_SUCCESS;
94 }
95 
96 /*
97  * Function     AvctCbCtrlChBindFail
98  * Description  This function is called when the control bind failed.
99  * Param[in]    *cbDev  The point to the device block.
100  * Param[in]    *data  Event data
101  * Return       AVCT_SUCCESS. Others: Fail
102  */
AvctCbCtrlChBindFail(AvctCbDev * cbDev,const AvctEvtData * data)103 uint16_t AvctCbCtrlChBindFail(AvctCbDev *cbDev, const AvctEvtData *data)
104 {
105     LOG_DEBUG("[AVCT] %{public}s:", __func__);
106     /* send connect cfm event ,result failed */
107     AvctCbConnEvtCallback(data->cbConn, AVCT_CONNECT_CFM_EVT, AVCT_FAILED, &(data->cbConn->cbDev->peerAddr));
108     /* dealloc memory */
109     AvctCbConnDealloc(data->cbConn);
110     return AVCT_SUCCESS;
111 }
112 
113 /*
114  * Function     AvctCbCtrlChDisconn
115  * Description  This function is called to disconnect the control channel.
116  * Param[in]    *cbDev  The point to the device block.
117  * Param[in]    *data  Event data
118  * Return       AVCT_SUCCESS. Others: Fail
119  */
AvctCbCtrlChDisconn(AvctCbDev * cbDev,const AvctEvtData * data)120 uint16_t AvctCbCtrlChDisconn(AvctCbDev *cbDev, const AvctEvtData *data)
121 {
122     LOG_DEBUG("[AVCT] %{public}s:", __func__);
123     L2CIF_DisconnectionReq(cbDev->cbCtrl->chId, NULL);
124     return AVCT_SUCCESS;
125 }
126 
127 /*
128  * Function     AvctCbCtrlChUnbind
129  * Description  This function is called to unbind and disconnect the control
130  *              channel.
131  * Param[in]    *cbDev  The point to the device block.
132  * Param[in]    *data  Event data
133  * Return       AVCT_SUCCESS. Others: Fail
134  */
AvctCbCtrlChUnbind(AvctCbDev * cbDev,const AvctEvtData * data)135 uint16_t AvctCbCtrlChUnbind(AvctCbDev *cbDev, const AvctEvtData *data)
136 {
137     LOG_DEBUG("[AVCT] %{public}s:", __func__);
138     /* send disconnect cfm event ,result failed */
139     AvctCbConnEvtCallback(data->cbConn, AVCT_DISCONNECT_CFM_EVT, AVCT_SUCCESS, &(data->cbConn->cbDev->peerAddr));
140     /* dealloc memory */
141     AvctCbConnDealloc(data->cbConn);
142     cbDev->bindCnt--;
143     return AVCT_SUCCESS;
144 }
145 
146 /*
147  * Function     AvctCbCtrlChCheckDisconn
148  * Description  This function is called to check if the connect is the last one which is using the ctrl channel.
149  *              If it is the last one, disconnect the channel.
150  * Param[in]    *cbDev  The point to the device block.
151  * Param[in]    *data  Event data
152  * Return       AVCT_SUCCESS. Others: Fail
153  */
AvctCbCtrlChCheckDisconn(AvctCbDev * cbDev,const AvctEvtData * data)154 uint16_t AvctCbCtrlChCheckDisconn(AvctCbDev *cbDev, const AvctEvtData *data)
155 {
156     LOG_DEBUG("[AVCT] %{public}s:", __func__);
157     /* check if the connect is the last one which is using the ctrl channel */
158     if (cbDev->bindCnt > 1) {
159         /* unbind */
160         AvctCbCtrlChUnbind(cbDev, data);
161     } else {
162         /* ctrl channel disconnect */
163         AvctCbCtrlEvt(cbDev, AVCT_DISCONN_EVT, data);
164         /* if the browser channel is exit, disconnect too */
165         if (cbDev->cbBr != NULL) {
166             AvctCbBrEvt(cbDev, AVCT_DISCONN_EVT, data);
167         }
168     }
169     return AVCT_SUCCESS;
170 }
171 
172 /*
173  * Function     AvctCbCtrlChConnInd
174  * Description  This function is called when receive the connect ind.
175  * Param[in]    *cbDev  The point to the device block.
176  * Param[in]    *data  Event data
177  * Return       AVCT_SUCCESS. Others: Fail
178  */
AvctCbCtrlChConnInd(AvctCbDev * cbDev,const AvctEvtData * data)179 uint16_t AvctCbCtrlChConnInd(AvctCbDev *cbDev, const AvctEvtData *data)
180 {
181     LOG_DEBUG("[AVCT] %{public}s:", __func__);
182     AvctCbConn *cbConn = NULL;
183     bool bind = false;
184     /* find the conn for the connection */
185     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
186         cbConn = &g_avctMng.cbConn[i];
187         if (cbConn->status) {
188             if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
189                 /* find the connection to the device and send cfm event to app */
190                 bind = true;
191                 AvctCbConnEvtCallback(cbConn, AVCT_CONNECT_CFM_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
192             } else if ((cbConn->cbDev == NULL) && (cbConn->connParam.role == AVCT_ACPT) &&
193                        (AvctGetCbConnByPid(cbDev, cbConn->connParam.pid) == NULL)) {
194                 /* bind the connection(ACCEPT) to the device */
195                 bind = true;
196                 cbConn->cbDev = cbDev;
197                 cbConn->status = AVCT_CONN_BIND;
198                 AvctCbConnEvtCallback(cbConn, AVCT_CONNECT_IND_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
199             } else {
200                 LOG_DEBUG("[AVCT] %{public}s:i(%hhu)Can't find the cbConn! "
201                           "cbConn->connId(%hhu),cbConn->status(%hhu)",
202                     __func__,
203                     i,
204                     cbConn->connId,
205                     cbConn->status);
206             }
207         }
208     }
209     /* can not bind to conn,send disconnect */
210     if (!bind) {
211         AvctCbCtrlEvt(cbDev, AVCT_DISCONN_EVT, data);
212     }
213     return AVCT_SUCCESS;
214 }
215 
216 /*
217  * Function     AvctCbCtrlChCloseInd
218  * Description  This function is called when receive the close ind.
219  * Param[in]    *cbDev  The point to the device block.
220  * Param[in]    *data  Event data
221  * Return       AVCT_SUCCESS. Others: Fail
222  */
AvctCbCtrlChCloseInd(AvctCbDev * cbDev,const AvctEvtData * data)223 uint16_t AvctCbCtrlChCloseInd(AvctCbDev *cbDev, const AvctEvtData *data)
224 {
225     LOG_DEBUG("[AVCT] %{public}s:", __func__);
226     AvctCbConn *cbConn = NULL;
227     /* find conn which connected to the device, send callback event, relase memory */
228     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
229         cbConn = &g_avctMng.cbConn[i];
230         if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
231             /* Send AVCT_DISCONNECT_IND_EVT */
232             AvctCbConnEvtCallback(cbConn, AVCT_DISCONNECT_IND_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
233             /* If Br channel is connected, send AVCT_DISCONN_EVT to close channel */
234             if (cbConn->cbDev->cbBr != NULL) {
235                 AvctCbBrEvt(cbDev, AVCT_DISCONN_EVT, (AvctEvtData *)&cbConn);
236             }
237             AvctCbConnDealloc(cbConn);
238         }
239     }
240     AvctCbChDealloc(&(cbDev->cbCtrl));
241     AvctCbDevDealloc(cbDev);
242     return AVCT_SUCCESS;
243 }
244 
245 /*
246  * Function     AvctCbCtrlChCloseCfm
247  * Description  This function is called when receive the close confirm.
248  * Param[in]    *cbDev  The point to the device block.
249  * Param[in]    *data  Event data
250  * Return       AVCT_SUCCESS. Others: Fail
251  */
AvctCbCtrlChCloseCfm(AvctCbDev * cbDev,const AvctEvtData * data)252 uint16_t AvctCbCtrlChCloseCfm(AvctCbDev *cbDev, const AvctEvtData *data)
253 {
254     LOG_DEBUG("[AVCT] %{public}s:", __func__);
255     AvctCbConn *cbConn = NULL;
256     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
257         cbConn = &g_avctMng.cbConn[i];
258         if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
259             /* Send AVCT_DISCONNECT_CFM_EVT */
260             AvctCbConnEvtCallback(cbConn, AVCT_DISCONNECT_CFM_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
261             AvctCbConnDealloc(cbConn);
262         }
263     }
264     /* Free resource */
265     AvctCbChDealloc(&(cbDev->cbCtrl));
266     AvctCbDevDealloc(cbDev);
267     return AVCT_SUCCESS;
268 }
269 
270 /*
271  * Function     AvctCbCtrlChBusyInd
272  * Description  This function is called when receive the channel busy ind.
273  * Param[in]    *cbDev  The point to the device block.
274  * Param[in]    *data  Event data
275  * Return       AVCT_SUCCESS. Others: Fail
276  */
AvctCbCtrlChBusyInd(AvctCbDev * cbDev,const AvctEvtData * data)277 uint16_t AvctCbCtrlChBusyInd(AvctCbDev *cbDev, const AvctEvtData *data)
278 {
279     LOG_DEBUG("[AVCT] %{public}s:", __func__);
280     AvctCbConn *cbConn = NULL;
281     uint8_t event = AVCT_CHANNEL_UNBUSY_EVT;
282     if (data->result == AVCT_BUSY_ST) {
283         event = AVCT_CHANNEL_BUSY_EVT;
284     }
285     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
286         cbConn = &g_avctMng.cbConn[i];
287         if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
288             /* Send AVCT_BR_CHANNEL_BUSY_EVT */
289             AvctCbConnEvtCallback(cbConn, event, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
290         }
291     }
292     return AVCT_SUCCESS;
293 }
294 
295 /*
296  * Function     AvctCbCtrlDiscardMsg
297  * Description  This function is called to discard message.
298  * Param[in]    *cbDev  The point to the device block.
299  * Param[in]    *data  Event data
300  * Return       AVCT_SUCCESS. Others: Fail
301  */
AvctCbCtrlDiscardMsg(AvctCbDev * cbDev,const AvctEvtData * data)302 uint16_t AvctCbCtrlDiscardMsg(AvctCbDev *cbDev, const AvctEvtData *data)
303 {
304     LOG_DEBUG("[AVCT] %{public}s:", __func__);
305     return AVCT_FAILED;
306 }
307 
308 /*
309  * Function     AvctCbCtrlSendMsg
310  * Description  This function is called to send message.
311  * Param[in]    *cbDev  The point to the device block.
312  * Param[in]    *data  Event data
313  * Return       AVCT_SUCCESS. Others: Fail
314  */
315 
AvctCbCtrlSendMsg(AvctCbDev * cbDev,const AvctEvtData * data)316 uint16_t AvctCbCtrlSendMsg(AvctCbDev *cbDev, const AvctEvtData *data)
317 {
318     uint16_t ret;
319     Packet *pkt = data->txMsg.buf;
320     uint16_t msgLen = (uint16_t)PacketSize(pkt);
321     LOG_DEBUG("[AVCT] %{public}s:PKT length %hu", __func__, msgLen);
322     if (msgLen > (cbDev->cbCtrl->peerMtu - AVCT_PKG_HDR_LEN_SINGLE)) {
323         /* Need Message Fragmentation */
324         ret = AvctSendFraMsg((const AvctCbCh *)cbDev->cbCtrl, (const AvctTxMsg)data->txMsg);
325     } else {
326         /* Send signle Message */
327         ret = AvctSendSignleMsg((const AvctCbCh *)cbDev->cbCtrl, (const AvctTxMsg)data->txMsg);
328     }
329     return ret;
330 }
331 
332 /*
333  * Function     AvctCbCtrlRevMsg
334  * Description  This function is called when receive message.
335  * Param[in]    *cbDev  The point to the device block.
336  * Param[in]    *data  Event data
337  * Return       AVCT_SUCCESS. Others: Fail
338  */
AvctCbCtrlRevMsg(AvctCbDev * cbDev,const AvctEvtData * data)339 NO_SANITIZE("cfi") uint16_t AvctCbCtrlRevMsg(AvctCbDev *cbDev, const AvctEvtData *data)
340 {
341     LOG_DEBUG("[AVCT] %{public}s:", __func__);
342     uint16_t ret = AVCT_SUCCESS;
343     uint8_t sHead[AVCT_PKG_HDR_LEN_SINGLE] = {0};
344     Packet *pkt = AvctMsgAsmbl(cbDev->cbCtrl, data->buf);
345     if (pkt == NULL) {
346         return ret;
347     }
348     /* Extract signle pkt head info */
349     PacketExtractHead(pkt, sHead, AVCT_PKG_HDR_LEN_SINGLE);
350     uint8_t label;
351     uint8_t cr;
352     uint8_t ipid;
353     uint16_t pid;
354     AVCT_PARSE_SIGNLE_HDR(sHead, label, cr, ipid, pid);
355     if (ipid == 1) {
356         /* an invalid Profile Identifier received */
357         LOG_WARN("[AVCT] %{public}s: Invalid ipid!", __func__);
358         return ret;
359     }
360     /* Get the conn by pid */
361     AvctCbConn *cbConn = AvctGetCbConnByPid(cbDev, pid);
362     if (cbConn != NULL) {
363         /* Send msg to app */
364         if (cbConn->connParam.msgCallback != NULL) {
365             (*cbConn->connParam.msgCallback)(cbConn->connId, label, cr, AVCT_DATA_CTRL, pkt, cbConn->connParam.context);
366         }
367         return ret;
368     }
369     LOG_DEBUG("[AVCT] %{public}s: ---------cbConn is null--------!", __func__);
370     /* Don't find pid connection,send reject */
371     if (cr == AVCT_CMD) {
372         Packet *sndPkg = PacketMalloc(AVCT_PKG_HDR_LEN_SINGLE, 0, 0);
373         if (sndPkg == NULL) {
374             LOG_ERROR("[AVCT] %{public}s: PacketMalloc failed!", __func__);
375             ret = AVCT_ERR_NO_RESOURCES;
376         } else {
377             AvctMakeRejMsgHead(sndPkg, label, pid);
378             int lRet = L2CIF_SendData(cbDev->cbCtrl->chId, sndPkg, NULL);
379             if (lRet) {
380                 LOG_WARN("[AVCT] %{public}s:L2CIF_SendData failed.error is %{public}d", __func__, lRet);
381             }
382             PacketFree(sndPkg);
383         }
384     }
385     return ret;
386 }
387 
388 /*
389  * Function     AvctCbCtrlDiscardRevMsg
390  * Description  This function is called to discard received message.
391  * Param[in]    *cbDev  The point to the device block.
392  * Param[in]    *data  Event data
393  * Return       AVCT_SUCCESS. Others: Fail
394  */
AvctCbCtrlDiscardRevMsg(AvctCbDev * cbDev,const AvctEvtData * data)395 uint16_t AvctCbCtrlDiscardRevMsg(AvctCbDev *cbDev, const AvctEvtData *data)
396 {
397     LOG_DEBUG("[AVCT] %{public}s:", __func__);
398     return AVCT_SUCCESS;
399 }
400 
401 /*
402  * Function     AvctSendSignleMsg
403  * Description  This function is called to send single type package.
404  * Param[in]    *cbCh  The point to the send link.
405  * Param[in]    txMsg  Package data
406  * Return       AVCT_SUCCESS. Others: Fail
407  */
AvctSendSignleMsg(const AvctCbCh * cbCh,const AvctTxMsg txMsg)408 uint16_t AvctSendSignleMsg(const AvctCbCh *cbCh, const AvctTxMsg txMsg)
409 {
410     LOG_DEBUG("[AVCT] %{public}s:", __func__);
411     uint16_t ret;
412     /* Malloc Head */
413     Packet *pkt = PacketInheritMalloc(txMsg.buf, AVCT_PKG_HDR_LEN_SINGLE, 0);
414     if (pkt == NULL) {
415         LOG_ERROR("[AVCT] %{public}s: PacketInheritMalloc failed!", __func__);
416         ret = AVCT_ERR_NO_RESOURCES;
417     } else {
418         /* Make Packet Head */
419         AvctMakeSignleMsgHead(pkt, txMsg.label, txMsg.cr, txMsg.cbConn->connParam.pid);
420         /* Send Packet */
421         ret = L2CIF_SendData(cbCh->chId, pkt, NULL);
422         /* pkt data debug print */
423         AvctPktDataPrint(pkt);
424         PacketFree(pkt);
425     }
426     return ret;
427 }
428 
429 /*
430  * Function     AvctSendFraMsg
431  * Description  This function is called to send fragmentation package.
432  * Param[in]    *cbCh  The point to the send link.
433  * Param[in]    txMsg  Package data
434  * Return       AVCT_SUCCESS. Others: Fail
435  */
AvctSendFraMsg(const AvctCbCh * cbCh,const AvctTxMsg txMsg)436 uint16_t AvctSendFraMsg(const AvctCbCh *cbCh, const AvctTxMsg txMsg)
437 {
438     LOG_DEBUG("[AVCT] %{public}s:", __func__);
439     uint16_t ret;
440     uint8_t pktType = AVCT_PKT_TYPE_START;
441     Packet *pkt = txMsg.buf;
442     Packet *sndPkg = NULL;
443     uint16_t msgLen = (uint16_t)PacketSize(pkt);
444     size_t size;
445     /* calculate Number of AVCTP Packets */
446     uint8_t num = (msgLen - (cbCh->peerMtu - AVCT_PKG_HDR_LEN_START)) / (cbCh->peerMtu - AVCT_PKG_HDR_LEN_CONTINUE) + 1;
447     if ((msgLen - (cbCh->peerMtu - AVCT_PKG_HDR_LEN_START)) % (cbCh->peerMtu - AVCT_PKG_HDR_LEN_CONTINUE) != 0) {
448         num++;
449     }
450     /* Fragement Message */
451     do {
452         /* Make Packet Head data */
453         if (pktType == AVCT_PKT_TYPE_START) {
454             sndPkg = AvctMakeFrgMsgHeadStart(num, txMsg.label, txMsg.cr, txMsg.cbConn->connParam.pid);
455             if (sndPkg == NULL) {
456                 LOG_ERROR("[AVCT] %{public}s: PacketMalloc failed!", __func__);
457                 ret = AVCT_ERR_NO_RESOURCES;
458                 break;
459             }
460         } else {
461             sndPkg = AvctMakeFrgMsgHeadContinueEnd(txMsg.label, pktType, txMsg.cr);
462             if (sndPkg == NULL) {
463                 LOG_ERROR("[AVCT] %{public}s: Packet memory Malloc failed!", __func__);
464                 ret = AVCT_ERR_NO_RESOURCES;
465                 break;
466             }
467         }
468         /* Make Fragment packet */
469         if (pktType == AVCT_PKT_TYPE_START) {
470             size = cbCh->peerMtu - AVCT_PKG_HDR_LEN_START;
471         } else {
472             size = cbCh->peerMtu - AVCT_PKG_HDR_LEN_CONTINUE;
473         }
474         msgLen = PacketFragment(pkt, sndPkg, size);
475         /* Send packet */
476         ret = L2CIF_SendData(cbCh->chId, sndPkg, NULL);
477         /* Free pkt memmory */
478         PacketFree(sndPkg);
479         /* Change packet type */
480         if (msgLen > (cbCh->peerMtu - AVCT_PKG_HDR_LEN_END)) {
481             pktType = AVCT_PKT_TYPE_CONTINUE;
482         } else {
483             pktType = AVCT_PKT_TYPE_END;
484         }
485     } while ((msgLen > 0) && (ret == L2CAP_SUCCESS));
486     return ret;
487 }
488 
489 /*
490  * Function     AvctParsePktType
491  * Description  This function is parase pkt type.
492  * Param[in]    data  pkg first byte.
493  * Param[out]   type  Package type
494  * Return       void
495  */
AvctParsePktType(uint8_t data,uint8_t * type)496 void AvctParsePktType(uint8_t data, uint8_t *type)
497 {
498     *type = (data >> MOVE_2BIT) & PKG_TYPE_MASK;
499 }
500 
501 /*
502  * Function     AvctMsgAsmbl
503  * Description  This function is called to asbmle fragmentation package.
504  * Param[in]    *cbCh  The point to the send link.
505  * Param[in]    pkt  Package data buffer
506  * Return       Packet. Package data buffer or NULL
507  */
AvctMsgAsmbl(AvctCbCh * cbCh,Packet * pkt)508 Packet *AvctMsgAsmbl(AvctCbCh *cbCh, Packet *pkt)
509 {
510     Packet *ret = NULL;
511     uint8_t fistByte = 0;
512     uint8_t pktType = 0;
513     uint8_t sHead[4] = {0};
514     /* Read first byte to check packet type */
515     PacketPayloadRead(pkt, &fistByte, 0, 1);
516     AvctParsePktType(fistByte, &pktType);
517     LOG_DEBUG("[AVCT] %{public}s:packet type is %hhu", __func__, pktType);
518     if (pktType == AVCT_PKT_TYPE_SINGLE) {
519         ret = pkt;
520     } else if (pktType == AVCT_PKT_TYPE_START) {
521         if (cbCh->rxMsg != NULL) {
522             /* Free pkt memmory */
523             PacketFree(cbCh->rxMsg);
524             cbCh->rxMsg = NULL;
525         }
526         /* Make single packet head at payload */
527         cbCh->rxMsg = PacketMalloc(0, 0, AVCT_PKG_HDR_LEN_SINGLE);
528         sHead[0] = fistByte;
529         PacketPayloadRead(pkt, &sHead[1], AVCT_START_PKT_PID_OFFSET, AVCT_START_PKT_PID_SIZE);
530         PacketPayloadWrite(cbCh->rxMsg, sHead, 0, AVCT_PKG_HDR_LEN_SINGLE);
531         /* Extrect start head */
532         PacketExtractHead(pkt, sHead, AVCT_PKG_HDR_LEN_START);
533         /* Add packet playload */
534         PacketAssemble(cbCh->rxMsg, pkt);
535         LOG_DEBUG("[AVCT] %{public}s:cbCh->rxMsg PacketSize(%u)", __func__, PacketSize(cbCh->rxMsg));
536     } else {
537         /* continue or end */
538         /* Extrect continue/end head */
539         PacketExtractHead(pkt, sHead, AVCT_PKG_HDR_LEN_CONTINUE);
540         /* Add packet playload */
541         PacketAssemble(cbCh->rxMsg, pkt);
542         if (pktType == AVCT_PKT_TYPE_END) {
543             ret = cbCh->rxMsg;
544         }
545         LOG_DEBUG("[AVCT] %{public}s:cbCh->rxMsg PacketSize(%u)", __func__, PacketSize(cbCh->rxMsg));
546     }
547     return ret;
548 }
549 /*
550  * Function     AvctMakeSignleMsgHead
551  * Description  Make signle packet head.
552  * Param[out]   *pkt    The point to the packet.
553  * Param[in]    label   stransport label
554  * Param[in]    cr      scommand / response
555  * Param[in]    pid     profile id
556  * Return       void
557  */
AvctMakeSignleMsgHead(const Packet * pkt,uint8_t label,uint8_t cr,uint16_t pid)558 void AvctMakeSignleMsgHead(const Packet *pkt, uint8_t label, uint8_t cr, uint16_t pid)
559 {
560     LOG_DEBUG("[AVCT] %{public}s:", __func__);
561     Buffer *buf = PacketHead(pkt);
562     uint8_t *p = (uint8_t *)BufferPtr(buf);
563     do {
564         *(p)++ = (((label) << MOVE_4BIT) | (AVCT_PKT_TYPE_SINGLE << MOVE_2BIT) | ((cr) << MOVE_1BIT));
565         *(p)++ = (uint8_t)((pid) >> MOVE_8BIT);
566         *(p) = (uint8_t)((pid)&0x00FF);
567     } while (0);
568     return;
569 }
570 /*
571  * Function     AvctMakeRejMsgHead
572  * Description  Make reject pakect head.
573  * Param[out]   *pkt    The point to the packet.
574  * Param[in]    label   stransport label
575  * Param[in]    pid     profile id
576  * Return       void
577  */
AvctMakeRejMsgHead(const Packet * pkt,uint8_t label,uint16_t pid)578 void AvctMakeRejMsgHead(const Packet *pkt, uint8_t label, uint16_t pid)
579 {
580     LOG_DEBUG("[AVCT] %{public}s:", __func__);
581     Buffer *buf = PacketHead(pkt);
582     uint8_t *p = (uint8_t *)BufferPtr(buf);
583     do {
584         *(p)++ = (((label) << MOVE_4BIT) | (AVCT_PKT_TYPE_SINGLE << MOVE_2BIT) | AVCT_REJ);
585         *(p)++ = (uint8_t)((pid) >> MOVE_8BIT);
586         *(p) = (uint8_t)((pid)&0x00FF);
587     } while (0);
588     return;
589 }
590 /*
591  * Function     AvctMakeFrgMsgHeadStart
592  * Description  Make fragment message type start.
593  * Param[in]    num    The num of fragment pakect.
594  * Param[in]    label   stransport label
595  * Param[in]    pid     profile id
596  * Return       void
597  */
AvctMakeFrgMsgHeadStart(uint8_t num,uint8_t label,uint8_t cr,uint16_t pid)598 Packet *AvctMakeFrgMsgHeadStart(uint8_t num, uint8_t label, uint8_t cr, uint16_t pid)
599 {
600     LOG_DEBUG("[AVCT] %{public}s:", __func__);
601     Packet *pkg = PacketMalloc(AVCT_PKG_HDR_LEN_START, 0, 0);
602     if (pkg != NULL) {
603         Buffer *buf = PacketHead(pkg);
604         uint8_t *p = (uint8_t *)BufferPtr(buf);
605         do {
606             *(p)++ = (((label) << MOVE_4BIT) | (AVCT_PKT_TYPE_START << MOVE_2BIT) | ((cr) << MOVE_1BIT));
607             *(p)++ = num;
608             *(p)++ = (uint8_t)((pid) >> MOVE_8BIT);
609             *(p) = (uint8_t)((pid)&0x00FF);
610         } while (0);
611     }
612     return pkg;
613 }
614 /*
615  * Function     AvctMakeFrgMsgHeadContinueEnd
616  * Description  Make fragment message type continue/End.
617  * Param[in]    label   stransport label
618  * Param[in]    type    continue/End
619  * Param[in]    cr      command/response
620  * Return       void
621  */
AvctMakeFrgMsgHeadContinueEnd(uint8_t label,uint8_t type,uint8_t cr)622 Packet *AvctMakeFrgMsgHeadContinueEnd(uint8_t label, uint8_t type, uint8_t cr)
623 {
624     LOG_DEBUG("[AVCT] %{public}s:", __func__);
625     /* Create Continue/End Head */
626     Packet *pkg = PacketMalloc(AVCT_PKG_HDR_LEN_CONTINUE, 0, 0);
627     if (pkg != NULL) {
628         Buffer *buf = PacketHead(pkg);
629         uint8_t *p = (uint8_t *)BufferPtr(buf);
630         do {
631             *(p)++ = (((label) << MOVE_4BIT) | ((type) << MOVE_2BIT) | ((cr) << MOVE_1BIT));
632         } while (0);
633     }
634     return pkg;
635 }
636 
AvctPktDataPrint(const Packet * pkt)637 void AvctPktDataPrint(const Packet *pkt)
638 {
639     uint16_t len = (uint16_t)PacketSize(pkt);
640     uint8_t buf[AVCT_32BYTE] = {0};
641     if (len > AVCT_32BYTE) {
642         len = AVCT_32BYTE;
643     }
644     PacketRead(pkt, buf, 0, len);
645     for (int i = 0; i < len; i++) {
646         LOG_DEBUG("%02X ", buf[i]);
647     }
648 }
649