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 "gap.h"
17 #include "gap_internal.h"
18
19 #include <securec.h>
20
21 #include "log.h"
22
23 #include "btm.h"
24 #include "btm/btm_inq_db.h"
25
26 typedef struct {
27 GapDiscoveryCallback callback;
28 void *context;
29 } DiscoveryCallback;
30
31 static DiscoveryCallback g_discoveryCallback;
32
GAP_RegisterDiscoveryCallback(const GapDiscoveryCallback * callback,void * context)33 int GAP_RegisterDiscoveryCallback(const GapDiscoveryCallback *callback, void *context)
34 {
35 LOG_INFO("%{public}s:%{public}s", __FUNCTION__, callback ? "register" : "NULL");
36 if (callback == NULL) {
37 (void)memset_s(&g_discoveryCallback.callback,
38 sizeof(g_discoveryCallback.callback),
39 0x00,
40 sizeof(g_discoveryCallback.callback));
41 } else {
42 g_discoveryCallback.callback = *callback;
43 }
44 g_discoveryCallback.context = context;
45 return GAP_SUCCESS;
46 }
47
GAP_DeregisterDiscoveryCallback(void)48 int GAP_DeregisterDiscoveryCallback(void)
49 {
50 (void)memset_s(&g_discoveryCallback.callback,
51 sizeof(g_discoveryCallback.callback),
52 0x00,
53 sizeof(g_discoveryCallback.callback));
54 g_discoveryCallback.context = NULL;
55 return GAP_SUCCESS;
56 }
57
GAP_Inquiry(uint8_t mode,uint8_t inquiryLength)58 int GAP_Inquiry(uint8_t mode, uint8_t inquiryLength)
59 {
60 int ret;
61 InquiryBlock *inquiryBlock = NULL;
62 const uint8_t resNum = 0;
63
64 LOG_INFO("%{public}s:%hhu[%02x]", __FUNCTION__, mode, inquiryLength);
65
66 if (mode > GAP_INQUIRY_MODE_LIMITED) {
67 return GAP_ERR_INVAL_PARAM;
68 }
69
70 if (GapIsBredrEnable() == false) {
71 return GAP_ERR_NOT_ENABLE;
72 }
73
74 inquiryBlock = GapGetInquiryBlock();
75 if (inquiryBlock->status != GAP_INQUIRY_STATUS_IDLE) {
76 ret = GAP_ERR_INVAL_STATE;
77 } else {
78 uint32_t iacLAP = LAP_GENERAL_INQUIRY_ACCESS;
79 inquiryBlock->status = GAP_INQUIRY_STATUS_START;
80
81 if (mode == GAP_INQUIRY_MODE_GENERAL) {
82 iacLAP = LAP_GENERAL_INQUIRY_ACCESS;
83 } else if (mode == GAP_INQUIRY_MODE_LIMITED) {
84 iacLAP = LAP_LIMITED_INQUIRY_ACCESS;
85 }
86
87 HciInquiryeParam param = {
88 .lap = iacLAP,
89 .inquiryLen = inquiryLength,
90 .numResponses = resNum,
91 };
92 ret = HCI_Inquiry(¶m);
93 }
94
95 return ret;
96 }
97
GapOnInquiryComplete(const HciInquiryCompleteEventParam * eventParam)98 NO_SANITIZE("cfi") void GapOnInquiryComplete(const HciInquiryCompleteEventParam *eventParam)
99 {
100 InquiryBlock *inquiryBlock = NULL;
101
102 LOG_DEBUG("%{public}s:", __FUNCTION__);
103
104 inquiryBlock = GapGetInquiryBlock();
105 inquiryBlock->status = GAP_INQUIRY_STATUS_IDLE;
106
107 if (g_discoveryCallback.callback.inquiryComplete) {
108 g_discoveryCallback.callback.inquiryComplete(eventParam->status, g_discoveryCallback.context);
109 }
110 }
111
GapOnInquiryResult(const HciInquiryResultEventParam * eventParam)112 void GapOnInquiryResult(const HciInquiryResultEventParam *eventParam)
113 {
114 BtmInquiryInfo inquiryInfo;
115
116 for (uint8_t i = 0; i < eventParam->numResponses; i++) {
117 BtAddr addr = BT_ADDR_NULL;
118 GapChangeHCIAddr(&addr, &eventParam->responses[i].bdAddr, BT_PUBLIC_DEVICE_ADDRESS);
119 uint32_t cod = COD_ARRAY_TO_UINT(eventParam->responses[i].classOfDevice);
120
121 inquiryInfo.clockOffset = eventParam->responses[i].clockOffset;
122 inquiryInfo.pageScanRepetitionMode = eventParam->responses[i].pageScanRepetitionMode;
123 BtmAssignOrUpdateInquiryInfo(&addr, &inquiryInfo);
124
125 LOG_DEBUG("%{public}s: " BT_ADDR_FMT, __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr));
126 if (g_discoveryCallback.callback.inquiryResult) {
127 g_discoveryCallback.callback.inquiryResult(&addr, cod, g_discoveryCallback.context);
128 }
129 }
130 }
131
GapOnInquiryResultRssi(const HciInquiryResultWithRssiEventParam * eventParam)132 NO_SANITIZE("cfi") void GapOnInquiryResultRssi(const HciInquiryResultWithRssiEventParam *eventParam)
133 {
134 BtmInquiryInfo inquiryInfo;
135
136 for (uint8_t i = 0; i < eventParam->numResponses; i++) {
137 BtAddr addr = BT_ADDR_NULL;
138 GapChangeHCIAddr(&addr, &eventParam->responses[i].bdAddr, BT_PUBLIC_DEVICE_ADDRESS);
139
140 uint32_t cod = COD_ARRAY_TO_UINT(eventParam->responses[i].classOfDevice);
141 int8_t rssi = (int8_t)eventParam->responses[i].rssi;
142
143 inquiryInfo.clockOffset = eventParam->responses[i].clockOffset;
144 inquiryInfo.pageScanRepetitionMode = eventParam->responses[i].pageScanRepetitionMode;
145 BtmAssignOrUpdateInquiryInfo(&addr, &inquiryInfo);
146
147 LOG_DEBUG("%{public}s: " BT_ADDR_FMT, __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr));
148 if (g_discoveryCallback.callback.inquiryResultRssi) {
149 g_discoveryCallback.callback.inquiryResultRssi(&addr, cod, rssi, g_discoveryCallback.context);
150 }
151 }
152 }
153
GapOnEntendedInquiryResult(const HciExtendedInquiryResultEventParam * eventParam)154 NO_SANITIZE("cfi") void GapOnEntendedInquiryResult(const HciExtendedInquiryResultEventParam *eventParam)
155 {
156 BtmInquiryInfo inquiryInfo;
157
158 BtAddr addr = BT_ADDR_NULL;
159 GapChangeHCIAddr(&addr, &eventParam->bdAddr, BT_PUBLIC_DEVICE_ADDRESS);
160
161 uint32_t cod = COD_ARRAY_TO_UINT(eventParam->classofDevice);
162 int8_t rssi = (int8_t)eventParam->rssi;
163
164 inquiryInfo.clockOffset = eventParam->clockOffset;
165 inquiryInfo.pageScanRepetitionMode = eventParam->pageScanRepetitionMode;
166 BtmAssignOrUpdateInquiryInfo(&addr, &inquiryInfo);
167
168 LOG_DEBUG("%{public}s: " BT_ADDR_FMT, __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr));
169 if (g_discoveryCallback.callback.extendedInquiryResult) {
170 g_discoveryCallback.callback.extendedInquiryResult(
171 &addr, cod, rssi, eventParam->extendedInquiryResponse, g_discoveryCallback.context);
172 }
173 }
174
GAP_InquiryCancel(void)175 int GAP_InquiryCancel(void)
176 {
177 int ret;
178 InquiryBlock *inquiryBlock = NULL;
179
180 LOG_INFO("%{public}s:", __FUNCTION__);
181
182 if (GapIsBredrEnable() == false) {
183 return GAP_ERR_NOT_ENABLE;
184 }
185
186 inquiryBlock = GapGetInquiryBlock();
187 if (inquiryBlock->status == GAP_INQUIRY_STATUS_START) {
188 inquiryBlock->status = GAP_INQUIRY_STATUS_CANCEL;
189 ret = HCI_InquiryCancel();
190 } else {
191 ret = GAP_ERR_INVAL_STATE;
192 }
193
194 return ret;
195 }
196
GapInquiryCancelComplete(const HciInquiryCancelReturnParam * param)197 NO_SANITIZE("cfi") void GapInquiryCancelComplete(const HciInquiryCancelReturnParam *param)
198 {
199 LOG_DEBUG("%{public}s:", __FUNCTION__);
200 InquiryBlock *inquiryBlock = NULL;
201 bool callback = false;
202
203 inquiryBlock = GapGetInquiryBlock();
204 if (inquiryBlock->status == GAP_INQUIRY_STATUS_CANCEL) {
205 callback = true;
206 if (param->status != HCI_SUCCESS) {
207 LOG_ERROR("Inquiry Cancel Fail. status = %hhu", param->status);
208 } else {
209 inquiryBlock->status = GAP_INQUIRY_STATUS_IDLE;
210 }
211 } else {
212 LOG_ERROR("Error Status");
213 }
214
215 if (callback && g_discoveryCallback.callback.inquiryComplete) {
216 g_discoveryCallback.callback.inquiryComplete(param->status, g_discoveryCallback.context);
217 }
218 }
219
GAP_GetRemoteName(const BtAddr * addr)220 int GAP_GetRemoteName(const BtAddr *addr)
221 {
222 int ret;
223 RemoteNameBlock *remoteNameBlock = NULL;
224 BtmInquiryInfo inquiryInfo;
225
226 LOG_INFO("%{public}s:" BT_ADDR_FMT, __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr->addr));
227
228 if (GapIsBredrEnable() == false) {
229 return GAP_ERR_NOT_ENABLE;
230 }
231
232 remoteNameBlock = GapGetRemoteNameBlock();
233 if (remoteNameBlock->status != GAP_REMOTE_NAME_STATUS_IDLE) {
234 ret = GAP_ERR_INVAL_STATE;
235 } else {
236 HciRemoteNameRequestParam hciCmdParam = {0};
237
238 remoteNameBlock->status = GAP_REMOTE_NAME_STATUS_START;
239 (void)memcpy_s(hciCmdParam.addr.raw, BT_ADDRESS_SIZE, addr->addr, BT_ADDRESS_SIZE);
240
241 ret = BtmQueryInquiryInfoByAddr(addr, &inquiryInfo);
242 if (ret == BT_SUCCESS) {
243 hciCmdParam.clockOffset = inquiryInfo.clockOffset;
244 hciCmdParam.pageScanRepetMode = inquiryInfo.pageScanRepetitionMode;
245 }
246
247 ret = HCI_RemoteNameRequest(&hciCmdParam);
248 }
249
250 return ret;
251 }
252
GapOnGetRemoteNameComplete(const HciRemoteNameRequestCompleteEventParam * eventParam)253 NO_SANITIZE("cfi") void GapOnGetRemoteNameComplete(const HciRemoteNameRequestCompleteEventParam *eventParam)
254 {
255 LOG_DEBUG("%{public}s:", __FUNCTION__);
256 RemoteNameBlock *remoteNameBlock = NULL;
257
258 remoteNameBlock = GapGetRemoteNameBlock();
259 if (remoteNameBlock->status == GAP_REMOTE_NAME_STATUS_IDLE) {
260 LOG_ERROR("Error Status");
261 }
262 remoteNameBlock->status = GAP_REMOTE_NAME_STATUS_IDLE;
263 BtAddr addr = BT_ADDR_NULL;
264 GapChangeHCIAddr(&addr, &eventParam->bdAddr, BT_PUBLIC_DEVICE_ADDRESS);
265
266 if (g_discoveryCallback.callback.remoteName) {
267 g_discoveryCallback.callback.remoteName(
268 eventParam->status, &addr, eventParam->remoteName, g_discoveryCallback.context);
269 }
270 }
271
GAP_GetRemoteNameCancel(const BtAddr * addr)272 int GAP_GetRemoteNameCancel(const BtAddr *addr)
273 {
274 int ret;
275 RemoteNameBlock *remoteNameBlock = NULL;
276
277 LOG_INFO("%{public}s:" BT_ADDR_FMT, __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr->addr));
278
279 if (GapIsBredrEnable() == false) {
280 return GAP_ERR_NOT_ENABLE;
281 }
282
283 remoteNameBlock = GapGetRemoteNameBlock();
284 if (remoteNameBlock->status == GAP_REMOTE_NAME_STATUS_IDLE) {
285 ret = GAP_ERR_INVAL_STATE;
286 } else {
287 remoteNameBlock->status = GAP_REMOTE_NAME_STATUS_CANCEL;
288 HciRemoteNameRequestCancelParam hciCmdParam;
289 (void)memcpy_s(hciCmdParam.addr.raw, BT_ADDRESS_SIZE, addr->addr, BT_ADDRESS_SIZE);
290
291 ret = HCI_RemoteNameRequestCancel(&hciCmdParam);
292 }
293
294 return ret;
295 }
296
GapGetRemoteNameCancelComplete(const HciRemoteNameRequestCancelReturnParam * param)297 void GapGetRemoteNameCancelComplete(const HciRemoteNameRequestCancelReturnParam *param)
298 {
299 LOG_DEBUG("%{public}s:", __FUNCTION__);
300 RemoteNameBlock *remoteNameBlock = NULL;
301
302 remoteNameBlock = GapGetRemoteNameBlock();
303 if (remoteNameBlock->status == GAP_REMOTE_NAME_STATUS_CANCEL) {
304 if (param->status != HCI_SUCCESS) {
305 LOG_ERROR("Get Remote Name Cancel Fail. status = %hhu", param->status);
306 }
307 } else {
308 LOG_ERROR("Error Status");
309 }
310 }
311