• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                 /* bind the connection(ACCEPT) to the device */
194                 bind = true;
195                 cbConn->cbDev = cbDev;
196                 cbConn->status = AVCT_CONN_BIND;
197                 AvctCbConnEvtCallback(cbConn, AVCT_CONNECT_IND_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
198             } else {
199                 LOG_DEBUG("[AVCT] %{public}s:i(%hhu)Can't find the cbConn! "
200                           "cbConn->connId(%hhu),cbConn->status(%hhu)",
201                     __func__,
202                     i,
203                     cbConn->connId,
204                     cbConn->status);
205             }
206         }
207     }
208     /* can not bind to conn,send disconnect */
209     if (!bind) {
210         AvctCbCtrlEvt(cbDev, AVCT_DISCONN_EVT, data);
211     }
212     return AVCT_SUCCESS;
213 }
214 
215 /*
216  * Function     AvctCbCtrlChCloseInd
217  * Description  This function is called when receive the close ind.
218  * Param[in]    *cbDev  The point to the device block.
219  * Param[in]    *data  Event data
220  * Return       AVCT_SUCCESS. Others: Fail
221  */
AvctCbCtrlChCloseInd(AvctCbDev * cbDev,const AvctEvtData * data)222 uint16_t AvctCbCtrlChCloseInd(AvctCbDev *cbDev, const AvctEvtData *data)
223 {
224     LOG_DEBUG("[AVCT] %{public}s:", __func__);
225     AvctCbConn *cbConn = NULL;
226     /* find conn which connected to the device, send callback event, relase memory */
227     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
228         cbConn = &g_avctMng.cbConn[i];
229         if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
230             /* Send AVCT_DISCONNECT_IND_EVT */
231             AvctCbConnEvtCallback(cbConn, AVCT_DISCONNECT_IND_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
232             /* If Br channel is connected, send AVCT_DISCONN_EVT to close channel */
233             if (cbConn->cbDev->cbBr != NULL) {
234                 AvctCbBrEvt(cbDev, AVCT_DISCONN_EVT, (AvctEvtData *)&cbConn);
235             }
236             AvctCbConnDealloc(cbConn);
237         }
238     }
239     AvctCbChDealloc(&(cbDev->cbCtrl));
240     AvctCbDevDealloc(cbDev);
241     return AVCT_SUCCESS;
242 }
243 
244 /*
245  * Function     AvctCbCtrlChCloseCfm
246  * Description  This function is called when receive the close confirm.
247  * Param[in]    *cbDev  The point to the device block.
248  * Param[in]    *data  Event data
249  * Return       AVCT_SUCCESS. Others: Fail
250  */
AvctCbCtrlChCloseCfm(AvctCbDev * cbDev,const AvctEvtData * data)251 uint16_t AvctCbCtrlChCloseCfm(AvctCbDev *cbDev, const AvctEvtData *data)
252 {
253     LOG_DEBUG("[AVCT] %{public}s:", __func__);
254     AvctCbConn *cbConn = NULL;
255     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
256         cbConn = &g_avctMng.cbConn[i];
257         if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
258             /* Send AVCT_DISCONNECT_CFM_EVT */
259             AvctCbConnEvtCallback(cbConn, AVCT_DISCONNECT_CFM_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
260             AvctCbConnDealloc(cbConn);
261         }
262     }
263     /* Free resource */
264     AvctCbChDealloc(&(cbDev->cbCtrl));
265     AvctCbDevDealloc(cbDev);
266     return AVCT_SUCCESS;
267 }
268 
269 /*
270  * Function     AvctCbCtrlChBusyInd
271  * Description  This function is called when receive the channel busy ind.
272  * Param[in]    *cbDev  The point to the device block.
273  * Param[in]    *data  Event data
274  * Return       AVCT_SUCCESS. Others: Fail
275  */
AvctCbCtrlChBusyInd(AvctCbDev * cbDev,const AvctEvtData * data)276 uint16_t AvctCbCtrlChBusyInd(AvctCbDev *cbDev, const AvctEvtData *data)
277 {
278     LOG_DEBUG("[AVCT] %{public}s:", __func__);
279     AvctCbConn *cbConn = NULL;
280     uint8_t event = AVCT_CHANNEL_UNBUSY_EVT;
281     if (data->result == AVCT_BUSY_ST) {
282         event = AVCT_CHANNEL_BUSY_EVT;
283     }
284     for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
285         cbConn = &g_avctMng.cbConn[i];
286         if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
287             /* Send AVCT_BR_CHANNEL_BUSY_EVT */
288             AvctCbConnEvtCallback(cbConn, event, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
289         }
290     }
291     return AVCT_SUCCESS;
292 }
293 
294 /*
295  * Function     AvctCbCtrlDiscardMsg
296  * Description  This function is called to discard message.
297  * Param[in]    *cbDev  The point to the device block.
298  * Param[in]    *data  Event data
299  * Return       AVCT_SUCCESS. Others: Fail
300  */
AvctCbCtrlDiscardMsg(AvctCbDev * cbDev,const AvctEvtData * data)301 uint16_t AvctCbCtrlDiscardMsg(AvctCbDev *cbDev, const AvctEvtData *data)
302 {
303     LOG_DEBUG("[AVCT] %{public}s:", __func__);
304     return AVCT_FAILED;
305 }
306 
307 /*
308  * Function     AvctCbCtrlSendMsg
309  * Description  This function is called to send message.
310  * Param[in]    *cbDev  The point to the device block.
311  * Param[in]    *data  Event data
312  * Return       AVCT_SUCCESS. Others: Fail
313  */
314 
AvctCbCtrlSendMsg(AvctCbDev * cbDev,const AvctEvtData * data)315 uint16_t AvctCbCtrlSendMsg(AvctCbDev *cbDev, const AvctEvtData *data)
316 {
317     uint16_t ret;
318     Packet *pkt = data->txMsg.buf;
319     uint16_t msgLen = (uint16_t)PacketSize(pkt);
320     LOG_DEBUG("[AVCT] %{public}s:PKT length %hu", __func__, msgLen);
321     if (msgLen > (cbDev->cbCtrl->peerMtu - AVCT_PKG_HDR_LEN_SINGLE)) {
322         /* Need Message Fragmentation */
323         ret = AvctSendFraMsg((const AvctCbCh *)cbDev->cbCtrl, (const AvctTxMsg)data->txMsg);
324     } else {
325         /* Send signle Message */
326         ret = AvctSendSignleMsg((const AvctCbCh *)cbDev->cbCtrl, (const AvctTxMsg)data->txMsg);
327     }
328     return ret;
329 }
330 
331 /*
332  * Function     AvctCbCtrlRevMsg
333  * Description  This function is called when receive message.
334  * Param[in]    *cbDev  The point to the device block.
335  * Param[in]    *data  Event data
336  * Return       AVCT_SUCCESS. Others: Fail
337  */
AvctCbCtrlRevMsg(AvctCbDev * cbDev,const AvctEvtData * data)338 NO_SANITIZE("cfi") uint16_t AvctCbCtrlRevMsg(AvctCbDev *cbDev, const AvctEvtData *data)
339 {
340     LOG_DEBUG("[AVCT] %{public}s:", __func__);
341     uint16_t ret = AVCT_SUCCESS;
342     uint8_t sHead[AVCT_PKG_HDR_LEN_SINGLE] = {0};
343     Packet *pkt = AvctMsgAsmbl(cbDev->cbCtrl, data->buf);
344     if (pkt == NULL) {
345         return ret;
346     }
347     /* Extract signle pkt head info */
348     PacketExtractHead(pkt, sHead, AVCT_PKG_HDR_LEN_SINGLE);
349     uint8_t label;
350     uint8_t cr;
351     uint8_t ipid;
352     uint16_t pid;
353     AVCT_PARSE_SIGNLE_HDR(sHead, label, cr, ipid, pid);
354     if (ipid == 1) {
355         /* an invalid Profile Identifier received */
356         LOG_WARN("[AVCT] %{public}s: Invalid ipid!", __func__);
357         return ret;
358     }
359     /* call all cb of pid */
360     uint8_t conId = 255; //invalid value
361     for (uint8_t i = 0; i <= AVCT_MAX_CONNECTS;) {
362         AvctCbConn *cbConn = AvctGetCbConidConn(cbDev, pid, i, &conId);
363         if ((cbConn != NULL) && (cbConn->connParam.msgCallback != NULL)) {
364             (*cbConn->connParam.msgCallback)(cbConn->connId, label, cr, AVCT_DATA_CTRL, pkt, cbConn->connParam.context);
365             i = conId + 1;
366             continue;
367         } else if (conId < AVCT_MAX_CONNECTS) {
368             return ret;
369         }
370         break;
371     }
372     LOG_DEBUG("[AVCT] %{public}s: ---------cbConn is null--------!", __func__);
373     /* Don't find pid connection,send reject */
374     if (cr == AVCT_CMD) {
375         Packet *sndPkg = PacketMalloc(AVCT_PKG_HDR_LEN_SINGLE, 0, 0);
376         if (sndPkg == NULL) {
377             LOG_ERROR("[AVCT] %{public}s: PacketMalloc failed!", __func__);
378             ret = AVCT_ERR_NO_RESOURCES;
379         } else {
380             AvctMakeRejMsgHead(sndPkg, label, pid);
381             int lRet = L2CIF_SendData(cbDev->cbCtrl->chId, sndPkg, NULL);
382             if (lRet) {
383                 LOG_WARN("[AVCT] %{public}s:L2CIF_SendData failed.error is %{public}d", __func__, lRet);
384             }
385             PacketFree(sndPkg);
386         }
387     }
388     return ret;
389 }
390 
391 /*
392  * Function     AvctCbCtrlDiscardRevMsg
393  * Description  This function is called to discard received message.
394  * Param[in]    *cbDev  The point to the device block.
395  * Param[in]    *data  Event data
396  * Return       AVCT_SUCCESS. Others: Fail
397  */
AvctCbCtrlDiscardRevMsg(AvctCbDev * cbDev,const AvctEvtData * data)398 uint16_t AvctCbCtrlDiscardRevMsg(AvctCbDev *cbDev, const AvctEvtData *data)
399 {
400     LOG_DEBUG("[AVCT] %{public}s:", __func__);
401     return AVCT_SUCCESS;
402 }
403 
404 /*
405  * Function     AvctSendSignleMsg
406  * Description  This function is called to send single type package.
407  * Param[in]    *cbCh  The point to the send link.
408  * Param[in]    txMsg  Package data
409  * Return       AVCT_SUCCESS. Others: Fail
410  */
AvctSendSignleMsg(const AvctCbCh * cbCh,const AvctTxMsg txMsg)411 uint16_t AvctSendSignleMsg(const AvctCbCh *cbCh, const AvctTxMsg txMsg)
412 {
413     LOG_DEBUG("[AVCT] %{public}s:", __func__);
414     uint16_t ret;
415     /* Malloc Head */
416     Packet *pkt = PacketInheritMalloc(txMsg.buf, AVCT_PKG_HDR_LEN_SINGLE, 0);
417     if (pkt == NULL) {
418         LOG_ERROR("[AVCT] %{public}s: PacketInheritMalloc failed!", __func__);
419         ret = AVCT_ERR_NO_RESOURCES;
420     } else {
421         /* Make Packet Head */
422         AvctMakeSignleMsgHead(pkt, txMsg.label, txMsg.cr, txMsg.cbConn->connParam.pid);
423         /* Send Packet */
424         ret = L2CIF_SendData(cbCh->chId, pkt, NULL);
425         /* pkt data debug print */
426         AvctPktDataPrint(pkt);
427         PacketFree(pkt);
428     }
429     return ret;
430 }
431 
432 /*
433  * Function     AvctSendFraMsg
434  * Description  This function is called to send fragmentation package.
435  * Param[in]    *cbCh  The point to the send link.
436  * Param[in]    txMsg  Package data
437  * Return       AVCT_SUCCESS. Others: Fail
438  */
AvctSendFraMsg(const AvctCbCh * cbCh,const AvctTxMsg txMsg)439 uint16_t AvctSendFraMsg(const AvctCbCh *cbCh, const AvctTxMsg txMsg)
440 {
441     LOG_DEBUG("[AVCT] %{public}s:", __func__);
442     uint16_t ret;
443     uint8_t pktType = AVCT_PKT_TYPE_START;
444     Packet *pkt = txMsg.buf;
445     Packet *sndPkg = NULL;
446     uint16_t msgLen = (uint16_t)PacketSize(pkt);
447     size_t size;
448     /* calculate Number of AVCTP Packets */
449     uint8_t num = (msgLen - (cbCh->peerMtu - AVCT_PKG_HDR_LEN_START)) / (cbCh->peerMtu - AVCT_PKG_HDR_LEN_CONTINUE) + 1;
450     if ((msgLen - (cbCh->peerMtu - AVCT_PKG_HDR_LEN_START)) % (cbCh->peerMtu - AVCT_PKG_HDR_LEN_CONTINUE) != 0) {
451         num++;
452     }
453     /* Fragement Message */
454     do {
455         /* Make Packet Head data */
456         if (pktType == AVCT_PKT_TYPE_START) {
457             sndPkg = AvctMakeFrgMsgHeadStart(num, txMsg.label, txMsg.cr, txMsg.cbConn->connParam.pid);
458             if (sndPkg == NULL) {
459                 LOG_ERROR("[AVCT] %{public}s: PacketMalloc failed!", __func__);
460                 ret = AVCT_ERR_NO_RESOURCES;
461                 break;
462             }
463         } else {
464             sndPkg = AvctMakeFrgMsgHeadContinueEnd(txMsg.label, pktType, txMsg.cr);
465             if (sndPkg == NULL) {
466                 LOG_ERROR("[AVCT] %{public}s: Packet memory Malloc failed!", __func__);
467                 ret = AVCT_ERR_NO_RESOURCES;
468                 break;
469             }
470         }
471         /* Make Fragment packet */
472         if (pktType == AVCT_PKT_TYPE_START) {
473             size = cbCh->peerMtu - AVCT_PKG_HDR_LEN_START;
474         } else {
475             size = cbCh->peerMtu - AVCT_PKG_HDR_LEN_CONTINUE;
476         }
477         msgLen = PacketFragment(pkt, sndPkg, size);
478         /* Send packet */
479         ret = L2CIF_SendData(cbCh->chId, sndPkg, NULL);
480         /* Free pkt memmory */
481         PacketFree(sndPkg);
482         /* Change packet type */
483         if (msgLen > (cbCh->peerMtu - AVCT_PKG_HDR_LEN_END)) {
484             pktType = AVCT_PKT_TYPE_CONTINUE;
485         } else {
486             pktType = AVCT_PKT_TYPE_END;
487         }
488     } while ((msgLen > 0) && (ret == L2CAP_SUCCESS));
489     return ret;
490 }
491 
492 /*
493  * Function     AvctParsePktType
494  * Description  This function is parase pkt type.
495  * Param[in]    data  pkg first byte.
496  * Param[out]   type  Package type
497  * Return       void
498  */
AvctParsePktType(uint8_t data,uint8_t * type)499 void AvctParsePktType(uint8_t data, uint8_t *type)
500 {
501     *type = (data >> MOVE_2BIT) & PKG_TYPE_MASK;
502 }
503 
504 /*
505  * Function     AvctMsgAsmbl
506  * Description  This function is called to asbmle fragmentation package.
507  * Param[in]    *cbCh  The point to the send link.
508  * Param[in]    pkt  Package data buffer
509  * Return       Packet. Package data buffer or NULL
510  */
AvctMsgAsmbl(AvctCbCh * cbCh,Packet * pkt)511 Packet *AvctMsgAsmbl(AvctCbCh *cbCh, Packet *pkt)
512 {
513     Packet *ret = NULL;
514     uint8_t fistByte = 0;
515     uint8_t pktType = 0;
516     uint8_t sHead[4] = {0};
517     /* Read first byte to check packet type */
518     PacketPayloadRead(pkt, &fistByte, 0, 1);
519     AvctParsePktType(fistByte, &pktType);
520     LOG_DEBUG("[AVCT] %{public}s:packet type is %hhu", __func__, pktType);
521     if (pktType == AVCT_PKT_TYPE_SINGLE) {
522         ret = pkt;
523     } else if (pktType == AVCT_PKT_TYPE_START) {
524         if (cbCh->rxMsg != NULL) {
525             /* Free pkt memmory */
526             PacketFree(cbCh->rxMsg);
527             cbCh->rxMsg = NULL;
528         }
529         /* Make single packet head at payload */
530         cbCh->rxMsg = PacketMalloc(0, 0, AVCT_PKG_HDR_LEN_SINGLE);
531         sHead[0] = fistByte;
532         PacketPayloadRead(pkt, &sHead[1], AVCT_START_PKT_PID_OFFSET, AVCT_START_PKT_PID_SIZE);
533         PacketPayloadWrite(cbCh->rxMsg, sHead, 0, AVCT_PKG_HDR_LEN_SINGLE);
534         /* Extrect start head */
535         PacketExtractHead(pkt, sHead, AVCT_PKG_HDR_LEN_START);
536         /* Add packet playload */
537         PacketAssemble(cbCh->rxMsg, pkt);
538         LOG_DEBUG("[AVCT] %{public}s:cbCh->rxMsg PacketSize(%u)", __func__, PacketSize(cbCh->rxMsg));
539     } else {
540         /* continue or end */
541         /* Extrect continue/end head */
542         PacketExtractHead(pkt, sHead, AVCT_PKG_HDR_LEN_CONTINUE);
543         /* Add packet playload */
544         PacketAssemble(cbCh->rxMsg, pkt);
545         if (pktType == AVCT_PKT_TYPE_END) {
546             ret = cbCh->rxMsg;
547         }
548         LOG_DEBUG("[AVCT] %{public}s:cbCh->rxMsg PacketSize(%u)", __func__, PacketSize(cbCh->rxMsg));
549     }
550     return ret;
551 }
552 /*
553  * Function     AvctMakeSignleMsgHead
554  * Description  Make signle packet head.
555  * Param[out]   *pkt    The point to the packet.
556  * Param[in]    label   stransport label
557  * Param[in]    cr      scommand / response
558  * Param[in]    pid     profile id
559  * Return       void
560  */
AvctMakeSignleMsgHead(const Packet * pkt,uint8_t label,uint8_t cr,uint16_t pid)561 void AvctMakeSignleMsgHead(const Packet *pkt, uint8_t label, uint8_t cr, uint16_t pid)
562 {
563     LOG_DEBUG("[AVCT] %{public}s:", __func__);
564     Buffer *buf = PacketHead(pkt);
565     uint8_t *p = (uint8_t *)BufferPtr(buf);
566     do {
567         *(p)++ = (((label) << MOVE_4BIT) | (AVCT_PKT_TYPE_SINGLE << MOVE_2BIT) | ((cr) << MOVE_1BIT));
568         *(p)++ = (uint8_t)((pid) >> MOVE_8BIT);
569         *(p) = (uint8_t)((pid)&0x00FF);
570     } while (0);
571     return;
572 }
573 /*
574  * Function     AvctMakeRejMsgHead
575  * Description  Make reject pakect head.
576  * Param[out]   *pkt    The point to the packet.
577  * Param[in]    label   stransport label
578  * Param[in]    pid     profile id
579  * Return       void
580  */
AvctMakeRejMsgHead(const Packet * pkt,uint8_t label,uint16_t pid)581 void AvctMakeRejMsgHead(const Packet *pkt, uint8_t label, uint16_t pid)
582 {
583     LOG_DEBUG("[AVCT] %{public}s:", __func__);
584     Buffer *buf = PacketHead(pkt);
585     uint8_t *p = (uint8_t *)BufferPtr(buf);
586     do {
587         *(p)++ = (((label) << MOVE_4BIT) | (AVCT_PKT_TYPE_SINGLE << MOVE_2BIT) | AVCT_REJ);
588         *(p)++ = (uint8_t)((pid) >> MOVE_8BIT);
589         *(p) = (uint8_t)((pid)&0x00FF);
590     } while (0);
591     return;
592 }
593 /*
594  * Function     AvctMakeFrgMsgHeadStart
595  * Description  Make fragment message type start.
596  * Param[in]    num    The num of fragment pakect.
597  * Param[in]    label   stransport label
598  * Param[in]    pid     profile id
599  * Return       void
600  */
AvctMakeFrgMsgHeadStart(uint8_t num,uint8_t label,uint8_t cr,uint16_t pid)601 Packet *AvctMakeFrgMsgHeadStart(uint8_t num, uint8_t label, uint8_t cr, uint16_t pid)
602 {
603     LOG_DEBUG("[AVCT] %{public}s:", __func__);
604     Packet *pkg = PacketMalloc(AVCT_PKG_HDR_LEN_START, 0, 0);
605     if (pkg != NULL) {
606         Buffer *buf = PacketHead(pkg);
607         uint8_t *p = (uint8_t *)BufferPtr(buf);
608         do {
609             *(p)++ = (((label) << MOVE_4BIT) | (AVCT_PKT_TYPE_START << MOVE_2BIT) | ((cr) << MOVE_1BIT));
610             *(p)++ = num;
611             *(p)++ = (uint8_t)((pid) >> MOVE_8BIT);
612             *(p) = (uint8_t)((pid)&0x00FF);
613         } while (0);
614     }
615     return pkg;
616 }
617 /*
618  * Function     AvctMakeFrgMsgHeadContinueEnd
619  * Description  Make fragment message type continue/End.
620  * Param[in]    label   stransport label
621  * Param[in]    type    continue/End
622  * Param[in]    cr      command/response
623  * Return       void
624  */
AvctMakeFrgMsgHeadContinueEnd(uint8_t label,uint8_t type,uint8_t cr)625 Packet *AvctMakeFrgMsgHeadContinueEnd(uint8_t label, uint8_t type, uint8_t cr)
626 {
627     LOG_DEBUG("[AVCT] %{public}s:", __func__);
628     /* Create Continue/End Head */
629     Packet *pkg = PacketMalloc(AVCT_PKG_HDR_LEN_CONTINUE, 0, 0);
630     if (pkg != NULL) {
631         Buffer *buf = PacketHead(pkg);
632         uint8_t *p = (uint8_t *)BufferPtr(buf);
633         do {
634             *(p)++ = (((label) << MOVE_4BIT) | ((type) << MOVE_2BIT) | ((cr) << MOVE_1BIT));
635         } while (0);
636     }
637     return pkg;
638 }
639 
AvctPktDataPrint(const Packet * pkt)640 void AvctPktDataPrint(const Packet *pkt)
641 {
642     uint16_t len = (uint16_t)PacketSize(pkt);
643     uint8_t buf[AVCT_32BYTE] = {0};
644     if (len > AVCT_32BYTE) {
645         len = AVCT_32BYTE;
646     }
647     PacketRead(pkt, buf, 0, len);
648     for (int i = 0; i < len; i++) {
649         LOG_DEBUG("%02X ", buf[i]);
650     }
651 }
652