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