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", __FUNCTION__, BT_ADDR_FMT_OUTPUT(info->addr.addr));
268
269 uint8_t addr[BT_ADDRESS_SIZE];
270 (void)memcpy_s(addr, BT_ADDRESS_SIZE, info->addr.addr, BT_ADDRESS_SIZE);
271 const uint8_t *addrPtr = addr;
272 const uint8_t *keyPtr = info->IRKList[info->resolveIndex].irk.key;
273 ret = SMP_AsyncResolveRPA(addrPtr, keyPtr);
274 if (ret != BT_NO_ERROR) {
275 info->doCallback = true;
276 GapDoCallbackRPAAdvertisingReport(info, NULL);
277 } else {
278 info->processing = true;
279 }
280 break;
281 }
282 node = ListGetNextNode(node);
283 }
284 }
285
GapResolveRPAResult(uint8_t status,bool result,const uint8_t * addr,const uint8_t * irk)286 void GapResolveRPAResult(uint8_t status, bool result, const uint8_t *addr, const uint8_t *irk)
287 {
288 LOG_INFO("%{public}s: status:%02x, result:%02x", __FUNCTION__, status, result);
289 ListNode *node = ListGetFirstNode(GapGetLeRandomAddressBlock()->reportRPAResolveList);
290 while (node != 0) {
291 AdvReportRPAResolveInfo *info = ListGetNodeData(node);
292 BtAddr currentAddr = info->addr;
293 node = ListGetNextNode(node);
294 if (!info->processing) {
295 continue;
296 }
297
298 info->processing = false;
299 if (status == SMP_PAIR_STATUS_SUCCESS && result == true) {
300 if (memcmp(info->IRKList[info->resolveIndex].irk.key, irk, GAP_IRK_SIZE)) {
301 LOG_ERROR("%{public}s: IRK mismatch", __FUNCTION__);
302 } else {
303 BTM_UpdateCurrentRemoteAddress(&info->IRKList[info->resolveIndex].addr, &info->addr);
304 (void)memcpy_s(&info->addr, sizeof(BtAddr), &info->IRKList[info->resolveIndex].addr, sizeof(BtAddr));
305 }
306 info->doCallback = true;
307 } else {
308 info->resolveIndex++;
309 if (info->resolveIndex == info->listCount) {
310 info->doCallback = true;
311 }
312 }
313 if (info->doCallback) {
314 GapDoCallbackRPAAdvertisingReport(info, result ? ¤tAddr : NULL);
315 }
316 break;
317 }
318
319 GapRPAResolveProcess();
320 }
321
GapLeAllocAdvReportRPAResolveInfo(BtAddr addr,AdvReportType type,const void * advReport)322 static AdvReportRPAResolveInfo *GapLeAllocAdvReportRPAResolveInfo(
323 BtAddr addr, AdvReportType type, const void *advReport)
324 {
325 AdvReportRPAResolveInfo *info = MEM_MALLOC.alloc(sizeof(AdvReportRPAResolveInfo));
326 void *report = NULL;
327 uint8_t *advData = NULL;
328
329 if (type == ADV_REPORT) {
330 advData = MEM_MALLOC.alloc(((const HciLeAdvertisingReport *)advReport)->lengthData);
331 if (advData != NULL) {
332 (void)memcpy_s(advData,
333 ((const HciLeAdvertisingReport *)advReport)->lengthData,
334 ((const HciLeAdvertisingReport *)advReport)->data,
335 ((const HciLeAdvertisingReport *)advReport)->lengthData);
336 }
337 report = MEM_MALLOC.alloc(sizeof(HciLeAdvertisingReport));
338 if (report != NULL) {
339 (void)memcpy_s(report, sizeof(HciLeAdvertisingReport), advReport, sizeof(HciLeAdvertisingReport));
340 ((HciLeAdvertisingReport *)report)->data = advData;
341 }
342 } else if (type == EXTENDED_ADV_REPORT) {
343 advData = MEM_MALLOC.alloc(((const HciLeExtendedAdvertisingReport *)advReport)->dataLength);
344 if (advData != NULL) {
345 (void)memcpy_s(advData,
346 ((const HciLeExtendedAdvertisingReport *)advReport)->dataLength,
347 ((const HciLeExtendedAdvertisingReport *)advReport)->data,
348 ((const HciLeExtendedAdvertisingReport *)advReport)->dataLength);
349 }
350 report = MEM_MALLOC.alloc(sizeof(HciLeExtendedAdvertisingReport));
351 if (report != NULL) {
352 (void)memcpy_s(
353 report, sizeof(HciLeExtendedAdvertisingReport), advReport, sizeof(HciLeExtendedAdvertisingReport));
354 ((HciLeExtendedAdvertisingReport *)report)->data = advData;
355 }
356 } else if (type == DIRECTED_ADV_REPORT) {
357 report = MEM_MALLOC.alloc(sizeof(HciLeDirectedAdvertisingReport));
358 if (report != NULL) {
359 (void)memcpy_s(
360 report, sizeof(HciLeDirectedAdvertisingReport), advReport, sizeof(HciLeDirectedAdvertisingReport));
361 }
362 }
363
364 if (info != NULL) {
365 info->report = report;
366 info->reportType = type;
367 info->resolveIndex = 0;
368 info->processing = false;
369 info->doCallback = false;
370 (void)memcpy_s(&info->addr, sizeof(BtAddr), &addr, sizeof(BtAddr));
371 }
372
373 return info;
374 }
375
GapTryChangeAddressForIdentityAddress(BtAddr * addr)376 static bool GapTryChangeAddressForIdentityAddress(BtAddr *addr)
377 {
378 BtAddr pairedAddr = {0};
379 int ret = BTM_GetPairdAddressFromRemoteIdentityAddress(addr, &pairedAddr);
380 if (ret == BT_NO_ERROR) {
381 LOG_INFO("%{public}s:" BT_ADDR_FMT " -> " BT_ADDR_FMT,
382 __FUNCTION__,
383 BT_ADDR_FMT_OUTPUT(addr->addr),
384 BT_ADDR_FMT_OUTPUT(pairedAddr.addr));
385 *addr = pairedAddr;
386 return true;
387 }
388 return false;
389 }
390
GapOnLeAdvertisingReportEventProcessOnce(const HciLeAdvertisingReport * report)391 static void GapOnLeAdvertisingReportEventProcessOnce(const HciLeAdvertisingReport *report)
392 {
393 BtAddr addr;
394 GapChangeHCIAddr(&addr, &report->address, report->addressType);
395 BtAddr currentAddr = addr;
396 uint8_t advType = report->eventType;
397 uint8_t rssi = report->rssi;
398 uint8_t dataLen = report->lengthData;
399 uint8_t *data = report->data;
400
401 if (GapAddrIsResolvablePrivateAddress(&addr)) {
402 BtmIdentityResolvingKey *deviceIRKList = NULL;
403 uint16_t listCount = 0;
404 int ret = BTM_GetAllRemoteIdentityResolvingKey(&deviceIRKList, &listCount);
405 if (ret == BT_NO_ERROR && listCount != 0) {
406 AdvReportRPAResolveInfo *info = GapLeAllocAdvReportRPAResolveInfo(addr, ADV_REPORT, report);
407 if (info != NULL) {
408 info->IRKList = deviceIRKList;
409 info->listCount = listCount;
410 ListAddLast(GapGetLeRandomAddressBlock()->reportRPAResolveList, info);
411 GapRPAResolveProcess();
412 return;
413 }
414 }
415 if (deviceIRKList != NULL) {
416 MEM_MALLOC.free(deviceIRKList);
417 }
418 } else if (GapAddrIsIdentityAddress(&addr)) {
419 GapTryChangeAddressForIdentityAddress(&addr);
420 } else if (GapAddrIsStaticAddress(&addr) || GapAddrIsPublicAddress(&addr)) {
421 if (GapTryChangeAddressForIdentityAddress(&addr)) {
422 BTM_UpdateCurrentRemoteAddress(&addr, ¤tAddr);
423 }
424 }
425
426 LOG_INFO("%{public}s:" BT_ADDR_FMT " type=%hhu", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr), addr.type);
427 if (g_leScanCallback.callback.advertisingReport) {
428 GapAdvReportParam reportParam = {
429 .dataLen = dataLen,
430 .data = data,
431 .rssi = rssi,
432 };
433 g_leScanCallback.callback.advertisingReport(advType, &addr, reportParam, NULL, g_leScanCallback.context);
434 }
435 }
436
GapOnLeAdvertisingReportEvent(const HciLeAdvertisingReportEventParam * eventParam)437 void GapOnLeAdvertisingReportEvent(const HciLeAdvertisingReportEventParam *eventParam)
438 {
439 for (uint8_t i = 0; i < eventParam->numReports; i++) {
440 GapOnLeAdvertisingReportEventProcessOnce(&eventParam->reports[i]);
441 }
442 }
443
GAP_LeScanSetEnable(uint8_t scanEnable,uint8_t filterDuplicates)444 int GAP_LeScanSetEnable(uint8_t scanEnable, uint8_t filterDuplicates)
445 {
446 LOG_INFO("%{public}s:", __FUNCTION__);
447 int ret;
448
449 if (GapIsLeEnable() == false) {
450 return GAP_ERR_NOT_ENABLE;
451 }
452
453 if (GapLeRolesCheck(GAP_LE_ROLE_OBSERVER | GAP_LE_ROLE_CENTRAL) == false) {
454 ret = GAP_ERR_INVAL_STATE;
455 } else {
456 HciLeSetScanEnableParam hciCmdParam = {
457 .leScanEnable = scanEnable,
458 .filterDuplicates = filterDuplicates,
459 };
460 ret = HCI_LeSetScanEnable(&hciCmdParam);
461 }
462
463 return ret;
464 }
465
GapLeScanSetEnableComplete(const HciLeSetScanEnableReturnParam * param)466 void GapLeScanSetEnableComplete(const HciLeSetScanEnableReturnParam *param)
467 {
468 if (g_leScanCallback.callback.scanSetEnableResult) {
469 g_leScanCallback.callback.scanSetEnableResult(param->status, g_leScanCallback.context);
470 }
471 }
472
GAP_RegisterExScanCallback(const GapExScanCallback * callback,void * context)473 int GAP_RegisterExScanCallback(const GapExScanCallback *callback, void *context)
474 {
475 LOG_INFO("%{public}s:%{public}s", __FUNCTION__, callback ? "register" : "NULL");
476 if (callback == NULL) {
477 (void)memset_s(&g_leExScanCallback.callback,
478 sizeof(g_leExScanCallback.callback),
479 0x00,
480 sizeof(g_leExScanCallback.callback));
481 } else {
482 g_leExScanCallback.callback = *callback;
483 }
484 g_leExScanCallback.context = context;
485 return GAP_SUCCESS;
486 }
487
GAP_DeregisterExScanCallback(void)488 int GAP_DeregisterExScanCallback(void)
489 {
490 (void)memset_s(
491 &g_leExScanCallback.callback, sizeof(g_leExScanCallback.callback), 0x00, sizeof(g_leExScanCallback.callback));
492 g_leExScanCallback.context = NULL;
493 return GAP_SUCCESS;
494 }
495
GapOnLeExtendedAdvertisingReportEventProcessOnce(const HciLeExtendedAdvertisingReport * report)496 static void GapOnLeExtendedAdvertisingReportEventProcessOnce(const HciLeExtendedAdvertisingReport *report)
497 {
498 BtAddr addr;
499 GapChangeHCIAddr(&addr, &report->address, report->addressType);
500 BtAddr currentAddr = addr;
501 uint8_t advType = report->eventType;
502 GapExAdvReportParam advParam;
503 BtAddr directAddr;
504 GapLeSetExAdvReportParam(&advParam, report);
505 GapChangeHCIAddr(&directAddr, &report->directAddress, report->directAddressType);
506 advParam.directAddr = &directAddr;
507
508 if (GapAddrIsResolvablePrivateAddress(&addr)) {
509 BtmIdentityResolvingKey *deviceIRKList = NULL;
510 uint16_t listCount = 0;
511 int ret = BTM_GetAllRemoteIdentityResolvingKey(&deviceIRKList, &listCount);
512 if (ret == BT_NO_ERROR && listCount != 0) {
513 AdvReportRPAResolveInfo *info = GapLeAllocAdvReportRPAResolveInfo(addr, EXTENDED_ADV_REPORT, report);
514 if (info != NULL) {
515 info->IRKList = deviceIRKList;
516 info->listCount = listCount;
517 ListAddLast(GapGetLeRandomAddressBlock()->reportRPAResolveList, info);
518 GapRPAResolveProcess();
519 return;
520 }
521 }
522 if (deviceIRKList != NULL) {
523 MEM_MALLOC.free(deviceIRKList);
524 }
525 } else if (GapAddrIsIdentityAddress(&addr)) {
526 GapTryChangeAddressForIdentityAddress(&addr);
527 } else if (GapAddrIsStaticAddress(&addr) || GapAddrIsPublicAddress(&addr)) {
528 if (GapTryChangeAddressForIdentityAddress(&addr)) {
529 BTM_UpdateCurrentRemoteAddress(&addr, ¤tAddr);
530 }
531 }
532
533 LOG_INFO("%{public}s:" BT_ADDR_FMT " type=%hhu", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr), addr.type);
534 if (g_leExScanCallback.callback.exAdvertisingReport) {
535 g_leExScanCallback.callback.exAdvertisingReport(advType, &addr, advParam, NULL, g_leExScanCallback.context);
536 }
537 }
538
GapOnLeExtendedAdvertisingReportEvent(const HciLeExtendedAdvertisingReportEventParam * eventParam)539 void GapOnLeExtendedAdvertisingReportEvent(const HciLeExtendedAdvertisingReportEventParam *eventParam)
540 {
541 for (uint8_t i = 0; i < eventParam->numReports; i++) {
542 GapOnLeExtendedAdvertisingReportEventProcessOnce(&eventParam->reports[i]);
543 }
544 }
545
GapOnLeDirectedAdvertisingReportProcessOnce(const HciLeDirectedAdvertisingReport * report)546 static void GapOnLeDirectedAdvertisingReportProcessOnce(const HciLeDirectedAdvertisingReport *report)
547 {
548 BtAddr addr;
549 GapChangeHCIAddr(&addr, &report->address, report->addressType);
550 BtAddr currentAddr = addr;
551 uint8_t advType = report->eventType;
552 BtAddr directAddr;
553 GapChangeHCIAddr(&directAddr, &report->directAddress, report->directAddressType);
554 int8_t rssi = report->rssi;
555
556 if (GapAddrIsResolvablePrivateAddress(&addr)) {
557 BtmIdentityResolvingKey *deviceIRKList = NULL;
558 uint16_t listCount = 0;
559 int ret = BTM_GetAllRemoteIdentityResolvingKey(&deviceIRKList, &listCount);
560 if (ret == BT_NO_ERROR && listCount != 0) {
561 AdvReportRPAResolveInfo *info = GapLeAllocAdvReportRPAResolveInfo(addr, DIRECTED_ADV_REPORT, report);
562 if (info != NULL) {
563 info->IRKList = deviceIRKList;
564 info->listCount = listCount;
565 ListAddLast(GapGetLeRandomAddressBlock()->reportRPAResolveList, info);
566 GapRPAResolveProcess();
567 return;
568 }
569 }
570 if (deviceIRKList != NULL) {
571 MEM_MALLOC.free(deviceIRKList);
572 }
573 } else if (GapAddrIsIdentityAddress(&addr)) {
574 GapTryChangeAddressForIdentityAddress(&addr);
575 } else if (GapAddrIsStaticAddress(&addr) || GapAddrIsPublicAddress(&addr)) {
576 if (GapTryChangeAddressForIdentityAddress(&addr)) {
577 BTM_UpdateCurrentRemoteAddress(&addr, ¤tAddr);
578 }
579 }
580
581 LOG_INFO("%{public}s:" BT_ADDR_FMT " type=%hhu", __FUNCTION__, BT_ADDR_FMT_OUTPUT(addr.addr), addr.type);
582 if (g_leExScanCallback.callback.directedAdvertisingReport) {
583 GapDirectedAdvReportParam reportParam = {
584 .directAddr = &directAddr,
585 .rssi = rssi,
586 };
587 g_leExScanCallback.callback.directedAdvertisingReport(
588 advType, &addr, reportParam, NULL, g_leExScanCallback.context);
589 }
590 }
591
GapOnLeDirectedAdvertisingReport(const HciLeDirectedAdvertisingReportEventParam * eventParam)592 void GapOnLeDirectedAdvertisingReport(const HciLeDirectedAdvertisingReportEventParam *eventParam)
593 {
594 for (uint8_t i = 0; i < eventParam->numReports; i++) {
595 GapOnLeDirectedAdvertisingReportProcessOnce(&eventParam->reports[i]);
596 }
597 }
598
GapOnLeScanTimeoutEvent(const void * eventParam)599 void GapOnLeScanTimeoutEvent(const void *eventParam)
600 {
601 if (g_leExScanCallback.callback.scanTimeoutEvent) {
602 g_leExScanCallback.callback.scanTimeoutEvent(g_leExScanCallback.context);
603 }
604 }
605
GapLeSetExtendedScanParameters(uint8_t ownAddrType,uint8_t scanFilterPolity,uint8_t scanPhys,const GapLeScanParam param[])606 static int GapLeSetExtendedScanParameters(
607 uint8_t ownAddrType, uint8_t scanFilterPolity, uint8_t scanPhys, const GapLeScanParam param[])
608 {
609 int ret;
610 HciLeSetExtendedScanParametersParam hciCmdParam;
611 hciCmdParam.ownAddressType = ownAddrType;
612 hciCmdParam.ScanningFilterPolicy = scanFilterPolity;
613 hciCmdParam.ScanningPHYs = scanPhys;
614
615 hciCmdParam.sets = MEM_MALLOC.alloc(EXTENDED_SCAN_PHY_MAX_NUM * sizeof(HciLeExtendedScanParametersSet));
616
617 if (hciCmdParam.sets) {
618 for (uint8_t i = 0, jj = 0; i < EXTENDED_SCAN_PHY_MAX_NUM; i++) {
619 if ((scanPhys >> i) & 0x01) {
620 hciCmdParam.sets[jj].scanInterval = param[jj].param.scanInterval;
621 hciCmdParam.sets[jj].scanWindow = param[jj].param.scanWindow;
622 hciCmdParam.sets[jj].scanType = param[jj].scanType;
623 jj++;
624 }
625 }
626
627 ret = HCI_LeSetExtendedScanParameters(&hciCmdParam);
628 MEM_MALLOC.free(hciCmdParam.sets);
629 } else {
630 ret = GAP_ERR_OUT_OF_RES;
631 }
632
633 return ret;
634 }
635
GapLeSetExtendedScanParametersComplete(const HciLeSetExtendedScanParametersReturnParam * param)636 void GapLeSetExtendedScanParametersComplete(const HciLeSetExtendedScanParametersReturnParam *param)
637 {
638 if (g_leExScanCallback.callback.scanExSetParamResult) {
639 g_leExScanCallback.callback.scanExSetParamResult(param->status, g_leExScanCallback.context);
640 }
641 }
642
GAP_LeExScanSetParam(uint8_t scanFilterPolity,uint8_t scanPhys,const GapLeScanParam param[])643 int GAP_LeExScanSetParam(uint8_t scanFilterPolity, uint8_t scanPhys, const GapLeScanParam param[])
644 {
645 LOG_INFO("%{public}s:", __FUNCTION__);
646 int ret;
647
648 if (GapIsLeEnable() == false) {
649 return GAP_ERR_NOT_ENABLE;
650 }
651
652 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_CENTRAL) == false) {
653 ret = GAP_ERR_INVAL_STATE;
654 } else {
655 ret = GapLeSetExtendedScanParameters(BTM_GetOwnAddressType(), scanFilterPolity, scanPhys, param);
656 }
657
658 return ret;
659 }
660
GapLeSetExtendedScanEnable(uint8_t scanEnable,uint8_t filterDuplicates,uint16_t duration,uint16_t period)661 static int GapLeSetExtendedScanEnable(uint8_t scanEnable, uint8_t filterDuplicates, uint16_t duration, uint16_t period)
662 {
663 HciLeSetExtendedScanEnableParam hciCmdParam = {
664 .duration = duration,
665 .enable = scanEnable,
666 .filterDuplicates = filterDuplicates,
667 .period = period,
668 };
669
670 return HCI_LeSetExtendedScanEnable(&hciCmdParam);
671 }
672
GapLeSetExtendedScanEnableComplete(const HciLeSetExtendedScanEnableReturnParam * param)673 void GapLeSetExtendedScanEnableComplete(const HciLeSetExtendedScanEnableReturnParam *param)
674 {
675 if (g_leExScanCallback.callback.scanExSetEnableResult) {
676 g_leExScanCallback.callback.scanExSetEnableResult(param->status, g_leExScanCallback.context);
677 }
678 }
679
GAP_LeExScanSetEnable(uint8_t scanEnable,uint8_t filterDuplicates,uint16_t duration,uint16_t period)680 int GAP_LeExScanSetEnable(uint8_t scanEnable, uint8_t filterDuplicates, uint16_t duration, uint16_t period)
681 {
682 LOG_INFO("%{public}s:", __FUNCTION__);
683 int ret;
684
685 if (GapIsLeEnable() == false) {
686 return GAP_ERR_NOT_ENABLE;
687 }
688
689 if (GapLeRolesCheck(GAP_LE_ROLE_BROADCASTER | GAP_LE_ROLE_CENTRAL) == false) {
690 ret = GAP_ERR_INVAL_STATE;
691 } else {
692 ret = GapLeSetExtendedScanEnable(scanEnable, filterDuplicates, duration, period);
693 }
694
695 return ret;
696 }