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(&param);
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