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 ? &currentAddr : 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, &currentAddr);
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, &currentAddr);
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, &currentAddr);
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