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