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(¶m->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(¶m->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 }