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_le.h"
17 #include "gap_internal.h"
18
19 #include <securec.h>
20
21 #include "allocator.h"
22 #include "log.h"
23 #include "thread.h"
24
25 #include "btm/btm_le_sec.h"
26 #include "btm/btm_thread.h"
27 #include "hci/hci.h"
28 #include "hci/hci_error.h"
29 #include "smp/smp.h"
30
31 typedef enum {
32 ADV_REPORT,
33 EXTENDED_ADV_REPORT,
34 DIRECTED_ADV_REPORT,
35 } AdvReportType;
36
37 typedef struct {
38 AdvReportType reportType;
39 void *report;
40 bool processing;
41 BtmIdentityResolvingKey *IRKList;
42 uint16_t listCount;
43 uint16_t resolveIndex;
44 BtAddr addr;
45 bool doCallback;
46 } AdvReportRPAResolveInfo;
47
48 typedef struct {
49 GapScanCallback callback;
50 void *context;
51 } LeScanCallback;
52
53 typedef struct {
54 GapExScanCallback callback;
55 void *context;
56 } LeExScanCallback;
57
58 static LeScanCallback g_leScanCallback;
59 static LeExScanCallback g_leExScanCallback;
60
GapFreeReportRPAResolveInfo(void * data)61 void GapFreeReportRPAResolveInfo(void *data)
62 {
63 AdvReportRPAResolveInfo *info = data;
64 switch (info->reportType) {
65 case ADV_REPORT: {
66 HciLeAdvertisingReport *report = info->report;
67 MEM_MALLOC.free(report->data);
68 break;
69 }
70 case EXTENDED_ADV_REPORT: {
71 HciLeExtendedAdvertisingReport *report = info->report;
72 MEM_MALLOC.free(report->data);
73 break;
74 }
75 case DIRECTED_ADV_REPORT:
76 default:
77 break;
78 }
79 MEM_MALLOC.free(info->report);
80 MEM_MALLOC.free(info->IRKList);
81 MEM_MALLOC.free(info);
82 }
83
GAP_RegisterScanCallback(const GapScanCallback * callback,void * context)84 int GAP_RegisterScanCallback(const GapScanCallback *callback, void *context)
85 {
86 LOG_INFO("%{public}s:%{public}s", __FUNCTION__, callback ? "register" : "NULL");
87 if (callback == NULL) {
88 (void)memset_s(
89 &g_leScanCallback.callback, sizeof(g_leScanCallback.callback), 0x00, sizeof(g_leScanCallback.callback));
90 } else {
91 g_leScanCallback.callback = *callback;
92 }
93 g_leScanCallback.context = context;
94 return GAP_SUCCESS;
95 }
96
GAP_DeregisterScanCallback(void)97 int GAP_DeregisterScanCallback(void)
98 {
99 (void)memset_s(
100 &g_leScanCallback.callback, sizeof(g_leScanCallback.callback), 0x00, sizeof(g_leScanCallback.callback));
101 g_leScanCallback.context = NULL;
102 return GAP_SUCCESS;
103 }
104
GAP_LeScanSetParam(GapLeScanParam param,uint8_t scanFilterPolity)105 int GAP_LeScanSetParam(GapLeScanParam param, uint8_t scanFilterPolity)
106 {
107 LOG_INFO("%{public}s:", __FUNCTION__);
108 int ret;
109
110 if (GapIsLeEnable() == false) {
111 return GAP_ERR_NOT_ENABLE;
112 }
113
114 if (GapLeRolesCheck(GAP_LE_ROLE_OBSERVER | GAP_LE_ROLE_CENTRAL) == false) {
115 ret = GAP_ERR_INVAL_STATE;
116 } else {
117 HciLeSetScanParametersParam hciCmdParam = {
118 .leScanType = param.scanType,
119 .leScanInterval = param.param.scanInterval,
120 .leScanWindow = param.param.scanWindow,
121 .ownAddressType = BTM_GetOwnAddressType(),
122 .scanningFilterPolicy = scanFilterPolity,
123 };
124 ret = HCI_LeSetScanParameters(&hciCmdParam);
125 }
126
127 return ret;
128 }
129
GapLeScanSetParamComplete(const HciLeSetExtendedScanParametersReturnParam * param)130 void GapLeScanSetParamComplete(const HciLeSetExtendedScanParametersReturnParam *param)
131 {
132 if (g_leScanCallback.callback.scanSetParamResult) {
133 g_leScanCallback.callback.scanSetParamResult(param->status, g_leScanCallback.context);
134 }
135 }
136
GapLeSetExAdvReportParam(GapExAdvReportParam * advParam,const HciLeExtendedAdvertisingReport * report)137 static void GapLeSetExAdvReportParam(GapExAdvReportParam *advParam, const HciLeExtendedAdvertisingReport *report)
138 {
139 if (advParam != NULL && report != NULL) {
140 advParam->advertisingSid = report->advertisingSID;
141 advParam->data = report->data;
142 advParam->dataLen = report->dataLength;
143 advParam->periodicAdvInterval = report->periodicAdvertisingInterval;
144 advParam->primaryPhy = report->primaryPHY;
145 advParam->rssi = report->rssi;
146 advParam->secondaryPhy = report->secondaryPHY;
147 advParam->txPower = report->txPower;
148 }
149 }
150
GapCallbackRPAAdvertisingReport(const AdvReportRPAResolveInfo * info,const BtAddr * currentAddr)151 static void GapCallbackRPAAdvertisingReport(const AdvReportRPAResolveInfo *info, const BtAddr *currentAddr)
152 {
153 if (info == NULL) {
154 LOG_WARN("%{public}s: miss info", __FUNCTION__);
155 return;
156 }
157
158 HciLeAdvertisingReport *report = info->report;
159 if (report == NULL || (report->lengthData != 0 && report->data == NULL)) {
160 LOG_WARN("%{public}s: miss report or data", __FUNCTION__);
161 return;
162 }
163 LOG_INFO("%{public}s:" BT_ADDR_FMT " -> " BT_ADDR_FMT,
164 __FUNCTION__,
165 BT_ADDR_FMT_OUTPUT(report->address.raw),
166 BT_ADDR_FMT_OUTPUT(info->addr.addr));
167 if (g_leScanCallback.callback.advertisingReport) {
168 GapAdvReportParam reportParam = {
169 .dataLen = report->lengthData,
170 .data = report->data,
171 .rssi = report->rssi,
172 };
173 g_leScanCallback.callback.advertisingReport(
174 report->eventType, &info->addr, reportParam, currentAddr, g_leScanCallback.context);
175 }
176 }
177
GapCallbackRPAExtendedAdvertisingReport(const AdvReportRPAResolveInfo * info,const BtAddr * currentAddr)178 static void GapCallbackRPAExtendedAdvertisingReport(const AdvReportRPAResolveInfo *info, const BtAddr *currentAddr)
179 {
180 if (info == NULL) {
181 LOG_WARN("%{public}s: miss info.", __FUNCTION__);
182 return;
183 }
184
185 HciLeExtendedAdvertisingReport *report = info->report;
186 GapExAdvReportParam advParam;
187 BtAddr directAddr;
188
189 if (report == NULL || ((report->dataLength != 0) && (report->data == NULL))) {
190 LOG_WARN("%{public}s: miss report or data", __FUNCTION__);
191 return;
192 }
193
194 GapLeSetExAdvReportParam(&advParam, report);
195 advParam.directAddr = &directAddr;
196 GapChangeHCIAddr(&directAddr, &report->directAddress, report->directAddressType);
197
198 LOG_INFO("%{public}s:" BT_ADDR_FMT " -> " BT_ADDR_FMT,
199 __FUNCTION__,
200 BT_ADDR_FMT_OUTPUT(report->address.raw),
201 BT_ADDR_FMT_OUTPUT(info->addr.addr));
202 if (g_leExScanCallback.callback.exAdvertisingReport) {
203 g_leExScanCallback.callback.exAdvertisingReport(
204 report->eventType, &info->addr, advParam, currentAddr, g_leExScanCallback.context);
205 }
206 }
207
GapCallbackRPADirectedAdvertisingReport(const AdvReportRPAResolveInfo * info,const BtAddr * currentAddr)208 static void GapCallbackRPADirectedAdvertisingReport(const AdvReportRPAResolveInfo *info, const BtAddr *currentAddr)
209 {
210 if (info == NULL || info->report == NULL) {
211 LOG_WARN("%{public}s: miss info or report", __FUNCTION__);
212 return;
213 }
214
215 HciLeDirectedAdvertisingReport *report = info->report;
216 BtAddr directAddr;
217 GapChangeHCIAddr(&directAddr, &report->directAddress, report->directAddressType);
218 LOG_INFO("%{public}s:" BT_ADDR_FMT " -> " BT_ADDR_FMT,
219 __FUNCTION__,
220 BT_ADDR_FMT_OUTPUT(report->address.raw),
221 BT_ADDR_FMT_OUTPUT(info->addr.addr));
222 if (g_leExScanCallback.callback.directedAdvertisingReport) {
223 GapDirectedAdvReportParam reportParam = {
224 .directAddr = &directAddr,
225 .rssi = report->rssi,
226 };
227 g_leExScanCallback.callback.directedAdvertisingReport(
228 report->eventType, &info->addr, reportParam, currentAddr, g_leExScanCallback.context);
229 }
230 }
231
GapDoCallbackRPAAdvertisingReport(void * data,const BtAddr * currentAddr)232 void GapDoCallbackRPAAdvertisingReport(void *data, const BtAddr *currentAddr)
233 {
234 AdvReportRPAResolveInfo *info = data;
235 switch (info->reportType) {
236 case ADV_REPORT: {
237 GapCallbackRPAAdvertisingReport(info, currentAddr);
238 break;
239 }
240 case EXTENDED_ADV_REPORT: {
241 GapCallbackRPAExtendedAdvertisingReport(info, currentAddr);
242 break;
243 }
244 case DIRECTED_ADV_REPORT: {
245 GapCallbackRPADirectedAdvertisingReport(info, currentAddr);
246 break;
247 }
248 default:
249 break;
250 }
251 ListRemoveNode(GapGetLeRandomAddressBlock()->reportRPAResolveList, data);
252 }
253
GapRPAResolveProcess(void)254 void GapRPAResolveProcess(void)
255 {
256 int ret;
257
258 ListNode *node = ListGetFirstNode(GapGetLeRandomAddressBlock()->reportRPAResolveList);
259 while (node != 0) {
260 AdvReportRPAResolveInfo *info = ListGetNodeData(node);
261
262 if (info->processing) {
263 break;
264 }
265
266 if (!info->doCallback) {
267 LOG_DEBUG("%{public}s: " BT_ADDR_FMT " start resolve RPA",
268 __FUNCTION__, BT_ADDR_FMT_OUTPUT(info->addr.addr));
269
270 uint8_t addr[BT_ADDRESS_SIZE];
271 (void)memcpy_s(addr, BT_ADDRESS_SIZE, info->addr.addr, BT_ADDRESS_SIZE);
272 const uint8_t *addrPtr = addr;
273 const uint8_t *keyPtr = info->IRKList[info->resolveIndex].irk.key;
274 ret = SMP_AsyncResolveRPA(addrPtr, keyPtr);
275 if (ret != BT_SUCCESS) {
276 info->doCallback = true;
277 GapDoCallbackRPAAdvertisingReport(info, NULL);
278 } else {
279 info->processing = true;
280 }
281 break;
282 }
283 node = ListGetNextNode(node);
284 }
285 }
286
GapResolveRPAResult(uint8_t status,bool result,const uint8_t * addr,const uint8_t * irk)287 void GapResolveRPAResult(uint8_t status, bool result, const uint8_t *addr, const uint8_t *irk)
288 {
289 LOG_INFO("%{public}s: status:%02x, result:%02x", __FUNCTION__, status, result);
290 ListNode *node = ListGetFirstNode(GapGetLeRandomAddressBlock()->reportRPAResolveList);
291 while (node != 0) {
292 AdvReportRPAResolveInfo *info = ListGetNodeData(node);
293 BtAddr currentAddr = info->addr;
294 node = ListGetNextNode(node);
295 if (!info->processing) {
296 continue;
297 }
298
299 info->processing = false;
300 if (status == SMP_PAIR_STATUS_SUCCESS && result == true) {
301 if (memcmp(info->IRKList[info->resolveIndex].irk.key, irk, GAP_IRK_SIZE)) {
302 LOG_ERROR("%{public}s: IRK mismatch", __FUNCTION__);
303 } else {
304 BTM_UpdateCurrentRemoteAddress(&info->IRKList[info->resolveIndex].addr, &info->addr);
305 (void)memcpy_s(&info->addr, sizeof(BtAddr), &info->IRKList[info->resolveIndex].addr, sizeof(BtAddr));
306 }
307 info->doCallback = true;
308 } else {
309 info->resolveIndex++;
310 if (info->resolveIndex == info->listCount) {
311 info->doCallback = true;
312 }
313 }
314 if (info->doCallback) {
315 GapDoCallbackRPAAdvertisingReport(info, result ? ¤tAddr : NULL);
316 }
317 break;
318 }
319
320 GapRPAResolveProcess();
321 }
322
GapLeAllocAdvReportRPAResolveInfo(BtAddr addr,AdvReportType type,const void * advReport)323 static AdvReportRPAResolveInfo *GapLeAllocAdvReportRPAResolveInfo(
324 BtAddr addr, AdvReportType type, const void *advReport)
325 {
326 AdvReportRPAResolveInfo *info = MEM_MALLOC.alloc(sizeof(AdvReportRPAResolveInfo));
327 void *report = NULL;
328 uint8_t *advData = NULL;
329
330 if (type == ADV_REPORT) {
331 advData = MEM_MALLOC.alloc(((const HciLeAdvertisingReport *)advReport)->lengthData);
332 if (advData != NULL) {
333 (void)memcpy_s(advData,
334 ((const HciLeAdvertisingReport *)advReport)->lengthData,
335 ((const HciLeAdvertisingReport *)advReport)->data,
336 ((const HciLeAdvertisingReport *)advReport)->lengthData);
337 }
338 report = MEM_MALLOC.alloc(sizeof(HciLeAdvertisingReport));
339 if (report != NULL) {
340 (void)memcpy_s(report, sizeof(HciLeAdvertisingReport), advReport, sizeof(HciLeAdvertisingReport));
341 ((HciLeAdvertisingReport *)report)->data = advData;
342 }
343 } else if (type == EXTENDED_ADV_REPORT) {
344 advData = MEM_MALLOC.alloc(((const HciLeExtendedAdvertisingReport *)advReport)->dataLength);
345 if (advData != NULL) {
346 (void)memcpy_s(advData,
347 ((const HciLeExtendedAdvertisingReport *)advReport)->dataLength,
348 ((const HciLeExtendedAdvertisingReport *)advReport)->data,
349 ((const HciLeExtendedAdvertisingReport *)advReport)->dataLength);
350 }
351 report = MEM_MALLOC.alloc(sizeof(HciLeExtendedAdvertisingReport));
352 if (report != NULL) {
353 (void)memcpy_s(
354 report, sizeof(HciLeExtendedAdvertisingReport), advReport, sizeof(HciLeExtendedAdvertisingReport));
355 ((HciLeExtendedAdvertisingReport *)report)->data = advData;
356 }
357 } else if (type == DIRECTED_ADV_REPORT) {
358 report = MEM_MALLOC.alloc(sizeof(HciLeDirectedAdvertisingReport));
359 if (report != NULL) {
360 (void)memcpy_s(
361 report, sizeof(HciLeDirectedAdvertisingReport), advReport, sizeof(HciLeDirectedAdvertisingReport));
362 }
363 }
364
365 if (info != NULL) {
366 info->report = report;
367 info->reportType = type;
368 info->resolveIndex = 0;
369 info->processing = false;
370 info->doCallback = false;
371 (void)memcpy_s(&info->addr, sizeof(BtAddr), &addr, sizeof(BtAddr));
372 }
373
374 return info;
375 }
376
GapTryChangeAddressForIdentityAddress(BtAddr * addr)377 static bool GapTryChangeAddressForIdentityAddress(BtAddr *addr)
378 {
379 BtAddr pairedAddr = {0};
380 int ret = BTM_GetPairdAddressFromRemoteIdentityAddress(addr, &pairedAddr);
381 if (ret == BT_SUCCESS) {
382 LOG_INFO("%{public}s:" BT_ADDR_FMT " -> " BT_ADDR_FMT,
383 __FUNCTION__,
384 BT_ADDR_FMT_OUTPUT(addr->addr),
385 BT_ADDR_FMT_OUTPUT(pairedAddr.addr));
386 *addr = pairedAddr;
387 return true;
388 }
389 return false;
390 }
391
GapOnLeAdvertisingReportEventProcessOnce(const HciLeAdvertisingReport * report)392 static void GapOnLeAdvertisingReportEventProcessOnce(const HciLeAdvertisingReport *report)
393 {
394 BtAddr addr;
395 GapChangeHCIAddr(&addr, &report->address, report->addressType);
396 BtAddr currentAddr = addr;
397 uint8_t advType = report->eventType;
398 uint8_t rssi = report->rssi;
399 uint8_t dataLen = report->lengthData;
400 uint8_t *data = report->data;
401
402 if (GapAddrIsResolvablePrivateAddress(&addr)) {
403 BtmIdentityResolvingKey *deviceIRKList = NULL;
404 uint16_t listCount = 0;
405 int ret = BTM_GetAllRemoteIdentityResolvingKey(&deviceIRKList, &listCount);
406 if (ret == BT_SUCCESS && listCount != 0) {
407 AdvReportRPAResolveInfo *info = GapLeAllocAdvReportRPAResolveInfo(addr, ADV_REPORT, report);
408 if (info != NULL) {
409 info->IRKList = deviceIRKList;
410 info->listCount = listCount;
411 ListAddLast(GapGetLeRandomAddressBlock()->reportRPAResolveList, info);
412 GapRPAResolveProcess();
413 return;
414 }
415 }
416 if (deviceIRKList != NULL) {
417 MEM_MALLOC.free(deviceIRKList);
418 }
419 } else if (GapAddrIsIdentityAddress(&addr)) {
420 GapTryChangeAddressForIdentityAddress(&addr);
421 } else if (GapAddrIsStaticAddress(&addr) || GapAddrIsPublicAddress(&addr)) {
422 if (GapTryChangeAddressForIdentityAddress(&addr)) {
423 BTM_UpdateCurrentRemoteAddress(&addr, ¤tAddr);
424 }
425 }
426
427 LOG_INFO("%{public}s:" BT_ADDR_FMT " type=%hhu", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr), addr.type);
428 if (g_leScanCallback.callback.advertisingReport) {
429 GapAdvReportParam reportParam = {
430 .dataLen = dataLen,
431 .data = data,
432 .rssi = rssi,
433 };
434 g_leScanCallback.callback.advertisingReport(advType, &addr, reportParam, NULL, g_leScanCallback.context);
435 }
436 }
437
GapOnLeAdvertisingReportEvent(const HciLeAdvertisingReportEventParam * eventParam)438 void GapOnLeAdvertisingReportEvent(const HciLeAdvertisingReportEventParam *eventParam)
439 {
440 for (uint8_t i = 0; i < eventParam->numReports; i++) {
441 GapOnLeAdvertisingReportEventProcessOnce(&eventParam->reports[i]);
442 }
443 }
444
GAP_LeScanSetEnable(uint8_t scanEnable,uint8_t filterDuplicates)445 int GAP_LeScanSetEnable(uint8_t scanEnable, uint8_t filterDuplicates)
446 {
447 LOG_INFO("%{public}s:", __FUNCTION__);
448 int ret;
449
450 if (GapIsLeEnable() == false) {
451 return GAP_ERR_NOT_ENABLE;
452 }
453
454 if (GapLeRolesCheck(GAP_LE_ROLE_OBSERVER | GAP_LE_ROLE_CENTRAL) == false) {
455 ret = GAP_ERR_INVAL_STATE;
456 } else {
457 HciLeSetScanEnableParam hciCmdParam = {
458 .leScanEnable = scanEnable,
459 .filterDuplicates = filterDuplicates,
460 };
461 ret = HCI_LeSetScanEnable(&hciCmdParam);
462 }
463
464 return ret;
465 }
466
GapLeScanSetEnableComplete(const HciLeSetScanEnableReturnParam * param)467 void GapLeScanSetEnableComplete(const HciLeSetScanEnableReturnParam *param)
468 {
469 if (g_leScanCallback.callback.scanSetEnableResult) {
470 g_leScanCallback.callback.scanSetEnableResult(param->status, g_leScanCallback.context);
471 }
472 }
473
GAP_RegisterExScanCallback(const GapExScanCallback * callback,void * context)474 int GAP_RegisterExScanCallback(const GapExScanCallback *callback, void *context)
475 {
476 LOG_INFO("%{public}s:%{public}s", __FUNCTION__, callback ? "register" : "NULL");
477 if (callback == NULL) {
478 (void)memset_s(&g_leExScanCallback.callback,
479 sizeof(g_leExScanCallback.callback),
480 0x00,
481 sizeof(g_leExScanCallback.callback));
482 } else {
483 g_leExScanCallback.callback = *callback;
484 }
485 g_leExScanCallback.context = context;
486 return GAP_SUCCESS;
487 }
488
GAP_DeregisterExScanCallback(void)489 int GAP_DeregisterExScanCallback(void)
490 {
491 (void)memset_s(
492 &g_leExScanCallback.callback, sizeof(g_leExScanCallback.callback), 0x00, sizeof(g_leExScanCallback.callback));
493 g_leExScanCallback.context = NULL;
494 return GAP_SUCCESS;
495 }
496
497 NO_SANITIZE("cfi")
GapOnLeExtendedAdvertisingReportEventProcessOnce(const HciLeExtendedAdvertisingReport * report)498 static void GapOnLeExtendedAdvertisingReportEventProcessOnce(const HciLeExtendedAdvertisingReport *report)
499 {
500 BtAddr addr;
501 GapChangeHCIAddr(&addr, &report->address, report->addressType);
502 BtAddr currentAddr = addr;
503 uint8_t advType = report->eventType;
504 GapExAdvReportParam advParam;
505 BtAddr directAddr;
506 GapLeSetExAdvReportParam(&advParam, report);
507 GapChangeHCIAddr(&directAddr, &report->directAddress, report->directAddressType);
508 advParam.directAddr = &directAddr;
509
510 if (GapAddrIsResolvablePrivateAddress(&addr)) {
511 BtmIdentityResolvingKey *deviceIRKList = NULL;
512 uint16_t listCount = 0;
513 int ret = BTM_GetAllRemoteIdentityResolvingKey(&deviceIRKList, &listCount);
514 if (ret == BT_SUCCESS && listCount != 0) {
515 AdvReportRPAResolveInfo *info = GapLeAllocAdvReportRPAResolveInfo(addr, EXTENDED_ADV_REPORT, report);
516 if (info != NULL) {
517 info->IRKList = deviceIRKList;
518 info->listCount = listCount;
519 ListAddLast(GapGetLeRandomAddressBlock()->reportRPAResolveList, info);
520 GapRPAResolveProcess();
521 return;
522 }
523 }
524 if (deviceIRKList != NULL) {
525 MEM_MALLOC.free(deviceIRKList);
526 }
527 } else if (GapAddrIsIdentityAddress(&addr)) {
528 GapTryChangeAddressForIdentityAddress(&addr);
529 } else if (GapAddrIsStaticAddress(&addr) || GapAddrIsPublicAddress(&addr)) {
530 if (GapTryChangeAddressForIdentityAddress(&addr)) {
531 BTM_UpdateCurrentRemoteAddress(&addr, ¤tAddr);
532 }
533 }
534
535 LOG_INFO("%{public}s:" BT_ADDR_FMT " type=%hhu", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr), addr.type);
536 if (g_leExScanCallback.callback.exAdvertisingReport) {
537 g_leExScanCallback.callback.exAdvertisingReport(advType, &addr, advParam, NULL, g_leExScanCallback.context);
538 }
539 }
540
GapOnLeExtendedAdvertisingReportEvent(const HciLeExtendedAdvertisingReportEventParam * eventParam)541 void GapOnLeExtendedAdvertisingReportEvent(const HciLeExtendedAdvertisingReportEventParam *eventParam)
542 {
543 for (uint8_t i = 0; i < eventParam->numReports; i++) {
544 GapOnLeExtendedAdvertisingReportEventProcessOnce(&eventParam->reports[i]);
545 }
546 }
547
GapOnLeDirectedAdvertisingReportProcessOnce(const HciLeDirectedAdvertisingReport * report)548 static void GapOnLeDirectedAdvertisingReportProcessOnce(const HciLeDirectedAdvertisingReport *report)
549 {
550 BtAddr addr;
551 GapChangeHCIAddr(&addr, &report->address, report->addressType);
552 BtAddr currentAddr = addr;
553 uint8_t advType = report->eventType;
554 BtAddr directAddr;
555 GapChangeHCIAddr(&directAddr, &report->directAddress, report->directAddressType);
556 int8_t rssi = report->rssi;
557
558 if (GapAddrIsResolvablePrivateAddress(&addr)) {
559 BtmIdentityResolvingKey *deviceIRKList = NULL;
560 uint16_t listCount = 0;
561 int ret = BTM_GetAllRemoteIdentityResolvingKey(&deviceIRKList, &listCount);
562 if (ret == BT_SUCCESS && listCount != 0) {
563 AdvReportRPAResolveInfo *info = GapLeAllocAdvReportRPAResolveInfo(addr, DIRECTED_ADV_REPORT, report);
564 if (info != NULL) {
565 info->IRKList = deviceIRKList;
566 info->listCount = listCount;
567 ListAddLast(GapGetLeRandomAddressBlock()->reportRPAResolveList, info);
568 GapRPAResolveProcess();
569 return;
570 }
571 }
572 if (deviceIRKList != NULL) {
573 MEM_MALLOC.free(deviceIRKList);
574 }
575 } else if (GapAddrIsIdentityAddress(&addr)) {
576 GapTryChangeAddressForIdentityAddress(&addr);
577 } else if (GapAddrIsStaticAddress(&addr) || GapAddrIsPublicAddress(&addr)) {
578 if (GapTryChangeAddressForIdentityAddress(&addr)) {
579 BTM_UpdateCurrentRemoteAddress(&addr, ¤tAddr);
580 }
581 }
582
583 LOG_INFO("%{public}s:" BT_ADDR_FMT " type=%hhu", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr), addr.type);
584 if (g_leExScanCallback.callback.directedAdvertisingReport) {
585 GapDirectedAdvReportParam reportParam = {
586 .directAddr = &directAddr,
587 .rssi = rssi,
588 };
589 g_leExScanCallback.callback.directedAdvertisingReport(
590 advType, &addr, reportParam, NULL, g_leExScanCallback.context);
591 }
592 }
593
GapOnLeDirectedAdvertisingReport(const HciLeDirectedAdvertisingReportEventParam * eventParam)594 void GapOnLeDirectedAdvertisingReport(const HciLeDirectedAdvertisingReportEventParam *eventParam)
595 {
596 for (uint8_t i = 0; i < eventParam->numReports; i++) {
597 GapOnLeDirectedAdvertisingReportProcessOnce(&eventParam->reports[i]);
598 }
599 }
600
GapOnLeScanTimeoutEvent(const void * eventParam)601 void GapOnLeScanTimeoutEvent(const void *eventParam)
602 {
603 if (g_leExScanCallback.callback.scanTimeoutEvent) {
604 g_leExScanCallback.callback.scanTimeoutEvent(g_leExScanCallback.context);
605 }
606 }
607
GapLeSetExtendedScanParameters(uint8_t ownAddrType,uint8_t scanFilterPolity,uint8_t scanPhys,const GapLeScanParam param[])608 static int GapLeSetExtendedScanParameters(
609 uint8_t ownAddrType, uint8_t scanFilterPolity, uint8_t scanPhys, const GapLeScanParam param[])
610 {
611 int ret;
612 HciLeSetExtendedScanParametersParam hciCmdParam;
613 hciCmdParam.ownAddressType = ownAddrType;
614 hciCmdParam.ScanningFilterPolicy = scanFilterPolity;
615 hciCmdParam.ScanningPHYs = scanPhys;
616
617 hciCmdParam.sets = MEM_MALLOC.alloc(EXTENDED_SCAN_PHY_MAX_NUM * sizeof(HciLeExtendedScanParametersSet));
618
619 if (hciCmdParam.sets) {
620 for (uint8_t i = 0, jj = 0; i < EXTENDED_SCAN_PHY_MAX_NUM; i++) {
621 if ((scanPhys >> i) & 0x01) {
622 hciCmdParam.sets[jj].scanInterval = param[jj].param.scanInterval;
623 hciCmdParam.sets[jj].scanWindow = param[jj].param.scanWindow;
624 hciCmdParam.sets[jj].scanType = param[jj].scanType;
625 jj++;
626 }
627 }
628
629 ret = HCI_LeSetExtendedScanParameters(&hciCmdParam);
630 MEM_MALLOC.free(hciCmdParam.sets);
631 } else {
632 ret = GAP_ERR_OUT_OF_RES;
633 }
634
635 return ret;
636 }
637
GapLeSetExtendedScanParametersComplete(const HciLeSetExtendedScanParametersReturnParam * param)638 NO_SANITIZE("cfi") void GapLeSetExtendedScanParametersComplete(const HciLeSetExtendedScanParametersReturnParam *param)
639 {
640 if (g_leExScanCallback.callback.scanExSetParamResult) {
641 g_leExScanCallback.callback.scanExSetParamResult(param->status, g_leExScanCallback.context);
642 }
643 }
644
GAP_LeExScanSetParam(uint8_t scanFilterPolity,uint8_t scanPhys,const GapLeScanParam param[])645 int GAP_LeExScanSetParam(uint8_t scanFilterPolity, uint8_t scanPhys, const GapLeScanParam param[])
646 {
647 LOG_INFO("%{public}s:", __FUNCTION__);
648 int ret;
649
650 if (GapIsLeEnable() == false) {
651 return GAP_ERR_NOT_ENABLE;
652 }
653
654 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_CENTRAL) == false) {
655 ret = GAP_ERR_INVAL_STATE;
656 } else {
657 ret = GapLeSetExtendedScanParameters(BTM_GetOwnAddressType(), scanFilterPolity, scanPhys, param);
658 }
659
660 return ret;
661 }
662
GapLeSetExtendedScanEnable(uint8_t scanEnable,uint8_t filterDuplicates,uint16_t duration,uint16_t period)663 static int GapLeSetExtendedScanEnable(uint8_t scanEnable, uint8_t filterDuplicates, uint16_t duration, uint16_t period)
664 {
665 HciLeSetExtendedScanEnableParam hciCmdParam = {
666 .duration = duration,
667 .enable = scanEnable,
668 .filterDuplicates = filterDuplicates,
669 .period = period,
670 };
671
672 return HCI_LeSetExtendedScanEnable(&hciCmdParam);
673 }
674
GapLeSetExtendedScanEnableComplete(const HciLeSetExtendedScanEnableReturnParam * param)675 NO_SANITIZE("cfi") void GapLeSetExtendedScanEnableComplete(const HciLeSetExtendedScanEnableReturnParam *param)
676 {
677 if (g_leExScanCallback.callback.scanExSetEnableResult) {
678 g_leExScanCallback.callback.scanExSetEnableResult(param->status, g_leExScanCallback.context);
679 }
680 }
681
GAP_LeExScanSetEnable(uint8_t scanEnable,uint8_t filterDuplicates,uint16_t duration,uint16_t period)682 int GAP_LeExScanSetEnable(uint8_t scanEnable, uint8_t filterDuplicates, uint16_t duration, uint16_t period)
683 {
684 LOG_INFO("%{public}s:", __FUNCTION__);
685 int ret;
686
687 if (GapIsLeEnable() == false) {
688 return GAP_ERR_NOT_ENABLE;
689 }
690
691 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_CENTRAL) == false) {
692 ret = GAP_ERR_INVAL_STATE;
693 } else {
694 ret = GapLeSetExtendedScanEnable(scanEnable, filterDuplicates, duration, period);
695 }
696
697 return ret;
698 }
699