1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "avctp_br_act.h"
16 #include "avctp_st.h"
17 #include "avctp_conn.h"
18 #include "avctp_gap.h"
19 #include "avctp_ctrl.h"
20 #include "avctp_ctrl_act.h"
21 #include "avctp_br.h"
22 #include "l2cap_if.h"
23 #include "log.h"
24
25 /*****************************************************************************
26 * Globle Data Define
27 ****************************************************************************/
28 /*
29 * Function AvctCbBrChConn
30 * Description This function is called to Open browser channel link.
31 * Param[in] *cbDev The point to the device block.
32 * Param[in] *data Event data
33 * Return AVCT_SUCCESS. Others: Fail
34 */
AvctCbBrChConn(AvctCbDev * cbDev,const AvctEvtData * data)35 uint16_t AvctCbBrChConn(AvctCbDev *cbDev, const AvctEvtData *data)
36 {
37 LOG_DEBUG("[AVCT] %{public}s:", __func__);
38 GAP_Service serviceId;
39 /* Request servcie security */
40 if (g_avctMng.role == AVCT_CT) {
41 serviceId = AVRCP_CT_BROWSING;
42 } else {
43 serviceId = AVRCP_TG_BROWSING;
44 }
45 AvctRequestSecurity(cbDev, serviceId, AVCT_BR_PSM);
46 return AVCT_SUCCESS;
47 }
48
49 /*
50 * Function AvctCbBrChConnFail
51 * Description This function is called when Open browser channel link failed.
52 * Param[in] *cbDev The point to the device block.
53 * Param[in] *data Event data
54 * Return AVCT_SUCCESS. Others: Fail
55 */
AvctCbBrChConnFail(AvctCbDev * cbDev,const AvctEvtData * data)56 uint16_t AvctCbBrChConnFail(AvctCbDev *cbDev, const AvctEvtData *data)
57 {
58 LOG_DEBUG("[AVCT] %{public}s:", __func__);
59 AvctCbConn *cbConn = NULL;
60 for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
61 cbConn = &g_avctMng.cbConn[i];
62 if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
63 if (cbDev->chLink & AVCT_ALLOC_BR) {
64 AvctCbConnEvtCallback(cbConn, AVCT_BR_CONNECT_CFM_EVT, data->result, &(cbConn->cbDev->peerAddr));
65 }
66 }
67 }
68 AvctCbChDealloc(&(cbDev->cbBr));
69 cbDev->chLink &= ~AVCT_ALLOC_BR;
70 return AVCT_SUCCESS;
71 }
72
73 /*
74 * Function AvctCbBrChBind
75 * Description This function is called when the browser channel had been
76 * created, only bind it.
77 * Param[in] *cbDev The point to the device block.
78 * Param[in] *data Event data
79 * Return AVCT_SUCCESS. Others: Fail
80 */
AvctCbBrChBind(AvctCbDev * cbDev,const AvctEvtData * data)81 uint16_t AvctCbBrChBind(AvctCbDev *cbDev, const AvctEvtData *data)
82 {
83 LOG_DEBUG("[AVCT] %{public}s:", __func__);
84 /* Send callback event to app */
85 AvctCbConnEvtCallback(data->cbConn, AVCT_BR_CONNECT_CFM_EVT, AVCT_SUCCESS, &(data->cbConn->cbDev->peerAddr));
86 return AVCT_SUCCESS;
87 }
88
89 /*
90 * Function AvctCbBrChBindFail
91 * Description This function is called when the browser channel had been
92 * created, try to bind it failed.
93 * Param[in] *cbDev The point to the device block.
94 * Param[in] *data Event data
95 * Return AVCT_SUCCESS. Others: Fail
96 */
AvctCbBrChBindFail(AvctCbDev * cbDev,const AvctEvtData * data)97 uint16_t AvctCbBrChBindFail(AvctCbDev *cbDev, const AvctEvtData *data)
98 {
99 LOG_DEBUG("[AVCT] %{public}s:", __func__);
100 /* send connect cfm event ,result failed */
101 AvctCbConnEvtCallback(data->cbConn, AVCT_BR_CONNECT_CFM_EVT, AVCT_FAILED, &(data->cbConn->cbDev->peerAddr));
102 return AVCT_SUCCESS;
103 }
104
105 /*
106 * Function AvctCbBrChDisconn
107 * Description This function is called to disconnect the browser channel .
108 * Param[in] *cbDev The point to the device block.
109 * Param[in] *data Event data
110 * Return AVCT_SUCCESS. Others: Fail
111 */
AvctCbBrChDisconn(AvctCbDev * cbDev,const AvctEvtData * data)112 uint16_t AvctCbBrChDisconn(AvctCbDev *cbDev, const AvctEvtData *data)
113 {
114 LOG_DEBUG("[AVCT] %{public}s:", __func__);
115 L2CIF_DisconnectionReq(cbDev->cbBr->chId, NULL);
116 return AVCT_SUCCESS;
117 }
118
119 /*
120 * Function AvctCbBrChUnbind
121 * Description This function is called to unbind and disconnect the browser
122 * channel.
123 * Param[in] *cbDev The point to the device block.
124 * Param[in] *data Event data
125 * Return AVCT_SUCCESS. Others: Fail
126 */
AvctCbBrChUnbind(AvctCbDev * cbDev,const AvctEvtData * data)127 uint16_t AvctCbBrChUnbind(AvctCbDev *cbDev, const AvctEvtData *data)
128 {
129 LOG_DEBUG("[AVCT] %{public}s:", __func__);
130 /* send disconnect cfm event ,result failed */
131 AvctCbConnEvtCallback(data->cbConn, AVCT_BR_DISCONNECT_CFM_EVT, AVCT_SUCCESS, &(data->cbConn->cbDev->peerAddr));
132 return AVCT_SUCCESS;
133 }
134
135 /*
136 * Function AvctCbBrChCheckDisconn
137 * Description This function is called to check if the connect is the last one which is using the br channel.
138 * If it is the last one, disconnect the channel.
139 * Param[in] *cbDev The point to the device block.
140 * Param[in] *data Event data
141 * Return AVCT_SUCCESS. Others: Fail
142 */
AvctCbBrChCheckDisconn(AvctCbDev * cbDev,const AvctEvtData * data)143 uint16_t AvctCbBrChCheckDisconn(AvctCbDev *cbDev, const AvctEvtData *data)
144 {
145 LOG_DEBUG("[AVCT] %{public}s:", __func__);
146 /* check if the connect is the last one which is using the br channel */
147 if (cbDev->bindCnt > 1) {
148 /* unbind */
149 AvctCbBrChUnbind(cbDev, data);
150 } else {
151 /* if the browser channel is exit, disconnect too */
152 if (cbDev->cbBr != NULL) {
153 AvctCbBrEvt(cbDev, AVCT_DISCONN_EVT, data);
154 }
155 }
156 return AVCT_SUCCESS;
157 }
158
159 /*
160 * Function AvctCbBrChConnInd
161 * Description This function is called when receive connect ind.
162 * Param[in] *cbDev The point to the device block.
163 * Param[in] *data Event data
164 * Return AVCT_SUCCESS. Others: Fail
165 */
AvctCbBrChConnInd(AvctCbDev * cbDev,const AvctEvtData * data)166 uint16_t AvctCbBrChConnInd(AvctCbDev *cbDev, const AvctEvtData *data)
167 {
168 LOG_DEBUG("[AVCT] %{public}s:", __func__);
169 AvctCbConn *cbConn = NULL;
170 bool bind = false;
171 /* find the conn for the connection */
172 for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
173 cbConn = &g_avctMng.cbConn[i];
174 if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
175 /* find the connection to the device and send cfm event to app */
176 bind = true;
177 if (cbDev->cbBr->ia == AVCT_ACPT) {
178 AvctCbConnEvtCallback(cbConn, AVCT_BR_CONNECT_IND_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
179 } else {
180 AvctCbConnEvtCallback(cbConn, AVCT_BR_CONNECT_CFM_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
181 }
182 }
183 }
184 /* can not bind to conn ,send disconnect */
185 if (!bind) {
186 AvctCbBrEvt(cbDev, AVCT_DISCONN_EVT, data);
187 }
188 return AVCT_SUCCESS;
189 }
190
191 /*
192 * Function AvctCbBrChCloseInd
193 * Description This function is called when receive close ind.
194 * Param[in] *cbDev The point to the device block.
195 * Param[in] *data Event data
196 * Return AVCT_SUCCESS. Others: Fail
197 */
AvctCbBrChCloseInd(AvctCbDev * cbDev,const AvctEvtData * data)198 uint16_t AvctCbBrChCloseInd(AvctCbDev *cbDev, const AvctEvtData *data)
199 {
200 LOG_DEBUG("[AVCT] %{public}s:", __func__);
201 AvctCbConn *cbConn = NULL;
202 /* find conn which connected to the device, send callback event,relase memory */
203 for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
204 if (g_avctMng.cbConn[i].cbDev == cbDev) {
205 cbConn = &g_avctMng.cbConn[i];
206 /* Send AVCT_DISCONNECT_IND_EVT */
207 AvctCbConnEvtCallback(cbConn, AVCT_BR_DISCONNECT_IND_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
208 }
209 }
210 AvctCbChDealloc(&(cbDev->cbBr));
211 cbDev->chLink &= ~AVCT_ALLOC_BR;
212 return AVCT_SUCCESS;
213 }
214
215 /*
216 * Function AvctCbBrChCloseCfm
217 * Description This function is called when receive close confirm.
218 * Param[in] *cbDev The point to the device block.
219 * Param[in] *data Event data
220 * Return AVCT_SUCCESS. Others: Fail
221 */
AvctCbBrChCloseCfm(AvctCbDev * cbDev,const AvctEvtData * data)222 uint16_t AvctCbBrChCloseCfm(AvctCbDev *cbDev, const AvctEvtData *data)
223 {
224 LOG_DEBUG("[AVCT] %{public}s:", __func__);
225 AvctCbConn *cbConn = NULL;
226 for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
227 cbConn = &g_avctMng.cbConn[i];
228 if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
229 /* Send AVCT_BR_DISCONNECT_CFM_EVT */
230 AvctCbConnEvtCallback(cbConn, AVCT_BR_DISCONNECT_CFM_EVT, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
231 }
232 }
233 /* Free resource */
234 AvctCbChDealloc(&(cbDev->cbBr));
235 cbDev->chLink &= ~AVCT_ALLOC_BR;
236 return AVCT_SUCCESS;
237 }
238
239 /*
240 * Function AvctCbBrChBusyInd
241 * Description This function is called when receive channel busy.
242 * Param[in] *cbDev The point to the device block.
243 * Param[in] *data Event data
244 * Return AVCT_SUCCESS. Others: Fail
245 */
AvctCbBrChBusyInd(AvctCbDev * cbDev,const AvctEvtData * data)246 uint16_t AvctCbBrChBusyInd(AvctCbDev *cbDev, const AvctEvtData *data)
247 {
248 LOG_DEBUG("[AVCT] %{public}s:", __func__);
249 AvctCbConn *cbConn = NULL;
250 uint8_t event = AVCT_BR_CHANNEL_UNBUSY_EVT;
251 if (data->result == AVCT_BUSY_ST) {
252 event = AVCT_BR_CHANNEL_BUSY_EVT;
253 }
254 for (uint8_t i = 0; i < AVCT_MAX_CONNECTS; i++) {
255 cbConn = &g_avctMng.cbConn[i];
256 if ((cbConn->status == AVCT_CONN_BIND) && (cbConn->cbDev == cbDev)) {
257 /* Send AVCT_BR_CHANNEL_BUSY_EVT */
258 AvctCbConnEvtCallback(cbConn, event, AVCT_SUCCESS, &(cbConn->cbDev->peerAddr));
259 }
260 }
261 return AVCT_SUCCESS;
262 }
263
264 /*
265 * Function AvctCbBrDiscardMsg
266 * Description This function is called when discard received message.
267 * Param[in] *cbDev The point to the device block.
268 * Param[in] *data Event data
269 * Return AVCT_SUCCESS. Others: Fail
270 */
AvctCbBrDiscardMsg(AvctCbDev * cbDev,const AvctEvtData * data)271 uint16_t AvctCbBrDiscardMsg(AvctCbDev *cbDev, const AvctEvtData *data)
272 {
273 LOG_DEBUG("[AVCT] %{public}s:", __func__);
274 return AVCT_FAILED;
275 }
276
277 /*
278 * Function AvctCbBrSendMsg
279 * Description This function is called to send message.
280 * Param[in] *cbDev The point to the device block.
281 * Param[in] *data Event data
282 * Return AVCT_SUCCESS. Others: Fail
283 */
AvctCbBrSendMsg(AvctCbDev * cbDev,const AvctEvtData * data)284 uint16_t AvctCbBrSendMsg(AvctCbDev *cbDev, const AvctEvtData *data)
285 {
286 LOG_DEBUG("[AVCT] %{public}s:", __func__);
287 uint16_t ret = AVCT_SUCCESS;
288 AvctTxMsg txMsg = data->txMsg;
289 AvctCbCh *cbBr = cbDev->cbBr;
290 /* Malloc Head */
291 Packet *pkt = PacketInheritMalloc(txMsg.buf, AVCT_PKG_HDR_LEN_SINGLE, 0);
292 if (pkt == NULL) {
293 LOG_ERROR("[AVCT] %{public}s: PacketInheritMalloc failed!", __func__);
294 ret = AVCT_ERR_NO_RESOURCES;
295 } else {
296 /* Make Packet Head */
297 AvctMakeSignleMsgHead(pkt, txMsg.label, txMsg.cr, txMsg.cbConn->connParam.pid);
298 /* Send Packet */
299 int lRet = L2CIF_SendData(cbBr->chId, pkt, NULL);
300 if (lRet) {
301 LOG_WARN("[AVCT] %{public}s:L2CIF_SendData failed.error is %{public}d", __func__, lRet);
302 }
303 PacketFree(pkt);
304 }
305 return ret;
306 }
307
308 /*
309 * Function AvctCbBrRevMsg
310 * Description This function is called when received message.
311 * Param[in] *cbDev The point to the device block.
312 * Param[in] *data Event data
313 * Return AVCT_SUCCESS. Others: Fail
314 */
AvctCbBrRevMsg(AvctCbDev * cbDev,const AvctEvtData * data)315 uint16_t AvctCbBrRevMsg(AvctCbDev *cbDev, const AvctEvtData *data)
316 {
317 LOG_DEBUG("[AVCT] %{public}s:", __func__);
318 uint16_t ret = AVCT_SUCCESS;
319 uint8_t sHead[AVCT_PKG_HDR_LEN_SINGLE] = {0};
320 Packet *pkt = AvctMsgAsmbl(cbDev->cbBr, data->buf);
321 if (pkt == NULL) {
322 return ret;
323 }
324 /* Extract signle pkt head info */
325 PacketExtractHead(pkt, sHead, AVCT_PKG_HDR_LEN_SINGLE);
326 uint8_t label;
327 uint8_t cr;
328 uint8_t ipid;
329 uint16_t pid;
330 AVCT_PARSE_SIGNLE_HDR(sHead, label, cr, ipid, pid);
331 if (ipid == 1) {
332 /* an invalid Profile Identifier received */
333 LOG_WARN("[AVCT] %{public}s: Invalid ipid!", __func__);
334 return ret;
335 }
336 /* Get the conn by pid */
337 AvctCbConn *cbConn = AvctGetCbConnByPid(cbDev, pid);
338 if (cbConn != NULL) {
339 /* Send msg to app */
340 if (cbConn->connParam.msgCallback != NULL) {
341 (*cbConn->connParam.msgCallback)(cbConn->connId, label, cr, AVCT_DATA_BR, pkt, cbConn->connParam.context);
342 }
343 return ret;
344 }
345 /* Don't find pid connection,send reject */
346 if (cr == AVCT_CMD) {
347 Packet *sndPkg = PacketMalloc(AVCT_PKG_HDR_LEN_SINGLE, 0, 0);
348 if (sndPkg == NULL) {
349 LOG_ERROR("[AVCT] %{public}s: PacketMalloc failed!", __func__);
350 ret = AVCT_ERR_NO_RESOURCES;
351 } else {
352 AvctMakeRejMsgHead(sndPkg, label, pid);
353 int lRet = L2CIF_SendData(cbDev->cbBr->chId, sndPkg, NULL);
354 if (lRet) {
355 LOG_WARN("[AVCT] %{public}s:L2CIF_SendData failed.error is %{public}d", __func__, lRet);
356 }
357 PacketFree(sndPkg);
358 }
359 }
360 return ret;
361 }
362
363 /*
364 * Function AvctCbBrDiscardRevMsg
365 * Description This function is called to discard received message.
366 * Param[in] *cbDev The point to the device block.
367 * Param[in] *data Event data
368 * Return AVCT_SUCCESS. Others: Fail
369 */
370
AvctCbBrDiscardRevMsg(AvctCbDev * cbDev,const AvctEvtData * data)371 uint16_t AvctCbBrDiscardRevMsg(AvctCbDev *cbDev, const AvctEvtData *data)
372 {
373 LOG_DEBUG("[AVCT] %{public}s:", __func__);
374 return AVCT_SUCCESS;
375 }
376