• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "bluetooth_ble_impl.h"
17 
18 #include "bluetooth_ble_central_manager.h"
19 #include "bluetooth_ble_common.h"
20 #include "bluetooth_ble_ffi.h"
21 #include "bluetooth_errorcode.h"
22 #include "bluetooth_log.h"
23 #include "cj_lambda.h"
24 #include "napi_bluetooth_utils.h"
25 
26 namespace OHOS {
27 namespace CJSystemapi {
28 namespace CJBluetoothBle {
29 using Bluetooth::BleAdvertiser;
30 using Bluetooth::BleAdvertiserData;
31 using Bluetooth::BleScanFilter;
32 using Bluetooth::BleScanSettings;
33 using Bluetooth::IsValidAddress;
34 using Bluetooth::IsValidUuid;
35 using Bluetooth::ParcelUuid;
36 using OHOS::FFI::FFIData;
37 
38 using Bluetooth::NapiAdvManufactureData;
39 using Bluetooth::NapiAdvServiceData;
40 
41 using Bluetooth::BT_ERR_BLE_SCAN_ALREADY_STARTED;
42 using Bluetooth::BT_ERR_INTERNAL_ERROR;
43 using Bluetooth::BT_ERR_INVALID_PARAM;
44 using Bluetooth::BT_NO_ERROR;
45 
46 namespace {
47 using Bluetooth::BleCentralManager;
48 
BleAdvertiserGetInstance(void)49 std::shared_ptr<BleAdvertiser> BleAdvertiserGetInstance(void)
50 {
51     static auto instance = BleAdvertiser::CreateInstance();
52     return instance;
53 }
54 
BleCentralManagerGetInstance(void)55 BleCentralManager *BleCentralManagerGetInstance(void)
56 {
57     static BleCentralManager instance(FfiBluetoothBleCentralManagerCallback::GetInstance());
58     return &instance;
59 }
60 } // namespace
61 
CreateGattServer(FfiGattServer * & ffiGattServer)62 int32_t BleImpl::CreateGattServer(FfiGattServer *&ffiGattServer)
63 {
64     ffiGattServer = FFIData::Create<FfiGattServer>();
65     if (ffiGattServer == nullptr) {
66         return BT_ERR_INTERNAL_ERROR;
67     }
68     return BT_NO_ERROR;
69 }
70 
CreateGattClientDevice(std::string deviceId,FfiClientDevice * & ffiClientDevice)71 int32_t BleImpl::CreateGattClientDevice(std::string deviceId, FfiClientDevice *&ffiClientDevice)
72 {
73     if (!IsValidAddress(deviceId)) {
74         HILOGE("Invalid deviceId: %{public}s", deviceId.c_str());
75         return BT_ERR_INVALID_PARAM;
76     }
77     ffiClientDevice = FFIData::Create<FfiClientDevice>(deviceId);
78     return BT_NO_ERROR;
79 }
80 
GetConnectedBleDevices(CArrString & res)81 int32_t BleImpl::GetConnectedBleDevices(CArrString &res)
82 {
83     std::lock_guard<std::mutex> lock(FfiGattServer::deviceListMutex_);
84     std::vector<std::string> devicesList = FfiGattServer::deviceList_;
85     res = Convert2CArrString(devicesList);
86     return BT_NO_ERROR;
87 }
88 
ParseScanFilterDeviceIdParameters(int32_t & status,NativeScanFilter & scanFilter,BleScanFilter & bleScanFilter)89 static void ParseScanFilterDeviceIdParameters(int32_t &status, NativeScanFilter &scanFilter,
90                                               BleScanFilter &bleScanFilter)
91 {
92     if (scanFilter.deviceId != nullptr) {
93         std::string deviceId = std::string(scanFilter.deviceId);
94         if (!IsValidAddress(deviceId)) {
95             HILOGE("Invalid deviceId: %{public}s", deviceId.c_str());
96             status = BT_ERR_INVALID_PARAM;
97         }
98         bleScanFilter.SetDeviceId(deviceId);
99     }
100 }
101 
ParseScanFilterLocalNameParameters(int32_t & status,NativeScanFilter & scanFilter,BleScanFilter & bleScanFilter)102 static void ParseScanFilterLocalNameParameters(int32_t &status, NativeScanFilter &scanFilter,
103                                                BleScanFilter &bleScanFilter)
104 {
105     if (scanFilter.name != nullptr) {
106         std::string name = std::string(scanFilter.name);
107         if (name.empty()) {
108             HILOGE("name is empty");
109             status = BT_ERR_INVALID_PARAM;
110         }
111         bleScanFilter.SetName(name);
112     }
113 }
114 
ParseUuidParams(char * name,UUID & outUuid)115 static int32_t ParseUuidParams(char *name, UUID &outUuid)
116 {
117     std::string uuid = std::string(name);
118     if (!IsValidUuid(uuid)) {
119         HILOGE("match the UUID faild.");
120         return BT_ERR_INVALID_PARAM;
121     }
122     outUuid = ParcelUuid::FromString(uuid);
123     return BT_NO_ERROR;
124 }
125 
ParseScanFilterServiceUuidParameters(int32_t & status,NativeScanFilter & scanFilter,BleScanFilter & bleScanFilter)126 static void ParseScanFilterServiceUuidParameters(int32_t &status, NativeScanFilter &scanFilter,
127                                                  BleScanFilter &bleScanFilter)
128 {
129     if (scanFilter.serviceUuid != nullptr) {
130         UUID uuid{};
131         status = ParseUuidParams(scanFilter.serviceUuid, uuid);
132         if (status != BT_NO_ERROR) {
133             return;
134         }
135         bleScanFilter.SetServiceUuid(uuid);
136     }
137 
138     if (scanFilter.serviceUuidMask != nullptr) {
139         UUID uuidMask{};
140         status = ParseUuidParams(scanFilter.serviceUuidMask, uuidMask);
141         if (status != BT_NO_ERROR) {
142             return;
143         }
144         bleScanFilter.SetServiceUuidMask(uuidMask);
145     }
146 }
147 
ParseScanFilterSolicitationUuidParameters(int32_t & status,NativeScanFilter & scanFilter,BleScanFilter & bleScanFilter)148 static void ParseScanFilterSolicitationUuidParameters(int32_t &status, NativeScanFilter &scanFilter,
149                                                       BleScanFilter &bleScanFilter)
150 {
151     if (scanFilter.serviceSolicitationUuid != nullptr) {
152         UUID uuid{};
153         status = ParseUuidParams(scanFilter.serviceSolicitationUuid, uuid);
154         if (status != BT_NO_ERROR) {
155             return;
156         }
157         bleScanFilter.SetServiceSolicitationUuid(uuid);
158     }
159 
160     if (scanFilter.serviceSolicitationUuidMask != nullptr) {
161         UUID uuidMask{};
162         status = ParseUuidParams(scanFilter.serviceSolicitationUuidMask, uuidMask);
163         if (status != BT_NO_ERROR) {
164             return;
165         }
166         bleScanFilter.SetServiceSolicitationUuidMask(uuidMask);
167     }
168 }
169 
ParseScanFilterServiceDataParameters(int32_t & status,NativeScanFilter & scanFilter,BleScanFilter & bleScanFilter)170 static void ParseScanFilterServiceDataParameters(int32_t &status, NativeScanFilter &scanFilter,
171                                                  BleScanFilter &bleScanFilter)
172 {
173     std::vector<uint8_t> data{};
174     if (scanFilter.serviceData.head != nullptr) {
175         bleScanFilter.SetServiceData(std::move(data));
176     }
177 
178     std::vector<uint8_t> dataMask{};
179     if (scanFilter.serviceDataMask.head != nullptr) {
180         bleScanFilter.SetServiceDataMask(std::move(dataMask));
181     }
182 }
183 
ParseScanFilterManufactureDataParameters(int32_t & status,NativeScanFilter & scanFilter,BleScanFilter & bleScanFilter)184 static void ParseScanFilterManufactureDataParameters(int32_t &status, NativeScanFilter &scanFilter,
185                                                      BleScanFilter &bleScanFilter)
186 {
187     if (scanFilter.manufactureId != 0) {
188         bleScanFilter.SetManufacturerId(scanFilter.manufactureId);
189         HILOGI("Scan filter manufacturerId is %{public}#x", scanFilter.manufactureId);
190     }
191 
192     std::vector<uint8_t> data{};
193     if (scanFilter.manufactureData.head != nullptr) {
194         for (int64_t i = 0; i < scanFilter.manufactureData.size; i++) {
195             data.push_back(scanFilter.manufactureData.head[i]);
196         }
197         bleScanFilter.SetManufactureData(std::move(data));
198     }
199 
200     std::vector<uint8_t> dataMask{};
201     if (scanFilter.manufactureDataMask.head != nullptr) {
202         for (int64_t i = 0; i < scanFilter.manufactureDataMask.size; i++) {
203             dataMask.push_back(scanFilter.manufactureDataMask.head[i]);
204         }
205         bleScanFilter.SetManufactureDataMask(std::move(dataMask));
206     }
207 }
208 
ParseScanFilter(int32_t & status,NativeScanFilter & scanFilter,BleScanFilter & bleScanFilter)209 static void ParseScanFilter(int32_t &status, NativeScanFilter &scanFilter, BleScanFilter &bleScanFilter)
210 {
211     ParseScanFilterDeviceIdParameters(status, scanFilter, bleScanFilter);
212     ParseScanFilterLocalNameParameters(status, scanFilter, bleScanFilter);
213     ParseScanFilterServiceUuidParameters(status, scanFilter, bleScanFilter);
214     ParseScanFilterSolicitationUuidParameters(status, scanFilter, bleScanFilter);
215     ParseScanFilterServiceDataParameters(status, scanFilter, bleScanFilter);
216     ParseScanFilterManufactureDataParameters(status, scanFilter, bleScanFilter);
217 }
218 
CheckBleScanParams(CArrNativeScanFilter filters,NativeScanOptions * scanOptions,std::vector<BleScanFilter> & outScanfilters,BleScanSettings & outSettinngs)219 static int32_t CheckBleScanParams(CArrNativeScanFilter filters, NativeScanOptions *scanOptions,
220                                   std::vector<BleScanFilter> &outScanfilters, BleScanSettings &outSettinngs)
221 {
222     std::vector<BleScanFilter> scanfilters;
223     uint32_t length = static_cast<uint32_t>(filters.size);
224     int32_t status = BT_NO_ERROR;
225     for (uint32_t i = 0; i < length; i++) {
226         BleScanFilter bleScanFilter;
227         ParseScanFilter(status, filters.head[i], bleScanFilter);
228         scanfilters.push_back(bleScanFilter);
229     }
230     if (status != BT_NO_ERROR) {
231         return status;
232     }
233 
234     if (scanOptions != nullptr) {
235         outSettinngs.SetReportDelay(scanOptions->interval);
236         outSettinngs.SetScanMode(scanOptions->dutyMode);
237         outSettinngs.SetPhy(scanOptions->phyType);
238     }
239 
240     outScanfilters = std::move(scanfilters);
241     return BT_NO_ERROR;
242 }
243 
StartBleScan(CArrNativeScanFilter filters,NativeScanOptions * options)244 int32_t BleImpl::StartBleScan(CArrNativeScanFilter filters, NativeScanOptions *options)
245 {
246     std::vector<BleScanFilter> scanfilters;
247     BleScanSettings settings;
248 
249     int status = CheckBleScanParams(filters, options, scanfilters, settings);
250     if (status != BT_NO_ERROR) {
251         return status;
252     }
253 
254     int ret = BleCentralManagerGetInstance()->StartScan(settings, scanfilters);
255     if (ret != BT_NO_ERROR && ret != BT_ERR_BLE_SCAN_ALREADY_STARTED) {
256         return ret;
257     }
258     return BT_NO_ERROR;
259 }
260 
StopBleScan()261 int32_t BleImpl::StopBleScan()
262 {
263     return BleCentralManagerGetInstance()->StopScan();
264 }
265 
ParseAdvertisingSettingsParameters(int32_t * errCode,NativeAdvertiseSetting & setting,BleAdvertiserSettings & outSettings)266 static void ParseAdvertisingSettingsParameters(int32_t *errCode, NativeAdvertiseSetting &setting,
267                                                BleAdvertiserSettings &outSettings)
268 {
269     uint32_t interval = setting.interval;
270     const uint32_t minInterval = 32;
271     const uint32_t maxInterval = 16384;
272     if (interval < minInterval || interval > maxInterval) {
273         HILOGE("Invalid interval: %{public}d", interval);
274         *errCode = BT_ERR_INVALID_PARAM;
275         return;
276     }
277     HILOGI("interval: %{public}u", interval);
278     outSettings.SetInterval(interval);
279 
280     int32_t txPower = setting.txPower;
281     const int32_t minTxPower = -127;
282     const int32_t maxTxPower = 1;
283     if (txPower < minTxPower || txPower > maxTxPower) {
284         HILOGE("Invalid tx power: %{public}d", txPower);
285         *errCode = BT_ERR_INVALID_PARAM;
286         return;
287     }
288     HILOGI("txPower is %{public}d", txPower);
289     outSettings.SetTxPower(txPower);
290 
291     bool connectable = setting.connectable;
292     HILOGI("connectable: %{public}d", connectable);
293     outSettings.SetConnectable(connectable);
294 
295     return;
296 }
297 
ParseServiceUuidParameters(int32_t * errCode,NativeAdvertiseData advData,BleAdvertiserData & outData)298 static void ParseServiceUuidParameters(int32_t *errCode, NativeAdvertiseData advData, BleAdvertiserData &outData)
299 {
300     for (int64_t i = 0; i < advData.serviceUuids.size; ++i) {
301         UUID uuid{};
302         *errCode = ParseUuidParams(advData.serviceUuids.head[i], uuid);
303         if (*errCode != BT_NO_ERROR) {
304             return;
305         }
306         outData.AddServiceUuid(uuid);
307         HILOGI("Service Uuid = %{public}s", uuid.ToString().c_str());
308     }
309     return;
310 }
311 
ParseManufactureDataParameters(int32_t * errCode,NativeAdvertiseData advData,BleAdvertiserData & outData)312 static void ParseManufactureDataParameters(int32_t *errCode, NativeAdvertiseData advData, BleAdvertiserData &outData)
313 {
314     CArrNativeManufactureData parameter = advData.manufactureData;
315     for (int64_t i = 0; i < parameter.size; ++i) {
316         NativeManufactureData manufactureData = parameter.head[i];
317         CArrUI8 manufactureValue = manufactureData.manufactureValue;
318         std::string value(reinterpret_cast<char *>(manufactureValue.head), manufactureValue.size);
319         outData.AddManufacturerData(manufactureData.manufactureId, value);
320     }
321     return;
322 }
323 
ParseServiceDataParameters(int32_t * errCode,NativeAdvertiseData advData,BleAdvertiserData & outData)324 static void ParseServiceDataParameters(int32_t *errCode, NativeAdvertiseData advData, BleAdvertiserData &outData)
325 {
326     CArrNativeServiceData data = advData.serviceData;
327     for (int64_t i = 0; i < data.size; ++i) {
328         NativeServiceData serviceData = data.head[i];
329         std::string value(reinterpret_cast<char *>(serviceData.serviceValue.head), serviceData.serviceValue.size);
330         outData.AddServiceData(ParcelUuid::FromString(std::string(serviceData.serviceUuid)), value);
331     }
332     return;
333 }
334 
ParseAdvertisDataParameters(int32_t * errCode,NativeAdvertiseData advData,BleAdvertiserData & outData)335 static void ParseAdvertisDataParameters(int32_t *errCode, NativeAdvertiseData advData, BleAdvertiserData &outData)
336 {
337     ParseServiceUuidParameters(errCode, advData, outData);
338     ParseManufactureDataParameters(errCode, advData, outData);
339     ParseServiceDataParameters(errCode, advData, outData);
340     bool includeDeviceName = advData.includeDeviceName;
341     HILOGI("includeDeviceName: %{public}d", includeDeviceName);
342     outData.SetIncludeDeviceName(includeDeviceName);
343     return;
344 }
345 
StartAdvertising(NativeAdvertiseSetting setting,NativeAdvertiseData advData,NativeAdvertiseData * advResponse)346 int32_t BleImpl::StartAdvertising(NativeAdvertiseSetting setting, NativeAdvertiseData advData,
347                                   NativeAdvertiseData *advResponse)
348 {
349     std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
350     BleAdvertiserSettings nativeSettings;
351     BleAdvertiserData nativeAdvData;
352     BleAdvertiserData nativeRspData;
353     int32_t errCode = BT_NO_ERROR;
354 
355     ParseAdvertisingSettingsParameters(&errCode, setting, nativeSettings);
356     ParseAdvertisDataParameters(&errCode, advData, nativeAdvData);
357     if (advResponse != nullptr) {
358         ParseAdvertisDataParameters(&errCode, *advResponse, nativeRspData);
359     }
360 
361     if (errCode != BT_NO_ERROR) {
362         return errCode;
363     }
364     return bleAdvertiser->StartAdvertising(nativeSettings, nativeAdvData, nativeRspData, 0,
365                                            FfiBluetoothBleAdvertiseCallback::GetInstance());
366 }
367 
StopAdvertising()368 int32_t BleImpl::StopAdvertising()
369 {
370     std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
371     if (bleAdvertiser == nullptr) {
372         HILOGE("bleAdvertiser is nullptr");
373         return BT_ERR_INTERNAL_ERROR;
374     }
375     return bleAdvertiser->StopAdvertising(FfiBluetoothBleAdvertiseCallback::GetInstance());
376 }
377 
IsValidAdvertiserDuration(uint32_t duration)378 static bool IsValidAdvertiserDuration(uint32_t duration)
379 {
380     const uint32_t MIN_DURATION = 0;
381     const uint32_t MAX_DURATION = 65535;
382     if (duration < MIN_DURATION || duration > MAX_DURATION) {
383         return false;
384     }
385     return true;
386 }
387 
StartAdvertising(NativeAdvertisingParams advertisingParams,int32_t & id)388 int32_t BleImpl::StartAdvertising(NativeAdvertisingParams advertisingParams, int32_t &id)
389 {
390     std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
391     BleAdvertiserSettings nativeSettings;
392     BleAdvertiserData nativeAdvData;
393     BleAdvertiserData nativeRspData;
394 
395     int32_t errCode = BT_NO_ERROR;
396     ParseAdvertisingSettingsParameters(&errCode, advertisingParams.advertisingSettings, nativeSettings);
397     ParseAdvertisDataParameters(&errCode, advertisingParams.advertisingData, nativeAdvData);
398     ParseAdvertisDataParameters(&errCode, advertisingParams.advertisingResponse, nativeRspData);
399     uint16_t duration = advertisingParams.duration;
400     if (!IsValidAdvertiserDuration(duration)) {
401         HILOGE("Invalid duration: %{public}d", duration);
402         return BT_ERR_INVALID_PARAM;
403     }
404     HILOGI("duration: %{public}u", duration);
405     errCode = bleAdvertiser->StartAdvertising(nativeSettings, nativeAdvData, nativeRspData, duration,
406                                               FfiBluetoothBleAdvertiseCallback::GetInstance());
407     if (errCode != BT_NO_ERROR) {
408         return errCode;
409     }
410     id = FfiBluetoothBleAdvertiseCallback::GetInstance()->GetAdvHandleEvent();
411     if (id < 0) {
412         return BT_ERR_INTERNAL_ERROR;
413     }
414     return BT_NO_ERROR;
415 }
416 
EnableAdvertising(NativeAdvertisingEnableParams advertisingEnableParams)417 int32_t BleImpl::EnableAdvertising(NativeAdvertisingEnableParams advertisingEnableParams)
418 {
419     uint32_t advHandle = advertisingEnableParams.advertisingId;
420     uint16_t duration = advertisingEnableParams.duration;
421 
422     std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
423     if (bleAdvertiser == nullptr) {
424         HILOGE("bleAdvertiser is nullptr");
425         return BT_ERR_INTERNAL_ERROR;
426     }
427     return bleAdvertiser->EnableAdvertising(advHandle, duration, FfiBluetoothBleAdvertiseCallback::GetInstance());
428 }
429 
DisableAdvertising(NativeAdvertisingDisableParams advertisingDisableParams)430 int32_t BleImpl::DisableAdvertising(NativeAdvertisingDisableParams advertisingDisableParams)
431 {
432     uint32_t advHandle = advertisingDisableParams.advertisingId;
433 
434     std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
435     if (bleAdvertiser == nullptr) {
436         HILOGE("bleAdvertiser is nullptr");
437         return BT_ERR_INTERNAL_ERROR;
438     }
439     return bleAdvertiser->DisableAdvertising(advHandle, FfiBluetoothBleAdvertiseCallback::GetInstance());
440 }
441 
StopAdvertising(uint32_t advertisingId)442 int32_t BleImpl::StopAdvertising(uint32_t advertisingId)
443 {
444     std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
445     if (bleAdvertiser == nullptr) {
446         HILOGE("bleAdvertiser is nullptr");
447         return BT_ERR_INTERNAL_ERROR;
448     }
449     uint32_t advHandle = advertisingId;
450     if (advHandle != bleAdvertiser->GetAdvHandle(FfiBluetoothBleAdvertiseCallback::GetInstance())) {
451         HILOGE("Invalid advHandle: %{public}d", advHandle);
452         return BT_ERR_INVALID_PARAM;
453     }
454     bleAdvertiser->StopAdvertising(FfiBluetoothBleAdvertiseCallback::GetInstance());
455     return BT_NO_ERROR;
456 }
457 
RegisterBleObserver(int32_t callbackType,void (* callback)())458 int32_t BleImpl::RegisterBleObserver(int32_t callbackType, void (*callback)())
459 {
460     if (callbackType == REGISTER_BLE_ADVERTISING_STATE_INFO_TYPE) {
461         auto callbackFunc = CJLambda::Create(reinterpret_cast<void (*)(CAdvertisingStateChangeInfo)>(callback));
462         FfiBluetoothBleAdvertiseCallback::GetInstance()->RegisterAdvertisingStateChangeFunc(callbackFunc);
463     } else if (callbackType == REGISTER_BLE_FIND_DEVICE_TYPE) {
464         auto callbackFunc = CJLambda::Create(reinterpret_cast<void (*)(CArrScanResult)>(callback));
465         FfiBluetoothBleCentralManagerCallback::GetInstance().RegisterBLEDeviceFindFunc(callbackFunc);
466     } else {
467         HILOGE("Unsupported callback type");
468         return BT_ERR_INVALID_PARAM;
469     }
470     return BT_NO_ERROR;
471 }
472 } // namespace CJBluetoothBle
473 } // namespace CJSystemapi
474 } // namespace OHOS