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