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_gap.h"
16 #include "avctp_br_l2cap.h"
17 #include "avctp_ctrl.h"
18 #include "avctp_ctrl_l2cap.h"
19 #include "avctp_st.h"
20 #include "log.h"
21 #include "securec.h"
22 
23 /*****************************************************************************
24  * Globle Data  Define
25  ****************************************************************************/
26 /*****************************************************************************
27  * Function
28  ****************************************************************************/
29 /*
30  * Function     AvctSecurityResultCallback
31  * Description  This function is the callback from gap to check service security .
32  * Param[in]    result  The check result.
33  * Param[in]    channelId  The service info.
34  * Param[in]    context  The connection control block.
35  * Return       void
36  */
AvctSecurityResultCallback(uint16_t result,GapServiceSecurityInfo serviceInfo,void * context)37 void AvctSecurityResultCallback(uint16_t result, GapServiceSecurityInfo serviceInfo, void *context)
38 {
39     LOG_INFO("[AVCT] %{public}s:result(%hu) ", __func__, result);
40     AvctSecurityResultCallbackTskParam *param = malloc(sizeof(AvctSecurityResultCallbackTskParam));
41     if (param == NULL) {
42         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
43         return;
44     }
45     (void)memset_s(param, sizeof(AvctSecurityResultCallbackTskParam), 0, sizeof(AvctSecurityResultCallbackTskParam));
46     param->result = result;
47     (void)memcpy_s(&param->serviceInfo, sizeof(GapServiceSecurityInfo), &serviceInfo, sizeof(GapServiceSecurityInfo));
48     param->context = context;
49     if (AvctAsyncProcess(AvctSecurityResultCallbackTsk, param)) {
50         free(param);
51     }
52     return;
53 }
54 
AvctSecurityResultCallbackTsk(void * context)55 void AvctSecurityResultCallbackTsk(void *context)
56 {
57     AvctSecurityResultCallbackTskParam *param = (AvctSecurityResultCallbackTskParam *)context;
58     AvctSecurityResult(param->result, param->serviceInfo, param->context);
59     free(param);
60     return;
61 }
62 
AvctSecurityResult(uint16_t result,GapServiceSecurityInfo serviceInfo,void * context)63 void AvctSecurityResult(uint16_t result, GapServiceSecurityInfo serviceInfo, void *context)
64 {
65     LOG_DEBUG("[AVCT] %{public}s:result(%hu) ", __func__, result);
66     AvctCbDev *cbDev = ((AvctCbDev *)context);
67     AvctCbCh *cbCh = NULL;
68     if (result != GAP_SUCCESS) {
69         /* Security check fail,send close event */
70         AvctEvtData evtData;
71         evtData.result = AVCT_FAILED;
72         AvctCbCtrlEvt(cbDev, AVCT_REV_DISCONN_EVT, &evtData);
73         return;
74     }
75     LOG_DEBUG("[AVCT] %{public}s: channelId.l2capPsm is (%x),serviceId(%{public}d),chlink(%hhu) ",
76         __func__,
77         serviceInfo.channelId.l2capPsm,
78         serviceInfo.serviceId,
79         cbDev->chLink);
80     if ((serviceInfo.serviceId == AVRCP_CT) || (serviceInfo.serviceId == AVRCP_TG)) {
81         if (cbDev->chLink & AVCT_ALLOC_CTRL) {
82             cbCh = cbDev->cbCtrl;
83             cbCh->chState = AVCT_CH_CONN;
84             if (L2CIF_ConnectReq(&(cbDev->peerAddr), AVCT_PSM, AVCT_PSM, NULL, AvctCtrlL2CIFConnectReqCallback)) {
85                 LOG_ERROR("[AVCT] %{public}s:L2CIF_ConnectReq failed.", __func__);
86             }
87         } else {
88             LOG_ERROR("[AVCT] %{public}s: Ctrl channel not allocated, Can't connect!", __func__);
89         }
90     } else if ((serviceInfo.serviceId == AVRCP_CT_BROWSING) || (serviceInfo.serviceId == AVRCP_TG_BROWSING)) {
91         /* Browser channel connect */
92         if (cbDev->chLink & AVCT_ALLOC_BR) {
93             cbCh = cbDev->cbBr;
94             cbCh->chState = AVCT_CH_CONN;
95             if (L2CIF_ConnectReq(&(cbDev->peerAddr), AVCT_BR_PSM, AVCT_BR_PSM, NULL, AvctBrwL2CIFConnectReqCallback)) {
96                 LOG_ERROR("[AVCT] %{public}s:L2CIF_ConnectReq failed.", __func__);
97             }
98         } else {
99             LOG_ERROR("[AVCT] %{public}s: Br channel not allocated, Can't connect!", __func__);
100         }
101     } else {
102         LOG_WARN("[AVCT] %{public}s: ServiceID(%{public}d) from GAP is error!", __func__, serviceInfo.serviceId);
103     }
104     return;
105 }
106 
107 /*
108  * Function     AvctRevConnSecurityResultCallback
109  * Description  GAP security request check callback func.
110  * Param[in]    result Check result.
111  * Param[in]    channelId   Channel Id.
112  * Param[out]   context
113  * Return       void
114  */
AvctRevConnSecurityResultCallback(uint16_t result,GapServiceSecurityInfo serviceInfo,void * context)115 void AvctRevConnSecurityResultCallback(uint16_t result, GapServiceSecurityInfo serviceInfo, void *context)
116 {
117     LOG_INFO("[AVCT] %{public}s:result(%hu)", __func__, result);
118     AvctRevConnSecurityResultCallbackTskParam *param = malloc(sizeof(AvctRevConnSecurityResultCallbackTskParam));
119     if (param == NULL) {
120         LOG_ERROR("[AVCT] %{public}s: memory malloc failed", __func__);
121         return;
122     }
123     (void)memset_s(
124         param, sizeof(AvctRevConnSecurityResultCallbackTskParam), 0, sizeof(AvctRevConnSecurityResultCallbackTskParam));
125     param->result = result;
126     (void)memcpy_s(&param->serviceInfo, sizeof(GapServiceSecurityInfo), &serviceInfo, sizeof(GapServiceSecurityInfo));
127     param->context = context;
128     if (AvctAsyncProcess(AvctRevConnSecurityResultCallbackTsk, param)) {
129         free((AvctRevConnParam *)param->context);
130         free(param);
131     }
132     return;
133 }
134 
AvctRevConnSecurityResultCallbackTsk(void * context)135 void AvctRevConnSecurityResultCallbackTsk(void *context)
136 {
137     AvctRevConnSecurityResultCallbackTskParam *param = (AvctRevConnSecurityResultCallbackTskParam *)context;
138     AvctRevConnSecurityResult(param->result, param->serviceInfo, param->context);
139     free(param);
140     return;
141 }
142 
AvctRevConnSecurityResult(uint16_t result,GapServiceSecurityInfo serviceInfo,void * context)143 void AvctRevConnSecurityResult(uint16_t result, GapServiceSecurityInfo serviceInfo, void *context)
144 {
145     LOG_DEBUG("[AVCT] %{public}s:result(%hu)", __func__, result);
146     AvctRevConnParam *param = (AvctRevConnParam *)context;
147     if (result != GAP_SUCCESS) {
148         /* Security check fail,send L2CAP_SECURITY_BLOCK rsp */
149         result = L2CAP_SECURITY_BLOCK;
150         L2CIF_ConnectRsp(param->lcid, param->id, result, 0, NULL);
151     } else {
152         if ((serviceInfo.serviceId == AVRCP_CT) || (serviceInfo.serviceId == AVRCP_TG)) {
153             AvctRecvConnectionReqAct(&(param->addr), param->aclHandle, param->lcid, param->id, param->psm);
154         } else if ((serviceInfo.serviceId == AVRCP_CT_BROWSING) || (serviceInfo.serviceId == AVRCP_TG_BROWSING)) {
155             AvctBrRecvConnectionReqAct(&(param->addr), param->aclHandle, param->lcid, param->id, param->psm);
156         } else {
157             LOG_WARN("[AVCT] %{public}s: ServiceID(%{public}d) from GAP is error!", __func__, serviceInfo.serviceId);
158         }
159     }
160     if (param != NULL) {
161         free(param);
162         param = NULL;
163     }
164     return;
165 }
166 
167 /*
168  * Function     AvctRequestSecurity
169  * Description  This function is called to Open control channel link.
170  * Param[in]    *cbDev      The point to the device block.
171  * Param[in]    serviceId   seviced id defined by GAP
172  * Param[in]    psm
173  * Return       AVCT_SUCCESS. Others: Fail
174  */
AvctRequestSecurity(const AvctCbDev * cbDev,GAP_Service serviceId,uint16_t psm)175 void AvctRequestSecurity(const AvctCbDev *cbDev, GAP_Service serviceId, uint16_t psm)
176 {
177     LOG_DEBUG("[AVCT] %{public}s:Sevcieid(0x%x),psm(0x%x)", __func__, serviceId, psm);
178     GapRequestSecurityParam gapParam = {0};
179     /* Request servcie security */
180     gapParam.info.protocolId = SEC_PROTOCOL_L2CAP;
181     gapParam.callback = AvctSecurityResultCallback;
182     gapParam.context = (AvctCbDev *)cbDev;
183     gapParam.info.direction = OUTGOING;
184     gapParam.info.serviceId = serviceId;
185     gapParam.info.channelId.l2capPsm = psm;
186     if (GAPIF_RequestSecurityAsync(&(cbDev->peerAddr), &gapParam)) {
187         LOG_ERROR("[AVCT] %{public}s:GAP_RequestSecurity failed!", __func__);
188     }
189     return;
190 }
191 /*
192  * Function     AvctRequestSecurityBy
193  * Description  This function is the callback from gap to check service security .
194  * Param[in]    aclHandle  ACL handle.
195  * Param[in]    lcid   The link channel id.
196  * Param[in]    id
197  * Param[in]    lpsm
198  * Return       void
199  */
AvctRequestSecurityBy(const uint16_t aclHandle,const BtAddr addr,const uint16_t lcid,const uint8_t id,const uint16_t lpsm)200 void AvctRequestSecurityBy(
201     const uint16_t aclHandle, const BtAddr addr, const uint16_t lcid, const uint8_t id, const uint16_t lpsm)
202 {
203     LOG_DEBUG("[AVCT] %{public}s:Addr(%x:%x:%x:%x:%x:%x)", __func__, BT_ADDR_FMT_ASC(addr.addr));
204     AvctRevConnParam *connParam = malloc(sizeof(AvctRevConnParam));
205     if (connParam == NULL) {
206         LOG_ERROR("[AVCT] %{public}s:memory alloc failed!", __func__);
207         return;
208     }
209     connParam->addr = addr;
210     connParam->aclHandle = aclHandle;
211     connParam->lcid = lcid;
212     connParam->id = id;
213     connParam->psm = lpsm;
214     /* Request servcie security */
215     GapRequestSecurityParam gapParam;
216     /* Request servcie security */
217     gapParam.info.protocolId = SEC_PROTOCOL_L2CAP;
218     gapParam.callback = (GapSecurityResultCallback)AvctRevConnSecurityResultCallback;
219     gapParam.context = connParam;
220     gapParam.info.channelId.l2capPsm = lpsm;
221     if (lpsm == AVCT_PSM) {
222         if (g_avctMng.role == AVCT_CT) {
223             gapParam.info.serviceId = AVRCP_CT;
224         } else {
225             gapParam.info.serviceId = AVRCP_TG;
226         }
227     } else {
228         if (g_avctMng.role == AVCT_CT) {
229             gapParam.info.serviceId = AVRCP_CT_BROWSING;
230         } else {
231             gapParam.info.serviceId = AVRCP_TG_BROWSING;
232         }
233     }
234     gapParam.info.direction = INCOMING;
235     if (GAPIF_RequestSecurityAsync(&addr, &gapParam)) {
236         LOG_ERROR("[AVCT] %{public}s:GAP_RequestSecurity failed!", __func__);
237         free(connParam);
238     }
239     return;
240 }