• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "ohos_bt_gatt.h"
17 
18 #include <unistd.h>
19 #include <cstdint>
20 #include <sstream>
21 #include <vector>
22 #include "__config"
23 #include "bluetooth_ble_advertiser.h"
24 #include "bluetooth_ble_central_manager.h"
25 #include "bluetooth_log.h"
26 #include "bluetooth_remote_device.h"
27 #include "bluetooth_utils.h"
28 #include "cstdint"
29 #include "iosfwd"
30 #include "istream"
31 #include "new"
32 #include "ohos_bt_adapter_utils.h"
33 #include "ohos_bt_def.h"
34 #include "ostream"
35 #include "securec.h"
36 #include "streambuf"
37 #include "string"
38 #include "uuid.h"
39 
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 using namespace std;
46 
47 namespace OHOS {
48 namespace Bluetooth {
49 #define MAX_BLE_ADV_NUM 7
50 
51 class BleCentralManagerCallbackWapper;
52 class BleAdvCallback;
53 
54 static BtGattCallbacks *g_AppCallback;
55 static BleCentralManager *g_BleCentralManager;
56 static BleCentralManagerCallbackWapper *g_scanCallback;
57 
58 static BleAdvCallback *g_bleAdvCallbacks[MAX_BLE_ADV_NUM];
59 static BleAdvertiser *g_BleAdvertiser = nullptr;
60 
61 class BleCentralManagerCallbackWapper : public BleCentralManagerCallback {
62 public:
63     /**
64      * @brief Scan result callback.
65      *
66      * @param result Scan result.
67      * @since 6
68      */
OnScanCallback(const BleScanResult & result)69     void OnScanCallback(const BleScanResult &result) {
70         BtScanResultData scanResult;
71         scanResult.eventType = OHOS_BLE_EVT_LEGACY_CONNECTABLE; // result.IsConnectable();
72         scanResult.dataStatus = OHOS_BLE_DATA_COMPLETE;
73         scanResult.addrType = OHOS_BLE_RANDOM_DEVICE_ADDRESS;
74         scanResult.primaryPhy = OHOS_BLE_SCAN_PHY_1M;
75         scanResult.secondaryPhy = OHOS_BLE_SCAN_PHY_1M;
76         scanResult.advSid = 1;
77         scanResult.txPower = 1;
78         scanResult.rssi = result.GetRssi();
79         scanResult.directAddrType = OHOS_BLE_RANDOM_DEVICE_ADDRESS;
80         GetAddrFromString(result.GetPeripheralDevice().GetDeviceAddr(), scanResult.addr.addr);
81         vector<uint8_t> vec = result.GetPayload();
82         scanResult.advData = vec.data();
83         scanResult.advLen = vec.size();
84 
85         std::string strs;
86         std::stringstream strStream;
87         for (int i = 0; i < scanResult.advLen; i++) {
88             char token[3] = {0};
89             (void)sprintf_s(token, 3, "%02X", scanResult.advData[i]);
90             strStream << token;
91         }
92         strStream >> strs;
93         string address = result.GetPeripheralDevice().GetDeviceAddr();
94         HILOGI("device: %{public}s, scan data: %{public}s", GetEncryptAddr(address).c_str(), strs.c_str());
95         if (g_AppCallback != nullptr && g_AppCallback->scanResultCb != nullptr) {
96             g_AppCallback->scanResultCb(&scanResult);
97         } else {
98             HILOGW("call back is null.");
99         }
100     }
101 
102     /**
103      * @brief Batch scan results event callback.
104      *
105      * @param results Scan results.
106      * @since 6
107      */
OnBleBatchScanResultsEvent(const std::vector<BleScanResult> & results)108     void OnBleBatchScanResultsEvent(const std::vector<BleScanResult> &results) {}
109 
110     /**
111      * @brief Start or Stop scan event callback.
112      *
113      * @param resultCode Scan result code.
114      * @param isStartScan true->start scan, false->stop scan.
115      * @since 6
116      */
OnStartOrStopScanEvent(int resultCode,bool isStartScan)117     void OnStartOrStopScanEvent(int resultCode, bool isStartScan) {}
118 };
119 
120 class BleAdvCallback : public BleAdvertiseCallback {
121 public:
BleAdvCallback(int advId)122     explicit BleAdvCallback(int advId)
123     {
124         advId_ = advId;
125     }
126 
OnStartResultEvent(int result)127     NO_SANITIZE("cfi") void OnStartResultEvent(int result) {
128         if (result != 0) {
129             HILOGE("result : %{public}d", result);
130             return;
131         }
132 
133         HILOGI("adv started. advId_: %{public}d", advId_);
134         if (g_AppCallback != nullptr && g_AppCallback->advEnableCb != nullptr) {
135             g_AppCallback->advEnableCb(advId_, 0);
136         } else {
137             HILOGW("call back is null.");
138         }
139     }
140 
141 protected:
142     BleAdvertiserData *advData;
143     BleAdvertiserData *advResponseData;
144     BleAdvertiserSettings *advSetting;
145 
146 private:
147     int advId_;
148 };
149 
150 /**
151  * @brief Initializes the Bluetooth protocol stack.
152  *
153  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the Bluetooth protocol stack is initialized;
154  * returns an error code defined in {@link BtStatus} otherwise.
155  * @since 6
156  */
InitBtStack(void)157 int InitBtStack(void) {
158     return OHOS_BT_STATUS_SUCCESS;
159 }
160 
161 /**
162  * @brief Enables the Bluetooth protocol stack.
163  *
164  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the Bluetooth protocol stack is enabled;
165  * returns an error code defined in {@link BtStatus} otherwise.
166  * @since 6
167  */
EnableBtStack(void)168 int EnableBtStack(void) {
169     return OHOS_BT_STATUS_SUCCESS;
170 }
171 
172 /**
173  * @brief Disables the Bluetooth protocol stack.
174  *
175  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the Bluetooth protocol stack is disabled;
176  * returns an error code defined in {@link BtStatus} otherwise.
177  * @since 6
178  */
DisableBtStack(void)179 int DisableBtStack(void) {
180     return OHOS_BT_STATUS_SUCCESS;
181 }
182 
183 /**
184  * @brief Sets the Bluetooth device name.
185  *
186  * @param name Indicates the pointer to the name to set.
187  * @param len Indicates the length of the name to set.
188  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the Bluetooth device name is set;
189  * returns an error code defined in {@link BtStatus} otherwise.
190  * @since 6
191  */
SetDeviceName(const char * name,unsigned int len)192 int SetDeviceName(const char *name, unsigned int len) {
193     return OHOS_BT_STATUS_UNSUPPORTED;
194 }
195 
196 /**
197  * @brief Sets advertising data.
198  *
199  * @param advId Indicates the advertisement ID, which is allocated by the upper layer of the advertiser.
200  * @param data Indicates the pointer to the advertising data. For details, see {@link StartAdvRawData}.
201  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if advertising data is set;
202  * returns an error code defined in {@link BtStatus} otherwise.
203  * @since 6
204  */
BleSetAdvData(int advId,const StartAdvRawData data)205 int BleSetAdvData(int advId, const StartAdvRawData data)
206 {
207     return OHOS_BT_STATUS_UNSUPPORTED;
208 }
209 
210 /**
211  * @brief Starts advertising.
212  *
213  * @param advId Indicates the advertisement ID, which is allocated by the upper layer of the advertiser.
214  * @param param Indicates the pointer to the advertising parameters. For details, see {@link BleAdvParams}.
215  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if advertising is started;
216  * returns an error code defined in {@link BtStatus} otherwise.
217  * @since 6
218  */
BleStartAdv(int advId,const BleAdvParams * param)219 int BleStartAdv(int advId, const BleAdvParams *param)
220 {
221     return OHOS_BT_STATUS_UNSUPPORTED;
222 }
223 
IsAllAdvStopped()224 static bool IsAllAdvStopped()
225 {
226     for (int i = 0; i < MAX_BLE_ADV_NUM; i++) {
227         if (g_bleAdvCallbacks[i] != nullptr) {
228             return false;
229         }
230     }
231     return true;
232 }
233 
234 /**
235  * @brief Stops advertising.
236  *
237  * @param advId Indicates the advertisement ID, which is allocated by the upper layer of the advertiser.
238  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if advertising is stopped;
239  * returns an error code defined in {@link BtStatus} otherwise.
240  * @since 6
241  */
BleStopAdv(int advId)242 NO_SANITIZE("cfi") int BleStopAdv(int advId)
243 {
244     HILOGI("BleStopAdv, advId: %{public}d.", advId);
245     if (advId < 0 || advId >= MAX_BLE_ADV_NUM) {
246         HILOGE("BleStopAdv fail, advId is invalid.");
247         return OHOS_BT_STATUS_FAIL;
248     }
249     if (g_BleAdvertiser == nullptr || g_bleAdvCallbacks[advId] == nullptr) {
250         HILOGE("BleStopAdv fail, the current adv is not started.");
251         return OHOS_BT_STATUS_FAIL;
252     }
253 
254     g_BleAdvertiser->StopAdvertising(*g_bleAdvCallbacks[advId]);
255 
256     usleep(100);
257     if (g_AppCallback != nullptr && g_AppCallback->advDisableCb != nullptr) {
258         HILOGI("adv stopped advId: %{public}d.", advId);
259         g_AppCallback->advDisableCb(advId, 0);
260     }
261     delete g_bleAdvCallbacks[advId];
262     g_bleAdvCallbacks[advId] = nullptr;
263 
264     if (IsAllAdvStopped()) {
265         HILOGI("All adv have been stopped.");
266         delete g_BleAdvertiser;
267         g_BleAdvertiser = nullptr;
268     }
269     return OHOS_BT_STATUS_SUCCESS;
270 }
271 
272 /**
273  * @brief Updates advertising parameters.
274  *
275  * @param advId Indicates the advertisement ID, which is allocated by the upper layer of the advertiser.
276  * @param param Indicates the pointer to the advertising parameters. For details, see {@link BleAdvParams}.
277  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if advertising parameters are updated;
278  * returns an error code defined in {@link BtStatus} otherwise.
279  * @since 6
280  */
BleUpdateAdv(int advId,const BleAdvParams * param)281 int BleUpdateAdv(int advId, const BleAdvParams *param) {
282     return OHOS_BT_STATUS_UNSUPPORTED;
283 }
284 
285 /**
286  * @brief Sets the secure I/O capability mode.
287  *
288  * @param mode Indicates the capability mode to set. For details, see {@link BleIoCapMode}.
289  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the capability mode is set;
290  * returns an error code defined in {@link BtStatus} otherwise.
291  * @since 6
292  */
BleSetSecurityIoCap(BleIoCapMode mode)293 int BleSetSecurityIoCap(BleIoCapMode mode) {
294     return OHOS_BT_STATUS_UNSUPPORTED;
295 }
296 
297 /**
298  * @brief Sets the authentication mode for secure connection requests.
299  *
300  * @param mode Indicates the authentication mode to set. For details, see {@link BleAuthReqMode}.
301  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the authentication mode is set;
302  * returns an error code defined in {@link BtStatus} otherwise.
303  * @since 6
304  */
BleSetSecurityAuthReq(BleAuthReqMode mode)305 int BleSetSecurityAuthReq(BleAuthReqMode mode) {
306     return OHOS_BT_STATUS_UNSUPPORTED;
307 }
308 
309 /**
310  * @brief Responds to a secure connection request.
311  *
312  * @param bdAddr Indicates the address of the device that sends the request.
313  * @param accept Specifies whether to accept the request. The value <b>true</b> means to accept the request,
314  * and <b>false</b> means to reject the request.
315  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the request is responded to;
316  * returns an error code defined in {@link BtStatus} otherwise.
317  * @since 6
318  */
BleGattSecurityRsp(BdAddr bdAddr,bool accept)319 int BleGattSecurityRsp(BdAddr bdAddr, bool accept) {
320     return OHOS_BT_STATUS_UNSUPPORTED;
321 }
322 
323 /**
324  * @brief Obtains the device MAC address.
325  *
326  * @param mac Indicates the pointer to the device MAC address.
327  * @param len Indicates the length of the device MAC address.
328  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the device MAC address is obtained;
329  * returns an error code defined in {@link BtStatus} otherwise.
330  * @since 6
331  */
ReadBtMacAddr(unsigned char * mac,unsigned int len)332 int ReadBtMacAddr(unsigned char *mac, unsigned int len) {
333     return OHOS_BT_STATUS_UNSUPPORTED;
334 }
335 
336 /**
337  * @brief Sets scan parameters.
338  *
339  * @param clientId Indicates the client ID, which is obtained during client registration.
340  * @param param Indicates the pointer to the scan parameters. For details, see {@link BleScanParams}.
341  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the scan parameters are set;
342  * returns an error code defined in {@link BtStatus} otherwise.
343  * @since 6
344  */
BleSetScanParameters(int clientId,BleScanParams * param)345 int BleSetScanParameters(int clientId, BleScanParams *param)
346 {
347     return OHOS_BT_STATUS_SUCCESS;
348 }
349 
350 /**
351  * @brief Starts a scan.
352  *
353  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the scan is started;
354  * returns an error code defined in {@link BtStatus} otherwise.
355  * @since 6
356  */
BleStartScan(void)357 int BleStartScan(void)
358 {
359     HILOGI("BleStartScan enter");
360     if (g_BleCentralManager == nullptr) {
361         HILOGE("BleStartScan fail, ble centra manager is null.");
362         return OHOS_BT_STATUS_FAIL;
363     }
364 
365     g_BleCentralManager->StartScan();
366     return OHOS_BT_STATUS_SUCCESS;
367 }
368 
369 /**
370  * @brief Stops a scan.
371  *
372  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the scan is stopped;
373  * returns an error code defined in {@link BtStatus} otherwise.
374  * @since 6
375  */
BleStopScan(void)376 int BleStopScan(void)
377 {
378     HILOGI("BleStopScan enter");
379     if (g_BleCentralManager == nullptr) {
380         HILOGE("BleStopScan fail, ble centra manager is null.");
381         return OHOS_BT_STATUS_FAIL;
382     }
383 
384     g_BleCentralManager->StopScan();
385     return OHOS_BT_STATUS_SUCCESS;
386 }
387 
388 /**
389  * @brief Registers GATT callbacks.
390  *
391  * @param func Indicates the pointer to the callbacks to register. For details, see {@link BtGattCallbacks}.
392  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the GATT callbacks are registered;
393  * returns an error code defined in {@link BtStatus} otherwise.
394  * @since 6
395  */
BleGattRegisterCallbacks(BtGattCallbacks * func)396 int BleGattRegisterCallbacks(BtGattCallbacks *func)
397 {
398     HILOGI("BleGattRegisterCallbacks enter");
399     if (func == nullptr) {
400         HILOGE("func is null.");
401         return OHOS_BT_STATUS_PARM_INVALID;
402     }
403     g_AppCallback = func;
404 
405     if (g_scanCallback == nullptr) {
406         g_scanCallback = new BleCentralManagerCallbackWapper();
407     }
408 
409     if (g_BleCentralManager == nullptr) {
410         g_BleCentralManager = new BleCentralManager(*g_scanCallback);
411     }
412     return OHOS_BT_STATUS_SUCCESS;
413 }
414 
415 /**
416  * @brief Sets advertising data and parameters and starts advertising.
417  *
418  * This function is available for system applications only. \n
419  *
420  * @param advId Indicates the pointer to the advertisement ID.
421  * @param rawData Indicates the advertising data. For details, see {@link StartAdvRawData}.
422  * @param advParam Indicates the advertising parameters. For details, see {@link BleAdvParams}.
423  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the operation is successful;
424  * returns an error code defined in {@link BtStatus} otherwise.
425  * @since 6
426  */
BleStartAdvEx(int * advId,const StartAdvRawData rawData,BleAdvParams advParam)427 int BleStartAdvEx(int *advId, const StartAdvRawData rawData, BleAdvParams advParam)
428 {
429     HILOGI("BleStartAdvEx enter");
430     if (g_BleAdvertiser == nullptr) {
431         g_BleAdvertiser = new BleAdvertiser();
432     }
433     int i = 0;
434     for (i = 0; i < MAX_BLE_ADV_NUM; i++) {
435         if (g_bleAdvCallbacks[i] == nullptr) {
436             g_bleAdvCallbacks[i] = new BleAdvCallback(i);
437             break;
438         }
439     }
440 
441     if (i == MAX_BLE_ADV_NUM) {
442         return OHOS_BT_STATUS_UNHANDLED;
443     }
444 
445     *advId = i;
446     HILOGI("ret advId: %{public}d.", *advId);
447 
448     BleAdvertiserSettings settings;
449     settings.SetInterval(advParam.minInterval);
450     if (advParam.advType == OHOS_BLE_ADV_SCAN_IND ||
451         advParam.advType == OHOS_BLE_ADV_NONCONN_IND) {
452         settings.SetConnectable(false);
453     }
454 
455     vector<uint8_t> advData;
456     if (rawData.advData != nullptr) {
457         for (unsigned int i = 0; i < rawData.advDataLen; i++) {
458             advData.push_back(rawData.advData[i]);
459         }
460     }
461 
462     vector<uint8_t> scanResponse;
463     if (rawData.rspData != nullptr) {
464         for (unsigned int i = 0; i < rawData.rspDataLen; i++) {
465             scanResponse.push_back(rawData.rspData[i]);
466         }
467     }
468 
469     g_BleAdvertiser->StartAdvertising(settings, advData, scanResponse, *g_bleAdvCallbacks[i]);
470     return OHOS_BT_STATUS_SUCCESS;
471 }
472 
SetServiceUuidParameter(BleScanFilter & scanFilter,BleScanNativeFilter * nativeScanFilter)473 static bool SetServiceUuidParameter(BleScanFilter &scanFilter, BleScanNativeFilter *nativeScanFilter)
474 {
475     HILOGI("SetServiceUuidParameter enter");
476     if (nativeScanFilter->serviceUuidLength != 0 && nativeScanFilter->serviceUuid != nullptr) {
477         if (!regex_match(std::string(reinterpret_cast<char *>(nativeScanFilter->serviceUuid)), uuidRegex)) {
478             HILOGE("match the UUID faild.");
479             return false;
480         }
481         UUID serviceUuid = UUID::FromString((char *)nativeScanFilter->serviceUuid);
482         scanFilter.SetServiceUuid(serviceUuid);
483         if (nativeScanFilter->serviceUuidMask != nullptr) {
484             if (!regex_match(std::string(reinterpret_cast<char *>(nativeScanFilter->serviceUuidMask)), uuidRegex)) {
485                 HILOGE("match the UUID faild.");
486                 return false;
487             }
488             UUID serviceUuidMask = UUID::FromString((char *)nativeScanFilter->serviceUuidMask);
489             scanFilter.SetServiceUuidMask(serviceUuidMask);
490         }
491     }
492     return true;
493 }
494 
495 /**
496  * @brief Sets one scan filter config.
497  *
498  * @param scanFilter Indicates the framework object of scan filter, see {@link BleScanFilter}.
499  * @param nativeScanFilter Indicates the pointer to the scan filter. For details, see {@link BleScanNativeFilter}.
500  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if set onr scan filter config success;
501  * returns an error code defined in {@link BtStatus} otherwise.
502  * @since 6
503  */
SetOneScanFilter(BleScanFilter & scanFilter,BleScanNativeFilter * nativeScanFilter)504 static int SetOneScanFilter(BleScanFilter &scanFilter, BleScanNativeFilter *nativeScanFilter)
505 {
506     HILOGI("SetOneScanFilter enter");
507     if (nativeScanFilter->address != nullptr) {
508         scanFilter.SetDeviceId(nativeScanFilter->address);
509     }
510     if (nativeScanFilter->deviceName != nullptr) {
511         scanFilter.SetName(nativeScanFilter->deviceName);
512     }
513     bool isSuccess = SetServiceUuidParameter(scanFilter, nativeScanFilter);
514     if (!isSuccess) {
515         HILOGE("SetServiceUuidParameter faild.");
516         return OHOS_BT_STATUS_PARM_INVALID;
517     }
518 
519     if (nativeScanFilter->serviceData != nullptr) {
520         std::vector<uint8_t> serviceData;
521         for (unsigned int i = 0; i < nativeScanFilter->serviceDataLength; i++) {
522             serviceData.push_back(nativeScanFilter->serviceData[i]);
523         }
524         scanFilter.SetServiceData(serviceData);
525 
526         if (nativeScanFilter->serviceDataMask != nullptr) {
527             std::vector<uint8_t> serviceDataMask;
528             for (unsigned int i = 0; i < nativeScanFilter->serviceDataLength; i++) {
529                 serviceDataMask.push_back(nativeScanFilter->serviceDataMask[i]);
530             }
531             scanFilter.SetServiceDataMask(serviceDataMask);
532         }
533     }
534 
535     if (nativeScanFilter->manufactureData != nullptr) {
536         std::vector<uint8_t> manufactureData;
537         for (unsigned int i = 0; i < nativeScanFilter->manufactureDataLength; i++) {
538             manufactureData.push_back(nativeScanFilter->manufactureData[i]);
539         }
540         scanFilter.SetManufactureData(manufactureData);
541 
542         if (nativeScanFilter->manufactureDataMask != nullptr) {
543             std::vector<uint8_t> manufactureDataMask;
544             for (unsigned int i = 0; i < nativeScanFilter->manufactureDataLength; i++) {
545                 manufactureDataMask.push_back(nativeScanFilter->manufactureDataMask[i]);
546             }
547             scanFilter.SetManufactureDataMask(manufactureDataMask);
548         }
549 
550         if (nativeScanFilter->manufactureId != 0) {
551             scanFilter.SetManufacturerId(nativeScanFilter->manufactureId);
552         }
553     }
554     return OHOS_BT_STATUS_SUCCESS;
555 }
556 
557 /**
558  * @brief Sets scan filter configs.
559  *
560  * @param filter Indicates the pointer to the scan filter. For details, see {@link BleScanNativeFilter}.
561  * @param filterSize Indicates the number of the scan filter.
562  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if set scan filter configs success;
563  * returns an error code defined in {@link BtStatus} otherwise.
564  * @since 6
565  */
SetConfigScanFilter(BleScanNativeFilter * filter,unsigned int filterSize)566 static int SetConfigScanFilter(BleScanNativeFilter *filter, unsigned int filterSize)
567 {
568     HILOGI("SetConfigScanFilter enter");
569     vector<BleScanFilter> scanFilters;
570     for (unsigned int i = 0; i < filterSize; i++) {
571         BleScanNativeFilter nativeScanFilter = filter[i];
572         BleScanFilter scanFilter;
573         int result = SetOneScanFilter(scanFilter, &nativeScanFilter);
574         if (result != OHOS_BT_STATUS_SUCCESS) {
575             HILOGE("SetOneScanFilter faild, result: %{public}d", result);
576             return OHOS_BT_STATUS_PARM_INVALID;
577         }
578         scanFilters.push_back(scanFilter);
579     }
580     g_BleCentralManager->ConfigScanFilter(scanFilters);
581     return OHOS_BT_STATUS_SUCCESS;
582 }
583 
584 /**
585  * @brief Starts a scan with BleScanConfigs.
586  * If don't need ble scan filter, set BleScanNativeFilter to NULL or filterSize to zero.
587  * If one of the ble scan filtering rules is not required, set it to NULL.
588  * For example, set the address to NULL when you don't need it.
589  * Don't support only using manufactureId as filter conditions, need to use it with manufactureData.
590  * The manufactureId need to be set a related number when you need a filtering condition of manufactureData.
591  *
592  * @param configs Indicates the pointer to the scan filter. For details, see {@link BleScanConfigs}.
593  * @param filter Indicates the pointer to the scan filter. For details, see {@link BleScanNativeFilter}.
594  * @param filterSize Indicates the number of the scan filter.
595  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the scan is started;
596  * returns an error code defined in {@link BtStatus} otherwise.
597  * @since 6
598  */
BleStartScanEx(BleScanConfigs * configs,BleScanNativeFilter * filter,unsigned int filterSize)599 int BleStartScanEx(BleScanConfigs *configs, BleScanNativeFilter *filter, unsigned int filterSize)
600 {
601     HILOGI("BleStartScanEx enter, filterSize %{public}u", filterSize);
602     if (g_BleCentralManager == nullptr || configs == nullptr) {
603         HILOGE("BleStartScanEx fail, ble centra manager is null or configs is null.");
604         return OHOS_BT_STATUS_FAIL;
605     }
606 
607     if (filter != nullptr && filterSize != 0) {
608         int result = SetConfigScanFilter(filter, filterSize);
609         if (result != OHOS_BT_STATUS_SUCCESS) {
610             HILOGE("SetConfigScanFilter faild, result: %{public}d", result);
611             return OHOS_BT_STATUS_PARM_INVALID;
612         }
613     }
614 
615     HILOGI("scanMode: %{public}d", configs->scanMode);
616     BleScanSettings settings;
617     settings.SetScanMode(configs->scanMode);
618     g_BleCentralManager->StartScan(settings);
619     return OHOS_BT_STATUS_SUCCESS;
620 }
621 }  // namespace Bluetooth
622 }  // namespace OHOS
623 #ifdef __cplusplus
624 }
625 #endif
626 /** @} */
627