已开启
for_bluetooth_br_test #2016
for_bluetooth_br_test #2016
已开启
panjie创建于 28 天前
68 个文件变更+5704-19
@@ -102,7 +102,13 @@
102 "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_connection:bluetoothConnection_taihe",102 "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_connection:bluetoothConnection_taihe",
103 "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetoothConstant_taihe",103 "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetoothConstant_taihe",
104 "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_hfp:bluetoothHfp_taihe",104 "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_hfp:bluetoothHfp_taihe",
105- "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_hid:bluetoothHid_taihe"105+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_hid:bluetoothHid_taihe",
106+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_common:bluetoothCommon_taihe",
107+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_map:bluetoothMap_taihe",
108+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_opp:bluetoothOpp_taihe",
109+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_pan:bluetoothPan_taihe",
110+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_pbap:bluetoothPbap_taihe",
111+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_socket:bluetoothSocket_taihe"
106 ],112 ],
107 "service_group": [113 "service_group": [
108 "//foundation/communication/bluetooth/tools/ohos-bluetoothTool:ohos-bluetoothTool",114 "//foundation/communication/bluetooth/tools/ohos-bluetoothTool:ohos-bluetoothTool",
@@ -83,4 +83,6 @@ function GetLocalAddress(): String;
83@gen_promise("factoryReset")83@gen_promise("factoryReset")
84function FactoryResetSync(): void;84function FactoryResetSync(): void;
85 85 
86+function IsBluetoothSupported(): bool;
87+ 
86function ConvertUuid(uuid: String): String;88function ConvertUuid(uuid: String): String;
@@ -212,6 +212,13 @@ void FactoryResetSync()
212 TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);212 TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
213}213}
214 214 
215+bool IsBluetoothSupported()
216+{
217+ bool isSupported = BluetoothHost::GetDefaultHost().IsBluetoothSupported();
218+ HILOGI("IsBluetoothSupported: %{public}d", isSupported);
219+ return isSupported;
220+}
221+ 
215::taihe::string ConvertUuid(::taihe::string uuid)222::taihe::string ConvertUuid(::taihe::string uuid)
216{223{
217 std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM };224 std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM };
@@ -257,5 +264,6 @@ TH_EXPORT_CPP_API_DeletePersistentDeviceId(OHOS::Bluetooth::DeletePersistentDevi
257TH_EXPORT_CPP_API_AddPersistentDeviceId(OHOS::Bluetooth::AddPersistentDeviceId);264TH_EXPORT_CPP_API_AddPersistentDeviceId(OHOS::Bluetooth::AddPersistentDeviceId);
258TH_EXPORT_CPP_API_NotifyDialogResult(OHOS::Bluetooth::NotifyDialogResult);265TH_EXPORT_CPP_API_NotifyDialogResult(OHOS::Bluetooth::NotifyDialogResult);
259TH_EXPORT_CPP_API_FactoryResetSync(OHOS::Bluetooth::FactoryResetSync);266TH_EXPORT_CPP_API_FactoryResetSync(OHOS::Bluetooth::FactoryResetSync);
267+TH_EXPORT_CPP_API_IsBluetoothSupported(OHOS::Bluetooth::IsBluetoothSupported);
260TH_EXPORT_CPP_API_ConvertUuid(OHOS::Bluetooth::ConvertUuid);268TH_EXPORT_CPP_API_ConvertUuid(OHOS::Bluetooth::ConvertUuid);
261// NOLINTEND269// NOLINTEND
@@ -22,7 +22,8 @@ copy_taihe_idl("bluetooth_ble_taihe") {
22 "idl/ohos.bluetooth.ble.taihe",22 "idl/ohos.bluetooth.ble.taihe",
23 ]23 ]
24 deps = [24 deps = [
25- "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetooth_constant_taihe"25+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetooth_constant_taihe",
26+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_connection:bluetooth_connection_taihe"
26 ]27 ]
27}28}
28 29 
@@ -86,6 +87,7 @@ taihe_shared_library("bluetoothBle_taihe_native") {
86 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_async_work.cpp",87 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_async_work.cpp",
87 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_ha_event_utils.cpp",88 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_ha_event_utils.cpp",
88 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_native_object.cpp",89 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_native_object.cpp",
90+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp",
89 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/parser/taihe_parser_utils.cpp",91 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/parser/taihe_parser_utils.cpp",
90 ]92 ]
91 deps = [93 deps = [
@@ -20,6 +20,7 @@
20static { loadLibraryWithPermissionCheck("bluetoothBle_taihe_native.z", "@ohos.bluetooth.ble") }20static { loadLibraryWithPermissionCheck("bluetoothBle_taihe_native.z", "@ohos.bluetooth.ble") }
21""")21""")
22from ohos.bluetooth.constant use ProfileConnectionState;22from ohos.bluetooth.constant use ProfileConnectionState;
23+from ohos.bluetooth.connection use BluetoothTransport;
23 24 
24struct ScanReport {25struct ScanReport {
25 reportType: ScanReportType;26 reportType: ScanReportType;
@@ -231,6 +232,21 @@ struct GattPermissions {
231 232 
232function StopAdvertising(): void;233function StopAdvertising(): void;
233 234 
235+@gen_async("stopAdvertising")
236+@gen_promise("stopAdvertising")
237+function StopAdvertisingSync(advertisingId: i32): void;
238+ 
239+struct GattSetting {
240+ autoConnect: Optional<bool>;
241+ transport: Optional<BluetoothTransport>;
242+}
243+ 
244+function OnAdvertisingStateChange(callback:(data: AdvertisingStateChangeInfo) => void): void;
245+function OffAdvertisingStateChange(callback: Optional<(data: AdvertisingStateChangeInfo) => void>): void;
246+ 
247+function OnBleDeviceFind(callback:(data: Array<ScanResult>) => void): void;
248+function OffBLEDeviceFind(callback: Optional<(data: Array<ScanResult>) => void>): void;
249+ 
234interface GattClientDevice {250interface GattClientDevice {
235 SetBLEMtuSize(mtu: i32): void;251 SetBLEMtuSize(mtu: i32): void;
236 Connect(): void;252 Connect(): void;
@@ -259,6 +275,63 @@ interface GattClientDevice {
259 275 
260 @rename("setCharacteristicChangeIndication")276 @rename("setCharacteristicChangeIndication")
261 SetCharacteristicChangeIndicationAsync(characteristic: BLECharacteristic, enable: bool, callback: @sts_type("AsyncCallback<void>") Opaque): void;277 SetCharacteristicChangeIndicationAsync(characteristic: BLECharacteristic, enable: bool, callback: @sts_type("AsyncCallback<void>") Opaque): void;
278+ 
279+ @gen_promise("readPhy")
280+ ReadPhySync(): PhyValue;
281+ 
282+ @gen_promise("setPhy")
283+ SetPhySync(phyValue: PhyValue): void;
284+ 
285+ @gen_promise("writeCharacteristicValueWithContext")
286+ WriteCharacteristicValueWithContextSync(characteristic: BLECharacteristic, writeType: GattWriteType): GattRspContext;
287+ 
288+ @gen_async("writeDescriptorValue")
289+ @gen_promise("writeDescriptorValue")
290+ WriteDescriptorValueSync(descriptor: BLEDescriptor): void;
291+ 
292+ @gen_promise("getServices")
293+ GetServicesSync(): Array<GattService>;
294+ 
295+ OnBlePhyUpdate(callback:(data: PhyValue) => void): void;
296+ OffBlePhyUpdate(callback: Optional<(data: PhyValue) => void>): void;
297+ 
298+ @gen_async("setCharacteristicChangeNotification")
299+ @gen_promise("setCharacteristicChangeNotification")
300+ SetCharacteristicChangeNotificationSync(characteristic: BLECharacteristic, enable: bool): void;
301+ 
302+ @gen_async("getRssiValue")
303+ @gen_promise("getRssiValue")
304+ GetRssiValueSync(): i32;
305+ 
306+ @gen_promise("setBLEMtu")
307+ SetBLEMtuSync(mtu: i32): i32;
308+ 
309+ @gen_async("writeCharacteristicValue")
310+ @gen_promise("writeCharacteristicValue")
311+ WriteCharacteristicValueSync(characteristic: BLECharacteristic, writeType: GattWriteType): void;
312+ 
313+ OnBLEMtuChange(callback:(data: i32) => void): void;
314+ OffBLEMtuChange(callback: Optional<(data: i32) => void>): void;
315+ 
316+ OnServiceChange(callback: () => void): void;
317+ OffServiceChange(callback: Optional<() => void>): void;
318+ 
319+ OnBLECharacteristicChange(callback:(data: BLECharacteristic) => void): void;
320+ OffBLECharacteristicChange(callback: Optional<(data: BLECharacteristic) => void>): void;
321+ 
322+ @gen_promise("updateConnectionParam")
323+ UpdateConnectionParamSync(param: ConnectionParam): void;
324+ 
325+ OnBLEConnectionStateChange(callback:(data: BLEConnectionChangeState) => void): void;
326+ OffBLEConnectionStateChange(callback: Optional<(data: BLEConnectionChangeState) => void>): void;
327+ 
328+ GetConnectedState(): ProfileConnectionState;
329+}
330+ 
331+enum ConnectionParam : i32 {
332+ LOW_POWER = 1,
333+ BALANCED = 2,
334+ HIGH = 3
262}335}
263 336 
264function CreateGattClientDevice(deviceId: String): GattClientDevice;337function CreateGattClientDevice(deviceId: String): GattClientDevice;
@@ -274,6 +347,43 @@ interface GattServer {
274 347 
275 @rename("notifyCharacteristicChanged")348 @rename("notifyCharacteristicChanged")
276 NotifyCharacteristicChangedAsync(deviceId: String, notifyCharacteristic: NotifyCharacteristic, callback: @sts_type("AsyncCallback<void>") Opaque): void;349 NotifyCharacteristicChangedAsync(deviceId: String, notifyCharacteristic: NotifyCharacteristic, callback: @sts_type("AsyncCallback<void>") Opaque): void;
350+ 
351+ OnBlePhyUpdate(callback:(data: PhyValue) => void): void;
352+ OffBlePhyUpdate(callback: Optional<(data: PhyValue) => void>): void;
353+ 
354+ @gen_promise("setPhy")
355+ SetPhySync(deviceId: String, phyValue: PhyValue): void;
356+ 
357+ @gen_promise("readPhy")
358+ ReadPhySync(deviceId: String): PhyValue;
359+ 
360+ OnBLEMtuChange(callback:(data: i32) => void): void;
361+ OffBLEMtuChange(callback: Optional<(data: i32) => void>): void;
362+ 
363+ Disconnect(deviceId: String): void;
364+ Connect(deviceId: String, autoConnect: Optional<bool>): void;
365+ 
366+ OnCharacteristicRead(callback:(data: CharacteristicReadRequest) => void): void;
367+ OffCharacteristicRead(callback: Optional<(data: CharacteristicReadRequest) => void>): void;
368+ 
369+ OnCharacteristicWrite(callback:(data: CharacteristicWriteRequest) => void): void;
370+ OffCharacteristicWrite(callback: Optional<(data: CharacteristicWriteRequest) => void>): void;
371+ 
372+ GetConnectedState(deviceId: String): ProfileConnectionState;
373+ 
374+ GetService(serviceUuid: String): GattService;
375+ 
376+ OnConnectionStateChange(callback:(data: BLEConnectionChangeState) => void): void;
377+ OffConnectionStateChange(callback: Optional<(data: BLEConnectionChangeState) => void>): void;
378+ 
379+ OnDescriptorWrite(callback:(data: DescriptorWriteRequest) => void): void;
380+ OffDescriptorWrite(callback: Optional<(data: DescriptorWriteRequest) => void>): void;
381+ 
382+ OnDescriptorRead(callback:(data: DescriptorReadRequest) => void): void;
383+ OffDescriptorRead(callback: Optional<(data: DescriptorReadRequest) => void>): void;
384+ 
385+ RemoveAllServices(): void;
386+ GetServices(): Array<GattService>;
277}387}
278 388 
279function CreateGattServer(): GattServer;389function CreateGattServer(): GattServer;
@@ -318,12 +428,37 @@ struct AdvertisingDisableParams {
318 advertisingId: i32;428 advertisingId: i32;
319}429}
320 430 
431+struct PhyValue {
432+ txPhy: BlePhy;
433+ rxPhy: BlePhy;
434+ phyMode: Optional<CodedPhyMode>;
435+}
436+ 
437+struct GattRspContext {
438+ timestamp: i64;
439+}
440+ 
441+enum BlePhy: i32 {
442+ BLE_PHY_1M = 1,
443+ BLE_PHY_2M = 2,
444+ BLE_PHY_CODED = 3,
445+}
446+ 
447+enum CodedPhyMode: i32 {
448+ BLE_PHY_CODED_S2 = 1,
449+ BLE_PHY_CODED_S8 = 2
450+}
451+ 
452+ 
321interface BleScanner {453interface BleScanner {
322 @rename("startScan")454 @rename("startScan")
323 StartScanPromise(filters: ScanFilterNullValue, options: Optional<ScanOptions>): @sts_type("Promise<void>") Opaque;455 StartScanPromise(filters: ScanFilterNullValue, options: Optional<ScanOptions>): @sts_type("Promise<void>") Opaque;
324 456 
325 @rename("stopScan")457 @rename("stopScan")
326 StopScanPromise(): @sts_type("Promise<void>") Opaque;458 StopScanPromise(): @sts_type("Promise<void>") Opaque;
459+ 
460+ OnBLEDeviceFind(callback:(data: ScanReport) => void): void;
461+ OffBleDeviceFind(callback: Optional<(data: ScanReport) => void>): void;
327}462}
328 463 
329function CreateBleScanner(): BleScanner;464function CreateBleScanner(): BleScanner;
@@ -25,6 +25,7 @@
25#include "stdexcept"25#include "stdexcept"
26#include "taihe_async_callback.h"26#include "taihe_async_callback.h"
27#include "taihe/runtime.hpp"27#include "taihe/runtime.hpp"
28+#include "taihe_event_module.h"
28 29 
29namespace OHOS {30namespace OHOS {
30namespace Bluetooth {31namespace Bluetooth {
@@ -45,6 +46,8 @@ public:
45 46 
46 TaiheAsyncWorkMap asyncWorkMap_ {};47 TaiheAsyncWorkMap asyncWorkMap_ {};
47 48 
49+ EventModule<void(::ohos::bluetooth::ble::AdvertisingStateChangeInfo const&)> advertisingStateChangeEvent_ {};
50+ 
48 int advHandle_ = -1;51 int advHandle_ = -1;
49};52};
50} // namespace Bluetooth53} // namespace Bluetooth
@@ -17,8 +17,12 @@
17#define TAIHE_BLUETOOTH_BLE_CENTRAL_MANAGER_H17#define TAIHE_BLUETOOTH_BLE_CENTRAL_MANAGER_H
18 18 
19#include "bluetooth_ble_central_manager.h"19#include "bluetooth_ble_central_manager.h"
20+#include "ohos.bluetooth.ble.impl.hpp"
21+#include "ohos.bluetooth.ble.proj.hpp"
22+#include "taihe/runtime.hpp"
20#include "taihe_async_callback.h"23#include "taihe_async_callback.h"
21#include "taihe_bluetooth_ble_utils.h"24#include "taihe_bluetooth_ble_utils.h"
25+#include "taihe_event_module.h"
22 26 
23namespace OHOS {27namespace OHOS {
24namespace Bluetooth {28namespace Bluetooth {
@@ -38,6 +42,9 @@ public:
38 void ConvertScanReportType(ScanReportType &scanReportType, uint8_t callbackType);42 void ConvertScanReportType(ScanReportType &scanReportType, uint8_t callbackType);
39 TaiheAsyncWorkMap asyncWorkMap_ {};43 TaiheAsyncWorkMap asyncWorkMap_ {};
40 bool isLatestTaiheBleScannerObj_ = false;44 bool isLatestTaiheBleScannerObj_ = false;
45+ 
46+ EventModule<void(::ohos::bluetooth::ble::ScanReport const&)> bleDeviceFindEvent_ {};
47+ EventModule<void(::taihe::array_view<::ohos::bluetooth::ble::ScanResult>)> moduleBleDeviceFindEvent_ {};
41};48};
42} // namespace Bluetooth49} // namespace Bluetooth
43} // namespace OHOS50} // namespace OHOS
@@ -30,6 +30,8 @@ public:
30 uintptr_t StartScanPromise(const ohos::bluetooth::ble::ScanFilterNullValue &filters,30 uintptr_t StartScanPromise(const ohos::bluetooth::ble::ScanFilterNullValue &filters,
31 taihe::optional_view<ohos::bluetooth::ble::ScanOptions> options);31 taihe::optional_view<ohos::bluetooth::ble::ScanOptions> options);
32 uintptr_t StopScanPromise();32 uintptr_t StopScanPromise();
33+ void OnBLEDeviceFind(::taihe::callback_view<void(::ohos::bluetooth::ble::ScanReport const& data)> callback);
34+ void OffBleDeviceFind(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::ScanReport const& data)>> callback);
33 35 
34 const std::shared_ptr<BleCentralManager> &GetBleCentralManager()36 const std::shared_ptr<BleCentralManager> &GetBleCentralManager()
35 {37 {
@@ -47,6 +47,47 @@ public:
47 taihe::string GetDeviceNameSync();47 taihe::string GetDeviceNameSync();
48 static int GattStatusFromService(int status);48 static int GattStatusFromService(int status);
49 49 
50+ ::ohos::bluetooth::ble::PhyValue ReadPhySync();
51+ void SetPhySync(::ohos::bluetooth::ble::PhyValue const& phyValue);
52+ ::ohos::bluetooth::ble::GattRspContext WriteCharacteristicValueWithContextSync(
53+ ::ohos::bluetooth::ble::BLECharacteristic const& characteristic,
54+ ::ohos::bluetooth::ble::GattWriteType writeType);
55+ void WriteDescriptorValueSync(::ohos::bluetooth::ble::BLEDescriptor const& descriptor);
56+ ::taihe::array<::ohos::bluetooth::ble::GattService> GetServicesSync();
57+ 
58+ void OnBlePhyUpdate(::taihe::callback_view<void(::ohos::bluetooth::ble::PhyValue const& data)> callback);
59+ void OffBlePhyUpdate(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::PhyValue const& data)>> callback);
60+ 
61+ void SetCharacteristicChangeNotificationSync(
62+ ::ohos::bluetooth::ble::BLECharacteristic const& characteristic, bool enable);
63+ 
64+ int32_t GetRssiValueSync();
65+ int32_t SetBLEMtuSync(int32_t mtu);
66+ 
67+ void WriteCharacteristicValueSync(
68+ ::ohos::bluetooth::ble::BLECharacteristic const& characteristic,
69+ ::ohos::bluetooth::ble::GattWriteType writeType);
70+ 
71+ void OnBLEMtuChange(::taihe::callback_view<void(int32_t data)> callback);
72+ void OffBLEMtuChange(::taihe::optional_view<::taihe::callback<void(int32_t data)>> callback);
73+ 
74+ void OnServiceChange(::taihe::callback_view<void()> callback);
75+ void OffServiceChange(::taihe::optional_view<::taihe::callback<void()>> callback);
76+ 
77+ void OnBLECharacteristicChange(
78+ ::taihe::callback_view<void(::ohos::bluetooth::ble::BLECharacteristic const& data)> callback);
79+ void OffBLECharacteristicChange(
80+ ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLECharacteristic const& data)>> callback);
81+ 
82+ void UpdateConnectionParamSync(::ohos::bluetooth::ble::ConnectionParam param);
83+ 
84+ void OnBLEConnectionStateChange(
85+ ::taihe::callback_view<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)> callback);
86+ void OffBLEConnectionStateChange(
87+ ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)>> callback);
88+ 
89+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectedState();
90+ 
50 std::shared_ptr<GattClient> &GetClient()91 std::shared_ptr<GattClient> &GetClient()
51 {92 {
52 return client_;93 return client_;
@@ -16,6 +16,7 @@
16#ifndef TAIHE_BLUETOOTH_GATT_CLIENT_CALLBACK_H_16#ifndef TAIHE_BLUETOOTH_GATT_CLIENT_CALLBACK_H_
17#define TAIHE_BLUETOOTH_GATT_CLIENT_CALLBACK_H_17#define TAIHE_BLUETOOTH_GATT_CLIENT_CALLBACK_H_
18 18 
19+#include <future>
19#include <shared_mutex>20#include <shared_mutex>
20 21 
21#include "bluetooth_gatt_client.h"22#include "bluetooth_gatt_client.h"
@@ -24,6 +25,7 @@
24#include "stdexcept"25#include "stdexcept"
25#include "taihe_async_callback.h"26#include "taihe_async_callback.h"
26#include "taihe/runtime.hpp"27#include "taihe/runtime.hpp"
28+#include "taihe_event_module.h"
27 29 
28namespace OHOS {30namespace OHOS {
29namespace Bluetooth {31namespace Bluetooth {
@@ -40,6 +42,9 @@ public:
40 void OnConnectionParameterChanged(int interval, int latency, int timeout, int status) override {}42 void OnConnectionParameterChanged(int interval, int latency, int timeout, int status) override {}
41 void OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status) override;43 void OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status) override;
42 void OnReadRemoteRssiValueResult(int rssi, int status) override;44 void OnReadRemoteRssiValueResult(int rssi, int status) override;
45+ void OnBlePhyUpdate(int32_t txPhy, int32_t rxPhy, int32_t status) override;
46+ void OnBlePhyRead(int32_t txPhy, int32_t rxPhy, int32_t status) override;
47+ void OnServicesChanged() override;
43 48 
44 std::string GetDeviceAddr(void)49 std::string GetDeviceAddr(void)
45 {50 {
@@ -55,6 +60,19 @@ public:
55 ~TaiheGattClientCallback() override = default;60 ~TaiheGattClientCallback() override = default;
56 61 
57 TaiheAsyncWorkMap asyncWorkMap_ {};62 TaiheAsyncWorkMap asyncWorkMap_ {};
63+ 
64+ // Promise for synchronous GetRssiValueSync - resolved by OnReadRemoteRssiValueResult
65+ std::shared_ptr<std::promise<int32_t>> rssiValuePromise_ = nullptr;
66+ std::mutex rssiValuePromiseLock_;
67+ // Promise for synchronous SetBLEMtuSync - resolved by OnMtuUpdate
68+ std::shared_ptr<std::promise<int32_t>> mtuValuePromise_ = nullptr;
69+ std::mutex mtuValuePromiseLock_;
70+ 
71+ EventModule<void(::ohos::bluetooth::ble::PhyValue const&)> blePhyUpdateEvent_ {};
72+ EventModule<void(int32_t)> bleMtuChangeEvent_ {};
73+ EventModule<void()> serviceChangeEvent_ {};
74+ EventModule<void(::ohos::bluetooth::ble::BLECharacteristic const&)> bleCharacteristicChangeEvent_ {};
75+ EventModule<void(::ohos::bluetooth::ble::BLEConnectionChangeState const&)> bleConnectionStateChangeEvent_ {};
58private:76private:
59 std::string deviceAddr_ = INVALID_MAC_ADDRESS;77 std::string deviceAddr_ = INVALID_MAC_ADDRESS;
60};78};
@@ -37,6 +37,28 @@ public:
37 const ohos::bluetooth::ble::NotifyCharacteristic &notifyCharacteristic);37 const ohos::bluetooth::ble::NotifyCharacteristic &notifyCharacteristic);
38 void NotifyCharacteristicChangedAsync(taihe::string_view deviceId,38 void NotifyCharacteristicChangedAsync(taihe::string_view deviceId,
39 const ohos::bluetooth::ble::NotifyCharacteristic &notifyCharacteristic, uintptr_t callback);39 const ohos::bluetooth::ble::NotifyCharacteristic &notifyCharacteristic, uintptr_t callback);
40+ void OnBlePhyUpdate(::taihe::callback_view<void(::ohos::bluetooth::ble::PhyValue const& data)> callback);
41+ void OffBlePhyUpdate(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::PhyValue const& data)>> callback);
42+ void SetPhySync(::taihe::string_view deviceId, ::ohos::bluetooth::ble::PhyValue const& phyValue);
43+ ::ohos::bluetooth::ble::PhyValue ReadPhySync(::taihe::string_view deviceId);
44+ void OnBLEMtuChange(::taihe::callback_view<void(int32_t data)> callback);
45+ void OffBLEMtuChange(::taihe::optional_view<::taihe::callback<void(int32_t data)>> callback);
46+ void Disconnect(::taihe::string_view deviceId);
47+ void Connect(::taihe::string_view deviceId, ::taihe::optional_view<bool> autoConnect);
48+ void OnCharacteristicRead(::taihe::callback_view<void(::ohos::bluetooth::ble::CharacteristicReadRequest const& data)> callback);
49+ void OffCharacteristicRead(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::CharacteristicReadRequest const& data)>> callback);
50+ void OnCharacteristicWrite(::taihe::callback_view<void(::ohos::bluetooth::ble::CharacteristicWriteRequest const& data)> callback);
51+ void OffCharacteristicWrite(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::CharacteristicWriteRequest const& data)>> callback);
52+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectedState(::taihe::string_view deviceId);
53+ ::ohos::bluetooth::ble::GattService GetService(::taihe::string_view serviceUuid);
54+ void OnConnectionStateChange(::taihe::callback_view<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)> callback);
55+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)>> callback);
56+ void OnDescriptorWrite(::taihe::callback_view<void(::ohos::bluetooth::ble::DescriptorWriteRequest const& data)> callback);
57+ void OffDescriptorWrite(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::DescriptorWriteRequest const& data)>> callback);
58+ void OnDescriptorRead(::taihe::callback_view<void(::ohos::bluetooth::ble::DescriptorReadRequest const& data)> callback);
59+ void OffDescriptorRead(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::DescriptorReadRequest const& data)>> callback);
60+ void RemoveAllServices();
61+ ::taihe::array<::ohos::bluetooth::ble::GattService> GetServices();
40 62 
41 std::shared_ptr<GattServer> &GetServer()63 std::shared_ptr<GattServer> &GetServer()
42 {64 {
@@ -17,13 +17,19 @@
17#define TAIHE_BLUETOOTH_GATT_SERVER_CALLBACK_H_17#define TAIHE_BLUETOOTH_GATT_SERVER_CALLBACK_H_
18 18 
19#include "bluetooth_gatt_server.h"19#include "bluetooth_gatt_server.h"
20+#include "ohos.bluetooth.ble.impl.hpp"
21+#include "ohos.bluetooth.ble.proj.hpp"
22+#include "taihe/runtime.hpp"
20#include "taihe_async_callback.h"23#include "taihe_async_callback.h"
24+#include "taihe_event_module.h"
21 25 
22namespace OHOS {26namespace OHOS {
23namespace Bluetooth {27namespace Bluetooth {
24class TaiheGattServerCallback : public GattServerCallback {28class TaiheGattServerCallback : public GattServerCallback {
25public:29public:
26 void OnConnectionStateUpdate(const BluetoothRemoteDevice &device, int state) override;30 void OnConnectionStateUpdate(const BluetoothRemoteDevice &device, int state) override;
31+ void OnConnectionStateUpdateWithMessage(const BluetoothRemoteDevice &device, int state,
32+ GattDisconnectParam disconnectParam) override;
27 void OnServiceAdded(GattService service, int ret) override {}33 void OnServiceAdded(GattService service, int ret) override {}
28 void OnCharacteristicReadRequest(const BluetoothRemoteDevice &device,34 void OnCharacteristicReadRequest(const BluetoothRemoteDevice &device,
29 GattCharacteristic &characteristic, int requestId) override;35 GattCharacteristic &characteristic, int requestId) override;
@@ -38,10 +44,21 @@ public:
38 int result) override;44 int result) override;
39 void OnConnectionParameterChanged(const BluetoothRemoteDevice &device,45 void OnConnectionParameterChanged(const BluetoothRemoteDevice &device,
40 int interval, int latency, int timeout, int status) override {}46 int interval, int latency, int timeout, int status) override {}
47+ void OnBlePhyUpdate(const BluetoothRemoteDevice &device,
48+ int32_t txPhy, int32_t rxPhy, int32_t status) override;
49+ void OnBlePhyRead(int32_t txPhy, int32_t rxPhy, int32_t status) override;
41 50 
42 TaiheAsyncWorkMap asyncWorkMap_ {};51 TaiheAsyncWorkMap asyncWorkMap_ {};
43 TaiheGattServerCallback();52 TaiheGattServerCallback();
44 ~TaiheGattServerCallback() override = default;53 ~TaiheGattServerCallback() override = default;
54+ 
55+ EventModule<void(::ohos::bluetooth::ble::PhyValue const&)> blePhyUpdateEvent_ {};
56+ EventModule<void(int32_t)> bleMtuChangeEvent_ {};
57+ EventModule<void(::ohos::bluetooth::ble::CharacteristicReadRequest const&)> characteristicReadEvent_ {};
58+ EventModule<void(::ohos::bluetooth::ble::CharacteristicWriteRequest const&)> characteristicWriteEvent_ {};
59+ EventModule<void(::ohos::bluetooth::ble::DescriptorWriteRequest const&)> descriptorWriteEvent_ {};
60+ EventModule<void(::ohos::bluetooth::ble::DescriptorReadRequest const&)> descriptorReadEvent_ {};
61+ EventModule<void(::ohos::bluetooth::ble::BLEConnectionChangeState const&)> connectionStateChangeEvent_ {};
45};62};
46} // namespace Bluetooth63} // namespace Bluetooth
47} // namespace OHOS64} // namespace OHOS
@@ -25,12 +25,14 @@
25#include "bluetooth_utils.h"25#include "bluetooth_utils.h"
26#include "stdexcept"26#include "stdexcept"
27#include "taihe_bluetooth_ble_advertise_callback.h"27#include "taihe_bluetooth_ble_advertise_callback.h"
28+#include "taihe_bluetooth_ble_central_manager_callback.h"
28#include "taihe_bluetooth_ble_scanner.h"29#include "taihe_bluetooth_ble_scanner.h"
29#include "taihe_bluetooth_ble_utils.h"30#include "taihe_bluetooth_ble_utils.h"
30#include "taihe_bluetooth_error.h"31#include "taihe_bluetooth_error.h"
31#include "taihe_bluetooth_gatt_client.h"32#include "taihe_bluetooth_gatt_client.h"
32#include "taihe_bluetooth_gatt_server.h"33#include "taihe_bluetooth_gatt_server.h"
33#include "taihe_bluetooth_utils.h"34#include "taihe_bluetooth_utils.h"
35+#include "taihe_event_module.h"
34#include "taihe_parser_utils.h"36#include "taihe_parser_utils.h"
35#include "taihe/array.hpp"37#include "taihe/array.hpp"
36#include "taihe/optional.hpp"38#include "taihe/optional.hpp"
@@ -681,6 +683,38 @@ void EnableAdvertisingAsync(const ohos::bluetooth::ble::AdvertisingEnableParams
681 TAIHE_BT_ASSERT_RETURN_VOID(false, result.errorCode);683 TAIHE_BT_ASSERT_RETURN_VOID(false, result.errorCode);
682 }684 }
683}685}
686+ 
687+void StopAdvertisingSync(int32_t advertisingId) {
688+ HILOGI("enter, advertisingId: %{public}d", advertisingId);
689+ std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
690+ TAIHE_BT_ASSERT_RETURN_VOID(bleAdvertiser != nullptr, BT_ERR_INTERNAL_ERROR);
691+ 
692+ auto callback = bleAdvertiser->GetAdvObserver(static_cast<uint32_t>(advertisingId));
693+ TAIHE_BT_ASSERT_RETURN_VOID(callback != nullptr, BT_ERR_INVALID_PARAM);
694+ 
695+ int ret = bleAdvertiser->StopAdvertising(callback);
696+ TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
697+}
698+ 
699+void OnAdvertisingStateChange(::taihe::callback_view<void(::ohos::bluetooth::ble::AdvertisingStateChangeInfo const& data)> callback) {
700+ HILOGI("enter");
701+ TaiheBluetoothBleAdvertiseCallback::GetInstance()->advertisingStateChangeEvent_.RegisterEvent(callback);
702+}
703+ 
704+void OffAdvertisingStateChange(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::AdvertisingStateChangeInfo const& data)>> callback) {
705+ HILOGI("enter");
706+ TaiheBluetoothBleAdvertiseCallback::GetInstance()->advertisingStateChangeEvent_.DeregisterEvent(callback);
707+}
708+ 
709+void OnBleDeviceFind(::taihe::callback_view<void(::taihe::array_view<::ohos::bluetooth::ble::ScanResult> data)> callback) {
710+ HILOGI("enter");
711+ TaiheBluetoothBleCentralManagerCallback::GetInstance().moduleBleDeviceFindEvent_.RegisterEvent(callback);
712+}
713+ 
714+void OffBLEDeviceFind(::taihe::optional_view<::taihe::callback<void(::taihe::array_view<::ohos::bluetooth::ble::ScanResult> data)>> callback) {
715+ HILOGI("enter");
716+ TaiheBluetoothBleCentralManagerCallback::GetInstance().moduleBleDeviceFindEvent_.DeregisterEvent(callback);
717+}
684} // Bluetooth718} // Bluetooth
685} // OHOS719} // OHOS
686 720 
@@ -700,4 +734,9 @@ TH_EXPORT_CPP_API_DisableAdvertisingPromise(OHOS::Bluetooth::DisableAdvertisingP
700TH_EXPORT_CPP_API_DisableAdvertisingAsync(OHOS::Bluetooth::DisableAdvertisingAsync);734TH_EXPORT_CPP_API_DisableAdvertisingAsync(OHOS::Bluetooth::DisableAdvertisingAsync);
701TH_EXPORT_CPP_API_EnableAdvertisingPromise(OHOS::Bluetooth::EnableAdvertisingPromise);735TH_EXPORT_CPP_API_EnableAdvertisingPromise(OHOS::Bluetooth::EnableAdvertisingPromise);
702TH_EXPORT_CPP_API_EnableAdvertisingAsync(OHOS::Bluetooth::EnableAdvertisingAsync);736TH_EXPORT_CPP_API_EnableAdvertisingAsync(OHOS::Bluetooth::EnableAdvertisingAsync);
737+TH_EXPORT_CPP_API_StopAdvertisingSync(OHOS::Bluetooth::StopAdvertisingSync);
738+TH_EXPORT_CPP_API_OnAdvertisingStateChange(OHOS::Bluetooth::OnAdvertisingStateChange);
739+TH_EXPORT_CPP_API_OffAdvertisingStateChange(OHOS::Bluetooth::OffAdvertisingStateChange);
740+TH_EXPORT_CPP_API_OnBleDeviceFind(OHOS::Bluetooth::OnBleDeviceFind);
741+TH_EXPORT_CPP_API_OffBLEDeviceFind(OHOS::Bluetooth::OffBLEDeviceFind);
703// NOLINTEND742// NOLINTEND
@@ -43,6 +43,11 @@ void TaiheBluetoothBleAdvertiseCallback::OnStartResultEvent(int result, int advH
43 auto taiheAdvHandle = std::make_shared<TaiheNativeInt>(advHandle);43 auto taiheAdvHandle = std::make_shared<TaiheNativeInt>(advHandle);
44 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GET_ADVERTISING_HANDLE, taiheAdvHandle, result);44 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GET_ADVERTISING_HANDLE, taiheAdvHandle, result);
45 }45 }
46+ ::ohos::bluetooth::ble::AdvertisingStateChangeInfo info{
47+ advHandle,
48+ ::ohos::bluetooth::ble::AdvertisingState(::ohos::bluetooth::ble::AdvertisingState::key_t::STARTED)
49+ };
50+ advertisingStateChangeEvent_.PublishEvent(info);
46}51}
47 52 
48void TaiheBluetoothBleAdvertiseCallback::OnEnableResultEvent(int result, int advHandle)53void TaiheBluetoothBleAdvertiseCallback::OnEnableResultEvent(int result, int advHandle)
@@ -54,6 +59,11 @@ void TaiheBluetoothBleAdvertiseCallback::OnEnableResultEvent(int result, int adv
54 auto taiheAdvResult = std::make_shared<TaiheNativeInt>(result);59 auto taiheAdvResult = std::make_shared<TaiheNativeInt>(result);
55 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::BLE_ENABLE_ADVERTISING, taiheAdvResult, result);60 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::BLE_ENABLE_ADVERTISING, taiheAdvResult, result);
56 }61 }
62+ ::ohos::bluetooth::ble::AdvertisingStateChangeInfo info{
63+ advHandle,
64+ ::ohos::bluetooth::ble::AdvertisingState(::ohos::bluetooth::ble::AdvertisingState::key_t::ENABLED)
65+ };
66+ advertisingStateChangeEvent_.PublishEvent(info);
57}67}
58 68 
59void TaiheBluetoothBleAdvertiseCallback::OnDisableResultEvent(int result, int advHandle)69void TaiheBluetoothBleAdvertiseCallback::OnDisableResultEvent(int result, int advHandle)
@@ -65,11 +75,21 @@ void TaiheBluetoothBleAdvertiseCallback::OnDisableResultEvent(int result, int ad
65 auto taiheAdvResult = std::make_shared<TaiheNativeInt>(result);75 auto taiheAdvResult = std::make_shared<TaiheNativeInt>(result);
66 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::BLE_DISABLE_ADVERTISING, taiheAdvResult, result);76 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::BLE_DISABLE_ADVERTISING, taiheAdvResult, result);
67 }77 }
78+ ::ohos::bluetooth::ble::AdvertisingStateChangeInfo info{
79+ advHandle,
80+ ::ohos::bluetooth::ble::AdvertisingState(::ohos::bluetooth::ble::AdvertisingState::key_t::DISABLED)
81+ };
82+ advertisingStateChangeEvent_.PublishEvent(info);
68}83}
69 84 
70void TaiheBluetoothBleAdvertiseCallback::OnStopResultEvent(int result, int advHandle)85void TaiheBluetoothBleAdvertiseCallback::OnStopResultEvent(int result, int advHandle)
71{86{
72 HILOGI("enter, result: %{public}d advHandle: %{public}d", result, advHandle);87 HILOGI("enter, result: %{public}d advHandle: %{public}d", result, advHandle);
88+ ::ohos::bluetooth::ble::AdvertisingStateChangeInfo info{
89+ advHandle,
90+ ::ohos::bluetooth::ble::AdvertisingState(::ohos::bluetooth::ble::AdvertisingState::key_t::STOPPED)
91+ };
92+ advertisingStateChangeEvent_.PublishEvent(info);
73}93}
74 94 
75void TaiheBluetoothBleAdvertiseCallback::OnSetAdvDataEvent(int result)95void TaiheBluetoothBleAdvertiseCallback::OnSetAdvDataEvent(int result)
@@ -33,19 +33,76 @@ TaiheBluetoothBleCentralManagerCallback &TaiheBluetoothBleCentralManagerCallback
33 return instance;33 return instance;
34}34}
35 35 
36+static ::ohos::bluetooth::ble::ScanResult ConvertScanResultItem(const BleScanResult &result)
37+{
38+ auto payload = result.GetPayload();
39+ BleScanResult &mutableResult = const_cast<BleScanResult &>(result);
40+ return ::ohos::bluetooth::ble::ScanResult{
41+ taihe::string(result.GetPeripheralDevice().GetDeviceAddr()),
42+ result.GetRssi(),
43+ taihe::array<uint8_t>(taihe::copy_data, payload.data(), payload.size()),
44+ taihe::string(mutableResult.GetName()),
45+ result.IsConnectable()
46+ };
47+}
48+ 
49+static ::ohos::bluetooth::ble::ScanReport ConvertScanResult(const BleScanResult &result,
50+ ::ohos::bluetooth::ble::ScanReportType reportType)
51+{
52+ std::vector<::ohos::bluetooth::ble::ScanResult> resultVec;
53+ resultVec.push_back(ConvertScanResultItem(result));
54+ ::ohos::bluetooth::ble::ScanReport scanReport{
55+ reportType,
56+ taihe::array<::ohos::bluetooth::ble::ScanResult>(
57+ taihe::move_data, resultVec.data(), resultVec.size())
58+ };
59+ return scanReport;
60+}
61+ 
36void TaiheBluetoothBleCentralManagerCallback::OnScanCallback(const BleScanResult &result)62void TaiheBluetoothBleCentralManagerCallback::OnScanCallback(const BleScanResult &result)
37{63{
38 HILOGD("enter, remote device address: %{public}s", GET_ENCRYPT_ADDR(result.GetPeripheralDevice()));64 HILOGD("enter, remote device address: %{public}s", GET_ENCRYPT_ADDR(result.GetPeripheralDevice()));
65+ if (isLatestTaiheBleScannerObj_) {
66+ auto scanReport = ConvertScanResult(result,
67+ ::ohos::bluetooth::ble::ScanReportType(::ohos::bluetooth::ble::ScanReportType::key_t::ON_FOUND));
68+ bleDeviceFindEvent_.PublishEvent(scanReport);
69+ } else {
70+ std::vector<::ohos::bluetooth::ble::ScanResult> resultVec;
71+ resultVec.push_back(ConvertScanResultItem(result));
72+ taihe::array<::ohos::bluetooth::ble::ScanResult> results(
73+ taihe::move_data, resultVec.data(), resultVec.size());
74+ moduleBleDeviceFindEvent_.PublishEvent(results);
75+ }
39}76}
40 77 
41void TaiheBluetoothBleCentralManagerCallback::OnFoundOrLostCallback(const BleScanResult &result, uint8_t callbackType)78void TaiheBluetoothBleCentralManagerCallback::OnFoundOrLostCallback(const BleScanResult &result, uint8_t callbackType)
42{79{
43 HILOGD("enter, remote device address: %{public}s", GET_ENCRYPT_ADDR(result.GetPeripheralDevice()));80 HILOGD("enter, remote device address: %{public}s", GET_ENCRYPT_ADDR(result.GetPeripheralDevice()));
81+ ScanReportType scanReportType = ScanReportType::ON_FOUND;
82+ ConvertScanReportType(scanReportType, callbackType);
83+ if (isLatestTaiheBleScannerObj_) {
84+ auto scanReport = ConvertScanResult(result,
85+ ::ohos::bluetooth::ble::ScanReportType::from_value(static_cast<int32_t>(scanReportType)));
86+ bleDeviceFindEvent_.PublishEvent(scanReport);
87+ }
44}88}
45 89 
46void TaiheBluetoothBleCentralManagerCallback::OnBleBatchScanResultsEvent(const std::vector<BleScanResult> &results)90void TaiheBluetoothBleCentralManagerCallback::OnBleBatchScanResultsEvent(const std::vector<BleScanResult> &results)
47{91{
48 HILOGI("enter, scan result size: %{public}zu", results.size());92 HILOGI("enter, scan result size: %{public}zu", results.size());
93+ if (isLatestTaiheBleScannerObj_ && !results.empty()) {
94+ std::vector<::ohos::bluetooth::ble::ScanResult> resultVec;
95+ resultVec.reserve(results.size());
96+ for (size_t i = 0; i < results.size(); i++) {
97+ resultVec.push_back(ConvertScanResultItem(results[i]));
98+ }
99+ ::ohos::bluetooth::ble::ScanReport scanReport{
100+ ::ohos::bluetooth::ble::ScanReportType(::ohos::bluetooth::ble::ScanReportType::key_t::ON_FOUND),
101+ taihe::array<::ohos::bluetooth::ble::ScanResult>(
102+ taihe::move_data, resultVec.data(), resultVec.size())
103+ };
104+ bleDeviceFindEvent_.PublishEvent(scanReport);
105+ }
49}106}
50 107 
51void TaiheBluetoothBleCentralManagerCallback::OnStartOrStopScanEvent(int resultCode, bool isStartScan)108void TaiheBluetoothBleCentralManagerCallback::OnStartOrStopScanEvent(int resultCode, bool isStartScan)
@@ -94,5 +94,17 @@ uintptr_t BleScannerImpl::StopScanPromise()
94 asyncWork->Run();94 asyncWork->Run();
95 return reinterpret_cast<uintptr_t>(asyncWork->GetRet());95 return reinterpret_cast<uintptr_t>(asyncWork->GetRet());
96}96}
97+void BleScannerImpl::OnBLEDeviceFind(::taihe::callback_view<void(::ohos::bluetooth::ble::ScanReport const& data)> callback) {
98+ HILOGI("enter");
99+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
100+ callback_->bleDeviceFindEvent_.RegisterEvent(callback);
101+}
102+ 
103+void BleScannerImpl::OffBleDeviceFind(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::ScanReport const& data)>> callback) {
104+ HILOGI("enter");
105+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
106+ callback_->bleDeviceFindEvent_.DeregisterEvent(callback);
107+}
108+ 
97} // namespace Bluetooth109} // namespace Bluetooth
98} // namespace OHOS110} // namespace OHOS
@@ -19,6 +19,9 @@
19 19 
20#include "taihe_bluetooth_gatt_client.h"20#include "taihe_bluetooth_gatt_client.h"
21 21 
22+#include <chrono>
23+#include <future>
24+ 
22#include "bluetooth_host.h"25#include "bluetooth_host.h"
23#include "bluetooth_utils.h"26#include "bluetooth_utils.h"
24#include "taihe_bluetooth_ble_utils.h"27#include "taihe_bluetooth_ble_utils.h"
@@ -28,6 +31,7 @@
28 31 
29namespace OHOS {32namespace OHOS {
30namespace Bluetooth {33namespace Bluetooth {
34+constexpr int32_t BLE_SYNC_TIMEOUT_SECONDS = 10;
31const std::vector<std::pair<int, int>> GattClientDeviceImpl::g_gattStatusSrvToTaihe = {35const std::vector<std::pair<int, int>> GattClientDeviceImpl::g_gattStatusSrvToTaihe = {
32 { Bluetooth::BT_NO_ERROR, GATT_SUCCESS },36 { Bluetooth::BT_NO_ERROR, GATT_SUCCESS },
33 { Bluetooth::BT_ERR_GATT_WRITE_NOT_PERMITTED, WRITE_NOT_PERMITTED },37 { Bluetooth::BT_ERR_GATT_WRITE_NOT_PERMITTED, WRITE_NOT_PERMITTED },
@@ -390,5 +394,414 @@ int GattClientDeviceImpl::GattStatusFromService(int status)
390 }394 }
391 return ret;395 return ret;
392}396}
397+ 
398+::ohos::bluetooth::ble::PhyValue GattClientDeviceImpl::ReadPhySync() {
399+ HILOGI("enter");
400+ TAIHE_BT_ASSERT_RETURN(client_ != nullptr, BT_ERR_INTERNAL_ERROR,
401+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
402+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
403+ TAIHE_BT_ASSERT_RETURN(callback_ != nullptr, BT_ERR_INTERNAL_ERROR,
404+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
405+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
406+ 
407+ auto func = [gattClient = client_]() {
408+ int ret = BT_ERR_INTERNAL_ERROR;
409+ if (gattClient) {
410+ ret = gattClient->ReadPhy();
411+ }
412+ return TaiheAsyncWorkRet(ret);
413+ };
414+ 
415+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(taihe::get_env(), nullptr, func);
416+ TAIHE_BT_ASSERT_RETURN(asyncWork, BT_ERR_INTERNAL_ERROR,
417+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
418+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
419+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_CLIENT_READ_PHY, asyncWork);
420+ TAIHE_BT_ASSERT_RETURN(success, BT_ERR_INTERNAL_ERROR,
421+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
422+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
423+ 
424+ asyncWork->Run();
425+ 
426+ return ::ohos::bluetooth::ble::PhyValue{
427+ ::ohos::bluetooth::ble::BlePhy::from_value(0),
428+ ::ohos::bluetooth::ble::BlePhy::from_value(0)
429+ };
430+}
431+ 
432+void GattClientDeviceImpl::SetPhySync(::ohos::bluetooth::ble::PhyValue const& phyValue) {
433+ HILOGI("enter");
434+ TAIHE_BT_ASSERT_RETURN_VOID(client_ != nullptr, BT_ERR_INTERNAL_ERROR);
435+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
436+ 
437+ auto func = [gattClient = client_, phyValue]() {
438+ int ret = BT_ERR_INTERNAL_ERROR;
439+ if (gattClient) {
440+ ret = gattClient->SetPhy(phyValue.txPhy, phyValue.rxPhy,
441+ phyValue.phyMode.has_value() ? phyValue.phyMode.value() : 0);
442+ }
443+ return TaiheAsyncWorkRet(ret);
444+ };
445+ 
446+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(taihe::get_env(), nullptr, func);
447+ TAIHE_BT_ASSERT_RETURN_VOID(asyncWork, BT_ERR_INTERNAL_ERROR);
448+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_CLIENT_SET_PHY, asyncWork);
449+ TAIHE_BT_ASSERT_RETURN_VOID(success, BT_ERR_INTERNAL_ERROR);
450+ 
451+ asyncWork->Run();
452+}
453+ 
454+::ohos::bluetooth::ble::GattRspContext GattClientDeviceImpl::WriteCharacteristicValueWithContextSync(
455+ ::ohos::bluetooth::ble::BLECharacteristic const& characteristic,
456+ ::ohos::bluetooth::ble::GattWriteType writeType) {
457+ HILOGI("enter");
458+ ani_env *env = taihe::get_env();
459+ TAIHE_BT_ASSERT_RETURN(env != nullptr, BT_ERR_INVALID_PARAM, ::ohos::bluetooth::ble::GattRspContext{0});
460+ TAIHE_BT_ASSERT_RETURN(client_ != nullptr, BT_ERR_INTERNAL_ERROR, ::ohos::bluetooth::ble::GattRspContext{0});
461+ TAIHE_BT_ASSERT_RETURN(callback_ != nullptr, BT_ERR_INTERNAL_ERROR, ::ohos::bluetooth::ble::GattRspContext{0});
462+ 
463+ TaiheBleCharacteristic taiheCharacter;
464+ TaiheStatus parseStatus = TaiheParseGattCharacteristic(characteristic, taiheCharacter);
465+ TAIHE_BT_ASSERT_RETURN(parseStatus == TAIHE_OK, parseStatus, ::ohos::bluetooth::ble::GattRspContext{0});
466+ GattCharacteristic *character = GetGattcCharacteristic(client_, taiheCharacter);
467+ TAIHE_BT_ASSERT_RETURN(character != nullptr, BT_ERR_INVALID_PARAM, ::ohos::bluetooth::ble::GattRspContext{0});
468+ 
469+ int writeTypeInt = static_cast<int>(writeType);
470+ character->SetWriteType(writeTypeInt);
471+ 
472+ auto func = [gattClient = client_, character]() {
473+ if (character == nullptr) {
474+ HILOGE("character is nullptr");
475+ return TaiheAsyncWorkRet(BT_ERR_GATT_CHARACTER_ERROR);
476+ }
477+ int ret = BT_ERR_INTERNAL_ERROR;
478+ if (gattClient) {
479+ ret = gattClient->WriteCharacteristic(*character, true);
480+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
481+ }
482+ return TaiheAsyncWorkRet(ret);
483+ };
484+ 
485+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(env, nullptr, func);
486+ TAIHE_BT_ASSERT_RETURN(asyncWork != nullptr, BT_ERR_INTERNAL_ERROR, ::ohos::bluetooth::ble::GattRspContext{0});
487+ bool success = callback_->asyncWorkMap_.TryPush(
488+ TaiheAsyncType::GATT_CLIENT_WRITE_CHARACTER_WITH_CONTEXT, asyncWork);
489+ TAIHE_BT_ASSERT_RETURN(success, BT_ERR_INTERNAL_ERROR, ::ohos::bluetooth::ble::GattRspContext{0});
490+ 
491+ asyncWork->Run();
492+ 
493+ int64_t timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(
494+ std::chrono::steady_clock::now().time_since_epoch()).count();
495+ return {timestamp};
496+}
497+ 
498+void GattClientDeviceImpl::WriteDescriptorValueSync(::ohos::bluetooth::ble::BLEDescriptor const& descriptor) {
499+ HILOGI("enter");
500+ TAIHE_BT_ASSERT_RETURN_VOID(client_ != nullptr, BT_ERR_INTERNAL_ERROR);
501+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
502+ 
503+ TaiheBleDescriptor taiheDescriptor;
504+ TaiheStatus parseStatus = TaiheParseGattDescriptor(descriptor, taiheDescriptor);
505+ TAIHE_BT_ASSERT_RETURN_VOID(parseStatus == TAIHE_OK, parseStatus);
506+ GattDescriptor *desc = GetGattcDescriptor(client_, taiheDescriptor);
507+ TAIHE_BT_ASSERT_RETURN_VOID(desc != nullptr, BT_ERR_INVALID_PARAM);
508+ 
509+ auto func = [gattClient = client_, desc]() {
510+ if (desc == nullptr) {
511+ HILOGE("descriptor is nullptr");
512+ return TaiheAsyncWorkRet(BT_ERR_INTERNAL_ERROR);
513+ }
514+ int ret = BT_ERR_INTERNAL_ERROR;
515+ if (gattClient) {
516+ ret = gattClient->WriteDescriptor(*desc);
517+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
518+ }
519+ return TaiheAsyncWorkRet(ret);
520+ };
521+ 
522+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(taihe::get_env(), nullptr, func);
523+ TAIHE_BT_ASSERT_RETURN_VOID(asyncWork, BT_ERR_INTERNAL_ERROR);
524+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_CLIENT_WRITE_DESCRIPTOR, asyncWork);
525+ TAIHE_BT_ASSERT_RETURN_VOID(success, BT_ERR_INTERNAL_ERROR);
526+ 
527+ asyncWork->Run();
528+}
529+ 
530+static ::ohos::bluetooth::ble::GattService TaiheConvertService(GattService &service)
531+{
532+ std::string serviceUuid = service.GetUuid().ToString();
533+ std::vector<GattCharacteristic> &characteristics = service.GetCharacteristics();
534+ std::vector<::ohos::bluetooth::ble::BLECharacteristic> charVec;
535+ charVec.reserve(characteristics.size());
536+ for (const auto &character : characteristics) {
537+ size_t valueSize = 0;
538+ const auto &valueData = character.GetValue(&valueSize);
539+ ::ohos::bluetooth::ble::BLECharacteristic taiheChar{
540+ taihe::string(serviceUuid),
541+ taihe::string(character.GetUuid().ToString()),
542+ taihe::array<uint8_t>(taihe::copy_data, valueData.get(), valueSize),
543+ taihe::array<::ohos::bluetooth::ble::BLEDescriptor>{}
544+ };
545+ taiheChar.characteristicValueHandle.emplace(static_cast<int32_t>(character.GetHandle()));
546+ charVec.push_back(std::move(taiheChar));
547+ }
548+ return ::ohos::bluetooth::ble::GattService{
549+ taihe::string(serviceUuid),
550+ service.IsPrimary(),
551+ taihe::array<::ohos::bluetooth::ble::BLECharacteristic>(
552+ taihe::move_data, charVec.data(), charVec.size()),
553+ std::nullopt
554+ };
555+}
556+ 
557+::taihe::array<::ohos::bluetooth::ble::GattService> GattClientDeviceImpl::GetServicesSync() {
558+ HILOGI("enter");
559+ TAIHE_BT_ASSERT_RETURN(client_ != nullptr, BT_ERR_INTERNAL_ERROR,
560+ ::taihe::array<::ohos::bluetooth::ble::GattService>{});
561+ 
562+ int ret = client_->DiscoverServices();
563+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret,
564+ ::taihe::array<::ohos::bluetooth::ble::GattService>{});
565+ 
566+ std::vector<GattService> services = client_->GetService();
567+ std::vector<::ohos::bluetooth::ble::GattService> serviceVec;
568+ serviceVec.reserve(services.size());
569+ for (auto &svc : services) {
570+ serviceVec.push_back(TaiheConvertService(svc));
571+ }
572+ return ::taihe::array<::ohos::bluetooth::ble::GattService>(
573+ taihe::move_data, serviceVec.data(), serviceVec.size());
574+}
575+ 
576+void GattClientDeviceImpl::OnBlePhyUpdate(
577+ ::taihe::callback_view<void(::ohos::bluetooth::ble::PhyValue const& data)> callback) {
578+ HILOGI("enter");
579+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
580+ callback_->blePhyUpdateEvent_.RegisterEvent(callback);
581+}
582+ 
583+void GattClientDeviceImpl::OffBlePhyUpdate(
584+ ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::PhyValue const& data)>> callback) {
585+ HILOGI("enter");
586+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
587+ callback_->blePhyUpdateEvent_.DeregisterEvent(callback);
588+}
589+ 
590+void GattClientDeviceImpl::SetCharacteristicChangeNotificationSync(
591+ ::ohos::bluetooth::ble::BLECharacteristic const& characteristic, bool enable) {
592+ HILOGI("enter");
593+ TAIHE_BT_ASSERT_RETURN_VOID(client_ != nullptr, BT_ERR_INTERNAL_ERROR);
594+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
595+ 
596+ TaiheBleCharacteristic taiheCharacter;
597+ TaiheStatus parseStatus = TaiheParseGattCharacteristic(characteristic, taiheCharacter);
598+ TAIHE_BT_ASSERT_RETURN_VOID(parseStatus == TAIHE_OK, parseStatus);
599+ GattCharacteristic *character = GetGattcCharacteristic(client_, taiheCharacter);
600+ TAIHE_BT_ASSERT_RETURN_VOID(character != nullptr, BT_ERR_INVALID_PARAM);
601+ 
602+ auto func = [gattClient = client_, character, enable]() {
603+ if (character == nullptr) {
604+ HILOGE("character is nullptr");
605+ return TaiheAsyncWorkRet(BT_ERR_INTERNAL_ERROR);
606+ }
607+ int ret = BT_ERR_INTERNAL_ERROR;
608+ if (gattClient) {
609+ ret = gattClient->SetNotifyCharacteristic(*character, enable);
610+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
611+ }
612+ return TaiheAsyncWorkRet(ret);
613+ };
614+ 
615+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(taihe::get_env(), nullptr, func);
616+ TAIHE_BT_ASSERT_RETURN_VOID(asyncWork, BT_ERR_INTERNAL_ERROR);
617+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_CLIENT_ENABLE_CHARACTER_CHANGED, asyncWork);
618+ TAIHE_BT_ASSERT_RETURN_VOID(success, BT_ERR_INTERNAL_ERROR);
619+ 
620+ asyncWork->Run();
621+}
622+ 
623+int32_t GattClientDeviceImpl::GetRssiValueSync() {
624+ HILOGI("enter");
625+ TAIHE_BT_ASSERT_RETURN(client_ != nullptr, BT_ERR_INTERNAL_ERROR, 0);
626+ TAIHE_BT_ASSERT_RETURN(callback_ != nullptr, BT_ERR_INTERNAL_ERROR, 0);
627+ 
628+ // Set up promise for async result - OnReadRemoteRssiValueResult will resolve it
629+ auto promise = std::make_shared<std::promise<int32_t>>();
630+ auto future = promise->get_future();
631+ {
632+ std::lock_guard<std::mutex> guard(callback_->rssiValuePromiseLock_);
633+ callback_->rssiValuePromise_ = promise;
634+ }
635+ 
636+ int ret = client_->ReadRemoteRssiValue();
637+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
638+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret, 0);
639+ 
640+ // Wait for OnReadRemoteRssiValueResult callback to resolve the promise
641+ auto status = future.wait_for(std::chrono::seconds(BLE_SYNC_TIMEOUT_SECONDS));
642+ if (status == std::future_status::timeout) {
643+ HILOGE("GetRssiValueSync timeout");
644+ std::lock_guard<std::mutex> guard(callback_->rssiValuePromiseLock_);
645+ callback_->rssiValuePromise_ = nullptr;
646+ return 0;
647+ }
648+ return future.get();
649+}
650+ 
651+int32_t GattClientDeviceImpl::SetBLEMtuSync(int32_t mtu) {
652+ HILOGI("enter");
653+ TAIHE_BT_ASSERT_RETURN(client_ != nullptr, BT_ERR_INTERNAL_ERROR, 0);
654+ TAIHE_BT_ASSERT_RETURN(callback_ != nullptr, BT_ERR_INTERNAL_ERROR, 0);
655+ 
656+ // Set up promise for async result - OnMtuUpdate will resolve it
657+ auto promise = std::make_shared<std::promise<int32_t>>();
658+ auto future = promise->get_future();
659+ {
660+ std::lock_guard<std::mutex> guard(callback_->mtuValuePromiseLock_);
661+ callback_->mtuValuePromise_ = promise;
662+ }
663+ 
664+ int ret = client_->RequestBleMtuSize(mtu);
665+ HILOGI("ret: %{public}d", ret);
666+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
667+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret, 0);
668+ 
669+ // Wait for OnMtuUpdate callback to resolve the promise
670+ auto status = future.wait_for(std::chrono::seconds(BLE_SYNC_TIMEOUT_SECONDS));
671+ if (status == std::future_status::timeout) {
672+ HILOGE("SetBLEMtuSync timeout");
673+ std::lock_guard<std::mutex> guard(callback_->mtuValuePromiseLock_);
674+ callback_->mtuValuePromise_ = nullptr;
675+ return 0;
676+ }
677+ return future.get();
678+}
679+ 
680+void GattClientDeviceImpl::WriteCharacteristicValueSync(
681+ ::ohos::bluetooth::ble::BLECharacteristic const& characteristic,
682+ ::ohos::bluetooth::ble::GattWriteType writeType) {
683+ HILOGI("enter");
684+ TAIHE_BT_ASSERT_RETURN_VOID(client_ != nullptr, BT_ERR_INTERNAL_ERROR);
685+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
686+ 
687+ TaiheBleCharacteristic taiheCharacter;
688+ TaiheStatus parseStatus = TaiheParseGattCharacteristic(characteristic, taiheCharacter);
689+ TAIHE_BT_ASSERT_RETURN_VOID(parseStatus == TAIHE_OK, parseStatus);
690+ GattCharacteristic *character = GetGattcCharacteristic(client_, taiheCharacter);
691+ TAIHE_BT_ASSERT_RETURN_VOID(character != nullptr, BT_ERR_INVALID_PARAM);
692+ 
693+ int writeTypeInt = static_cast<int>(writeType);
694+ character->SetWriteType(writeTypeInt);
695+ 
696+ auto func = [gattClient = client_, character]() {
697+ if (character == nullptr) {
698+ HILOGE("character is nullptr");
699+ return TaiheAsyncWorkRet(BT_ERR_GATT_CHARACTER_ERROR);
700+ }
701+ int ret = BT_ERR_INTERNAL_ERROR;
702+ if (gattClient) {
703+ ret = gattClient->WriteCharacteristic(*character, false);
704+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
705+ }
706+ return TaiheAsyncWorkRet(ret);
707+ };
708+ 
709+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(taihe::get_env(), nullptr, func);
710+ TAIHE_BT_ASSERT_RETURN_VOID(asyncWork, BT_ERR_INTERNAL_ERROR);
711+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_CLIENT_WRITE_CHARACTER, asyncWork);
712+ TAIHE_BT_ASSERT_RETURN_VOID(success, BT_ERR_INTERNAL_ERROR);
713+ 
714+ asyncWork->Run();
715+}
716+ 
717+void GattClientDeviceImpl::OnBLEMtuChange(::taihe::callback_view<void(int32_t data)> callback) {
718+ HILOGI("enter");
719+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
720+ callback_->bleMtuChangeEvent_.RegisterEvent(callback);
721+}
722+ 
723+void GattClientDeviceImpl::OffBLEMtuChange(
724+ ::taihe::optional_view<::taihe::callback<void(int32_t data)>> callback) {
725+ HILOGI("enter");
726+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
727+ callback_->bleMtuChangeEvent_.DeregisterEvent(callback);
728+}
729+ 
730+void GattClientDeviceImpl::OnServiceChange(::taihe::callback_view<void()> callback) {
731+ HILOGI("enter");
732+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
733+ callback_->serviceChangeEvent_.RegisterEvent(callback);
734+}
735+ 
736+void GattClientDeviceImpl::OffServiceChange(
737+ ::taihe::optional_view<::taihe::callback<void()>> callback) {
738+ HILOGI("enter");
739+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
740+ callback_->serviceChangeEvent_.DeregisterEvent(callback);
741+}
742+ 
743+void GattClientDeviceImpl::OnBLECharacteristicChange(
744+ ::taihe::callback_view<void(::ohos::bluetooth::ble::BLECharacteristic const& data)> callback) {
745+ HILOGI("enter");
746+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
747+ callback_->bleCharacteristicChangeEvent_.RegisterEvent(callback);
748+}
749+ 
750+void GattClientDeviceImpl::OffBLECharacteristicChange(
751+ ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLECharacteristic const& data)>> callback) {
752+ HILOGI("enter");
753+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
754+ callback_->bleCharacteristicChangeEvent_.DeregisterEvent(callback);
755+}
756+ 
757+void GattClientDeviceImpl::UpdateConnectionParamSync(::ohos::bluetooth::ble::ConnectionParam param) {
758+ HILOGI("enter");
759+ TAIHE_BT_ASSERT_RETURN_VOID(client_ != nullptr, BT_ERR_INTERNAL_ERROR);
760+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
761+ 
762+ int connectionPriority = static_cast<int>(param);
763+ 
764+ auto func = [gattClient = client_, connectionPriority]() {
765+ int ret = gattClient->RequestConnectionPriority(connectionPriority);
766+ return TaiheAsyncWorkRet(ret);
767+ };
768+ 
769+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(taihe::get_env(), nullptr, func);
770+ TAIHE_BT_ASSERT_RETURN_VOID(asyncWork, BT_ERR_INTERNAL_ERROR);
771+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_CLIENT_UPDATE_CONNECTION_PRIORITY, asyncWork);
772+ TAIHE_BT_ASSERT_RETURN_VOID(success, BT_ERR_INTERNAL_ERROR);
773+ 
774+ asyncWork->Run();
775+}
776+ 
777+void GattClientDeviceImpl::OnBLEConnectionStateChange(
778+ ::taihe::callback_view<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)> callback) {
779+ HILOGI("enter");
780+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
781+ callback_->bleConnectionStateChangeEvent_.RegisterEvent(callback);
782+}
783+ 
784+void GattClientDeviceImpl::OffBLEConnectionStateChange(
785+ ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)>> callback) {
786+ HILOGI("enter");
787+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
788+ callback_->bleConnectionStateChangeEvent_.DeregisterEvent(callback);
789+}
790+ 
791+::ohos::bluetooth::constant::ProfileConnectionState GattClientDeviceImpl::GetConnectedState() {
792+ HILOGI("enter");
793+ TAIHE_BT_ASSERT_RETURN(client_ != nullptr, BT_ERR_INTERNAL_ERROR,
794+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
795+ 
796+ int state = 0;
797+ int ret = client_->GetConnectedState(state);
798+ HILOGI("ret: %{public}d, state: %{public}d", ret, state);
799+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret,
800+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
801+ 
802+ int profileState = TaiheUtils::GetProfileConnectionState(state);
803+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
804+}
805+ 
393} // namespace Bluetooth806} // namespace Bluetooth
394} // namespace OHOS807} // namespace OHOS
@@ -28,6 +28,20 @@ TaiheGattClientCallback::TaiheGattClientCallback()
28void TaiheGattClientCallback::OnCharacteristicChanged(const GattCharacteristic &characteristic)28void TaiheGattClientCallback::OnCharacteristicChanged(const GattCharacteristic &characteristic)
29{29{
30 HILOGI("UUID: %{public}s", characteristic.GetUuid().ToString().c_str());30 HILOGI("UUID: %{public}s", characteristic.GetUuid().ToString().c_str());
31+ std::string serviceUuid;
32+ if (characteristic.GetService() != nullptr) {
33+ serviceUuid = characteristic.GetService()->GetUuid().ToString();
34+ }
35+ size_t valueSize = 0;
36+ const auto &valueData = characteristic.GetValue(&valueSize);
37+ ::ohos::bluetooth::ble::BLECharacteristic taiheCharacter{
38+ taihe::string(serviceUuid),
39+ taihe::string(characteristic.GetUuid().ToString()),
40+ taihe::array<uint8_t>(taihe::copy_data, valueData.get(), valueSize),
41+ taihe::array<::ohos::bluetooth::ble::BLEDescriptor>{}
42+ };
43+ taiheCharacter.characteristicValueHandle.emplace(static_cast<int32_t>(characteristic.GetHandle()));
44+ bleCharacteristicChangeEvent_.PublishEvent(taiheCharacter);
31}45}
32 46 
33void TaiheGattClientCallback::OnCharacteristicReadResult(const GattCharacteristic &characteristic, int ret)47void TaiheGattClientCallback::OnCharacteristicReadResult(const GattCharacteristic &characteristic, int ret)
@@ -49,6 +63,12 @@ void TaiheGattClientCallback::OnDescriptorReadResult(const GattDescriptor &descr
49void TaiheGattClientCallback::OnConnectionStateChanged(int connectionState, int ret)63void TaiheGattClientCallback::OnConnectionStateChanged(int connectionState, int ret)
50{64{
51 HILOGI("connectionState:%{public}d, ret:%{public}d", connectionState, ret);65 HILOGI("connectionState:%{public}d, ret:%{public}d", connectionState, ret);
66+ ::ohos::bluetooth::ble::BLEConnectionChangeState state{
67+ taihe::string(deviceAddr_),
68+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(
69+ TaiheUtils::GetProfileConnectionState(connectionState))
70+ };
71+ bleConnectionStateChangeEvent_.PublishEvent(state);
52}72}
53 73 
54void TaiheGattClientCallback::OnServicesDiscovered(int status)74void TaiheGattClientCallback::OnServicesDiscovered(int status)
@@ -59,6 +79,17 @@ void TaiheGattClientCallback::OnServicesDiscovered(int status)
59void TaiheGattClientCallback::OnReadRemoteRssiValueResult(int rssi, int ret)79void TaiheGattClientCallback::OnReadRemoteRssiValueResult(int rssi, int ret)
60{80{
61 HILOGI("rssi: %{public}d, ret: %{public}d", rssi, ret);81 HILOGI("rssi: %{public}d, ret: %{public}d", rssi, ret);
82+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
83+ // Resolve the promise for GetRssiValueSync (synchronous wait pattern)
84+ {
85+ std::lock_guard<std::mutex> guard(rssiValuePromiseLock_);
86+ if (rssiValuePromise_) {
87+ rssiValuePromise_->set_value(rssi);
88+ rssiValuePromise_ = nullptr;
89+ }
90+ }
91+ auto taiheRssi = std::make_shared<TaiheNativeInt>(rssi);
92+ AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_CLIENT_READ_REMOTE_RSSI_VALUE, taiheRssi, ret);
62}93}
63 94 
64void TaiheGattClientCallback::OnCharacteristicWriteResult(const GattCharacteristic &characteristic, int ret)95void TaiheGattClientCallback::OnCharacteristicWriteResult(const GattCharacteristic &characteristic, int ret)
@@ -72,6 +103,9 @@ void TaiheGattClientCallback::OnCharacteristicWriteResult(const GattCharacterist
72void TaiheGattClientCallback::OnDescriptorWriteResult(const GattDescriptor &descriptor, int ret)103void TaiheGattClientCallback::OnDescriptorWriteResult(const GattDescriptor &descriptor, int ret)
73{104{
74 HILOGI("UUID: %{public}s, ret: %{public}d", descriptor.GetUuid().ToString().c_str(), ret);105 HILOGI("UUID: %{public}s, ret: %{public}d", descriptor.GetUuid().ToString().c_str(), ret);
106+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
107+ auto taiheDescriptor = std::make_shared<TaiheNativeBleDescriptor>(descriptor);
108+ AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_CLIENT_WRITE_DESCRIPTOR, taiheDescriptor, ret);
75}109}
76 110 
77void TaiheGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status)111void TaiheGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status)
@@ -84,6 +118,45 @@ void TaiheGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic
84void TaiheGattClientCallback::OnMtuUpdate(int mtu, int ret)118void TaiheGattClientCallback::OnMtuUpdate(int mtu, int ret)
85{119{
86 HILOGI("ret: %{public}d, mtu: %{public}d", ret, mtu);120 HILOGI("ret: %{public}d, mtu: %{public}d", ret, mtu);
121+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
122+ // Resolve the promise for SetBLEMtuSync (synchronous wait pattern)
123+ {
124+ std::lock_guard<std::mutex> guard(mtuValuePromiseLock_);
125+ if (mtuValuePromise_) {
126+ mtuValuePromise_->set_value(mtu);
127+ mtuValuePromise_ = nullptr;
128+ }
129+ }
130+ auto taiheMtu = std::make_shared<TaiheNativeInt>(mtu);
131+ AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_CLIENT_MTU_CHANGED, taiheMtu, ret);
132+ bleMtuChangeEvent_.PublishEvent(mtu);
133+}
134+ 
135+void TaiheGattClientCallback::OnBlePhyUpdate(int32_t txPhy, int32_t rxPhy, int32_t status)
136+{
137+ HILOGI("txPhy: %{public}d, rxPhy: %{public}d, status: %{public}d", txPhy, rxPhy, status);
138+ status = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(status));
139+ auto taihePhyValue = std::make_shared<TaiheNativePhyValue>(txPhy, rxPhy);
140+ AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_CLIENT_SET_PHY, taihePhyValue, status);
141+ ::ohos::bluetooth::ble::PhyValue phyValue{
142+ ::ohos::bluetooth::ble::BlePhy::from_value(txPhy),
143+ ::ohos::bluetooth::ble::BlePhy::from_value(rxPhy)
144+ };
145+ blePhyUpdateEvent_.PublishEvent(phyValue);
146+}
147+ 
148+void TaiheGattClientCallback::OnBlePhyRead(int32_t txPhy, int32_t rxPhy, int32_t status)
149+{
150+ HILOGI("txPhy: %{public}d, rxPhy: %{public}d, status: %{public}d", txPhy, rxPhy, status);
151+ status = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(status));
152+ auto taihePhyValue = std::make_shared<TaiheNativePhyValue>(txPhy, rxPhy);
153+ AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_CLIENT_READ_PHY, taihePhyValue, status);
154+}
155+ 
156+void TaiheGattClientCallback::OnServicesChanged()
157+{
158+ HILOGI("enter");
159+ serviceChangeEvent_.PublishEvent();
87}160}
88 161 
89} // namespace Bluetooth162} // namespace Bluetooth
@@ -20,8 +20,10 @@
20#include "taihe_bluetooth_gatt_server.h"20#include "taihe_bluetooth_gatt_server.h"
21 21 
22#include "bluetooth_utils.h"22#include "bluetooth_utils.h"
23+#include "bluetooth_remote_device.h"
23#include "taihe_bluetooth_error.h"24#include "taihe_bluetooth_error.h"
24#include "taihe_bluetooth_utils.h"25#include "taihe_bluetooth_utils.h"
26+#include "taihe_event_module.h"
25#include "taihe_parser_utils.h"27#include "taihe_parser_utils.h"
26 28 
27namespace OHOS {29namespace OHOS {
@@ -188,5 +190,272 @@ void GattServerImpl::NotifyCharacteristicChangedAsync(taihe::string_view deviceI
188 TAIHE_BT_ASSERT_RETURN_VOID(false, result.errorCode);190 TAIHE_BT_ASSERT_RETURN_VOID(false, result.errorCode);
189 }191 }
190}192}
193+ 
194+void GattServerImpl::OnBlePhyUpdate(::taihe::callback_view<void(::ohos::bluetooth::ble::PhyValue const& data)> callback) {
195+ HILOGI("enter");
196+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
197+ callback_->blePhyUpdateEvent_.RegisterEvent(callback);
198+}
199+ 
200+void GattServerImpl::OffBlePhyUpdate(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::PhyValue const& data)>> callback) {
201+ HILOGI("enter");
202+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
203+ callback_->blePhyUpdateEvent_.DeregisterEvent(callback);
204+}
205+ 
206+void GattServerImpl::SetPhySync(::taihe::string_view deviceId, ::ohos::bluetooth::ble::PhyValue const& phyValue) {
207+ HILOGI("enter");
208+ ani_env *env = taihe::get_env();
209+ TAIHE_BT_ASSERT_RETURN_VOID(env != nullptr, BT_ERR_INVALID_PARAM);
210+ TAIHE_BT_ASSERT_RETURN_VOID(server_ != nullptr, BT_ERR_INTERNAL_ERROR);
211+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
212+ 
213+ std::string devId = static_cast<std::string>(deviceId);
214+ int32_t txPhy = static_cast<int32_t>(phyValue.txPhy);
215+ int32_t rxPhy = static_cast<int32_t>(phyValue.rxPhy);
216+ int32_t phyOptions = phyValue.phyMode.has_value() ? phyValue.phyMode.value() : 0;
217+ 
218+ auto func = [gattServer = server_, devId, txPhy, rxPhy, phyOptions]() {
219+ int ret = BT_ERR_INTERNAL_ERROR;
220+ if (gattServer) {
221+ ret = gattServer->SetPhy(devId, txPhy, rxPhy, phyOptions);
222+ }
223+ return TaiheAsyncWorkRet(ret);
224+ };
225+ 
226+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(env, nullptr, func);
227+ TAIHE_BT_ASSERT_RETURN_VOID(asyncWork != nullptr, BT_ERR_INTERNAL_ERROR);
228+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_SERVER_SET_PHY, asyncWork);
229+ TAIHE_BT_ASSERT_RETURN_VOID(success, BT_ERR_INTERNAL_ERROR);
230+ 
231+ asyncWork->Run();
232+}
233+ 
234+::ohos::bluetooth::ble::PhyValue GattServerImpl::ReadPhySync(::taihe::string_view deviceId) {
235+ HILOGI("enter");
236+ ani_env *env = taihe::get_env();
237+ TAIHE_BT_ASSERT_RETURN(env != nullptr, BT_ERR_INVALID_PARAM,
238+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
239+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
240+ TAIHE_BT_ASSERT_RETURN(server_ != nullptr, BT_ERR_INTERNAL_ERROR,
241+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
242+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
243+ TAIHE_BT_ASSERT_RETURN(callback_ != nullptr, BT_ERR_INTERNAL_ERROR,
244+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
245+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
246+ 
247+ std::string devId = static_cast<std::string>(deviceId);
248+ 
249+ auto func = [gattServer = server_, devId]() {
250+ int ret = BT_ERR_INTERNAL_ERROR;
251+ if (gattServer) {
252+ ret = gattServer->ReadPhy(devId);
253+ }
254+ return TaiheAsyncWorkRet(ret);
255+ };
256+ 
257+ auto asyncWork = TaiheAsyncWorkFactory::CreateAsyncWork(env, nullptr, func);
258+ TAIHE_BT_ASSERT_RETURN(asyncWork != nullptr, BT_ERR_INTERNAL_ERROR,
259+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
260+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
261+ bool success = callback_->asyncWorkMap_.TryPush(TaiheAsyncType::GATT_SERVER_READ_PHY, asyncWork);
262+ TAIHE_BT_ASSERT_RETURN(success, BT_ERR_INTERNAL_ERROR,
263+ (::ohos::bluetooth::ble::PhyValue{::ohos::bluetooth::ble::BlePhy::from_value(0),
264+ ::ohos::bluetooth::ble::BlePhy::from_value(0)}));
265+ 
266+ asyncWork->Run();
267+ 
268+ return ::ohos::bluetooth::ble::PhyValue{
269+ ::ohos::bluetooth::ble::BlePhy::from_value(0),
270+ ::ohos::bluetooth::ble::BlePhy::from_value(0)
271+ };
272+}
273+ 
274+void GattServerImpl::OnBLEMtuChange(::taihe::callback_view<void(int32_t data)> callback) {
275+ HILOGI("enter");
276+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
277+ callback_->bleMtuChangeEvent_.RegisterEvent(callback);
278+}
279+ 
280+void GattServerImpl::OffBLEMtuChange(::taihe::optional_view<::taihe::callback<void(int32_t data)>> callback) {
281+ HILOGI("enter");
282+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
283+ callback_->bleMtuChangeEvent_.DeregisterEvent(callback);
284+}
285+ 
286+void GattServerImpl::Disconnect(::taihe::string_view deviceId) {
287+ HILOGI("enter");
288+ TAIHE_BT_ASSERT_RETURN_VOID(server_ != nullptr, BT_ERR_INTERNAL_ERROR);
289+ std::string devId = static_cast<std::string>(deviceId);
290+ BluetoothRemoteDevice remoteDevice(devId, BTTransport::ADAPTER_BLE);
291+ int ret = server_->CancelConnection(remoteDevice);
292+ TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
293+}
294+ 
295+void GattServerImpl::Connect(::taihe::string_view deviceId, ::taihe::optional_view<bool> autoConnect) {
296+ HILOGI("enter");
297+ TAIHE_BT_ASSERT_RETURN_VOID(server_ != nullptr, BT_ERR_INTERNAL_ERROR);
298+ std::string devId = static_cast<std::string>(deviceId);
299+ bool isAutoConnect = false;
300+ if (autoConnect.has_value()) {
301+ isAutoConnect = autoConnect.value();
302+ }
303+ BluetoothRemoteDevice remoteDevice(devId, BTTransport::ADAPTER_BLE);
304+ int ret = server_->Connect(remoteDevice, !isAutoConnect);
305+ TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
306+}
307+ 
308+void GattServerImpl::OnCharacteristicRead(::taihe::callback_view<void(::ohos::bluetooth::ble::CharacteristicReadRequest const& data)> callback) {
309+ HILOGI("enter");
310+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
311+ callback_->characteristicReadEvent_.RegisterEvent(callback);
312+}
313+ 
314+void GattServerImpl::OffCharacteristicRead(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::CharacteristicReadRequest const& data)>> callback) {
315+ HILOGI("enter");
316+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
317+ callback_->characteristicReadEvent_.DeregisterEvent(callback);
318+}
319+ 
320+void GattServerImpl::OnCharacteristicWrite(::taihe::callback_view<void(::ohos::bluetooth::ble::CharacteristicWriteRequest const& data)> callback) {
321+ HILOGI("enter");
322+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
323+ callback_->characteristicWriteEvent_.RegisterEvent(callback);
324+}
325+ 
326+void GattServerImpl::OffCharacteristicWrite(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::CharacteristicWriteRequest const& data)>> callback) {
327+ HILOGI("enter");
328+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
329+ callback_->characteristicWriteEvent_.DeregisterEvent(callback);
330+}
331+ 
332+::ohos::bluetooth::constant::ProfileConnectionState GattServerImpl::GetConnectedState(::taihe::string_view deviceId) {
333+ HILOGI("enter");
334+ TAIHE_BT_ASSERT_RETURN(server_ != nullptr, BT_ERR_INTERNAL_ERROR,
335+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
336+ 
337+ std::string devId = static_cast<std::string>(deviceId);
338+ int state = -1;
339+ int ret = server_->GetConnectedState(devId, state);
340+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret,
341+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
342+ 
343+ int profileState = TaiheUtils::GetProfileConnectionState(state);
344+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
345+}
346+ 
347+static ::ohos::bluetooth::ble::GattService TaiheConvertService(GattService &service)
348+{
349+ std::string serviceUuid = service.GetUuid().ToString();
350+ std::vector<GattCharacteristic> &characteristics = service.GetCharacteristics();
351+ std::vector<::ohos::bluetooth::ble::BLECharacteristic> charVec;
352+ charVec.reserve(characteristics.size());
353+ for (const auto &character : characteristics) {
354+ size_t valueSize = 0;
355+ const auto &valueData = character.GetValue(&valueSize);
356+ ::ohos::bluetooth::ble::BLECharacteristic taiheChar{
357+ taihe::string(serviceUuid),
358+ taihe::string(character.GetUuid().ToString()),
359+ taihe::array<uint8_t>(taihe::copy_data, valueData.get(), valueSize),
360+ taihe::array<::ohos::bluetooth::ble::BLEDescriptor>{}
361+ };
362+ taiheChar.characteristicValueHandle.emplace(static_cast<int32_t>(character.GetHandle()));
363+ charVec.push_back(std::move(taiheChar));
364+ }
365+ return ::ohos::bluetooth::ble::GattService{
366+ taihe::string(serviceUuid),
367+ service.IsPrimary(),
368+ taihe::array<::ohos::bluetooth::ble::BLECharacteristic>(
369+ taihe::move_data, charVec.data(), charVec.size()),
370+ std::nullopt
371+ };
372+}
373+ 
374+::ohos::bluetooth::ble::GattService GattServerImpl::GetService(::taihe::string_view serviceUuid) {
375+ HILOGI("enter");
376+ TAIHE_BT_ASSERT_RETURN(server_ != nullptr, BT_ERR_INTERNAL_ERROR,
377+ (::ohos::bluetooth::ble::GattService{taihe::string(""), false,
378+ taihe::array<::ohos::bluetooth::ble::BLECharacteristic>{}, std::nullopt}));
379+ 
380+ UUID uuid;
381+ auto status = ParseUuidParams(std::string(serviceUuid), uuid);
382+ TAIHE_BT_ASSERT_RETURN(status == TAIHE_OK, BT_ERR_INVALID_PARAM,
383+ (::ohos::bluetooth::ble::GattService{taihe::string(""), false,
384+ taihe::array<::ohos::bluetooth::ble::BLECharacteristic>{}, std::nullopt}));
385+ 
386+ GattService outService(UUID::FromString("00000000-0000-0000-0000-000000000000"), GattServiceType::PRIMARY);
387+ int ret = server_->GetService(uuid, true, outService);
388+ if (ret != BT_NO_ERROR) {
389+ ret = server_->GetService(uuid, false, outService);
390+ }
391+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret,
392+ (::ohos::bluetooth::ble::GattService{taihe::string(""), false,
393+ taihe::array<::ohos::bluetooth::ble::BLECharacteristic>{}, std::nullopt}));
394+ 
395+ return TaiheConvertService(outService);
396+}
397+ 
398+void GattServerImpl::OnConnectionStateChange(::taihe::callback_view<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)> callback) {
399+ HILOGI("enter");
400+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
401+ callback_->connectionStateChangeEvent_.RegisterEvent(callback);
402+}
403+ 
404+void GattServerImpl::OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)>> callback) {
405+ HILOGI("enter");
406+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
407+ callback_->connectionStateChangeEvent_.DeregisterEvent(callback);
408+}
409+ 
410+void GattServerImpl::OnDescriptorWrite(::taihe::callback_view<void(::ohos::bluetooth::ble::DescriptorWriteRequest const& data)> callback) {
411+ HILOGI("enter");
412+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
413+ callback_->descriptorWriteEvent_.RegisterEvent(callback);
414+}
415+ 
416+void GattServerImpl::OffDescriptorWrite(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::DescriptorWriteRequest const& data)>> callback) {
417+ HILOGI("enter");
418+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
419+ callback_->descriptorWriteEvent_.DeregisterEvent(callback);
420+}
421+ 
422+void GattServerImpl::OnDescriptorRead(::taihe::callback_view<void(::ohos::bluetooth::ble::DescriptorReadRequest const& data)> callback) {
423+ HILOGI("enter");
424+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
425+ callback_->descriptorReadEvent_.RegisterEvent(callback);
426+}
427+ 
428+void GattServerImpl::OffDescriptorRead(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::DescriptorReadRequest const& data)>> callback) {
429+ HILOGI("enter");
430+ TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR);
431+ callback_->descriptorReadEvent_.DeregisterEvent(callback);
432+}
433+ 
434+void GattServerImpl::RemoveAllServices() {
435+ HILOGI("enter");
436+ TAIHE_BT_ASSERT_RETURN_VOID(server_ != nullptr, BT_ERR_INTERNAL_ERROR);
437+ int ret = server_->ClearServices();
438+ TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
439+}
440+ 
441+::taihe::array<::ohos::bluetooth::ble::GattService> GattServerImpl::GetServices() {
442+ HILOGI("enter");
443+ TAIHE_BT_ASSERT_RETURN(server_ != nullptr, BT_ERR_INTERNAL_ERROR,
444+ ::taihe::array<::ohos::bluetooth::ble::GattService>{});
445+ 
446+ std::list<GattService> serviceList;
447+ int ret = server_->GetServices(serviceList);
448+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret,
449+ ::taihe::array<::ohos::bluetooth::ble::GattService>{});
450+ 
451+ std::vector<::ohos::bluetooth::ble::GattService> serviceVec;
452+ serviceVec.reserve(serviceList.size());
453+ for (auto &svc : serviceList) {
454+ serviceVec.push_back(TaiheConvertService(svc));
455+ }
456+ return ::taihe::array<::ohos::bluetooth::ble::GattService>(
457+ taihe::move_data, serviceVec.data(), serviceVec.size());
458+}
459+ 
191} // namespace Bluetooth460} // namespace Bluetooth
192} // namespace OHOS461} // namespace OHOS
@@ -34,6 +34,18 @@ void TaiheGattServerCallback::OnCharacteristicReadRequest(
34{34{
35 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",35 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",
36 GET_ENCRYPT_ADDR(device), requestId);36 GET_ENCRYPT_ADDR(device), requestId);
37+ std::string serviceUuid;
38+ if (characteristic.GetService() != nullptr) {
39+ serviceUuid = characteristic.GetService()->GetUuid().ToString();
40+ }
41+ ::ohos::bluetooth::ble::CharacteristicReadRequest request{
42+ taihe::string(device.GetDeviceAddr()),
43+ requestId,
44+ 0,
45+ taihe::string(characteristic.GetUuid().ToString()),
46+ taihe::string(serviceUuid)
47+ };
48+ characteristicReadEvent_.PublishEvent(request);
37}49}
38 50 
39void TaiheGattServerCallback::OnCharacteristicWriteRequest(const BluetoothRemoteDevice &device,51void TaiheGattServerCallback::OnCharacteristicWriteRequest(const BluetoothRemoteDevice &device,
@@ -41,6 +53,23 @@ void TaiheGattServerCallback::OnCharacteristicWriteRequest(const BluetoothRemote
41{53{
42 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",54 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",
43 GET_ENCRYPT_ADDR(device), requestId);55 GET_ENCRYPT_ADDR(device), requestId);
56+ std::string serviceUuid;
57+ if (characteristic.GetService() != nullptr) {
58+ serviceUuid = characteristic.GetService()->GetUuid().ToString();
59+ }
60+ size_t valueSize = 0;
61+ const auto &valueData = characteristic.GetValue(&valueSize);
62+ ::ohos::bluetooth::ble::CharacteristicWriteRequest request{
63+ taihe::string(device.GetDeviceAddr()),
64+ requestId,
65+ 0,
66+ false,
67+ false,
68+ taihe::array<uint8_t>(taihe::copy_data, valueData.get(), valueSize),
69+ taihe::string(characteristic.GetUuid().ToString()),
70+ taihe::string(serviceUuid)
71+ };
72+ characteristicWriteEvent_.PublishEvent(request);
44}73}
45 74 
46void TaiheGattServerCallback::OnConnectionStateUpdate(const BluetoothRemoteDevice &device, int state)75void TaiheGattServerCallback::OnConnectionStateUpdate(const BluetoothRemoteDevice &device, int state)
@@ -74,11 +103,46 @@ void TaiheGattServerCallback::OnConnectionStateUpdate(const BluetoothRemoteDevic
74 }103 }
75}104}
76 105 
106+void TaiheGattServerCallback::OnConnectionStateUpdateWithMessage(const BluetoothRemoteDevice &device,
107+ int state, GattDisconnectParam disconnectParam)
108+{
109+ HILOGI("enter, state: %{public}d, remote device address: %{public}s", state, GET_ENCRYPT_ADDR(device));
110+ OnConnectionStateUpdate(device, state);
111+ ::ohos::bluetooth::ble::BLEConnectionChangeState changeState{
112+ taihe::string(device.GetDeviceAddr()),
113+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(
114+ TaiheUtils::GetProfileConnectionState(state))
115+ };
116+ connectionStateChangeEvent_.PublishEvent(changeState);
117+}
118+ 
77void TaiheGattServerCallback::OnDescriptorWriteRequest(const BluetoothRemoteDevice &device,119void TaiheGattServerCallback::OnDescriptorWriteRequest(const BluetoothRemoteDevice &device,
78 GattDescriptor &descriptor, int requestId)120 GattDescriptor &descriptor, int requestId)
79{121{
80 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",122 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",
81 GET_ENCRYPT_ADDR(device), requestId);123 GET_ENCRYPT_ADDR(device), requestId);
124+ std::string characteristicUuid;
125+ std::string serviceUuid;
126+ if (descriptor.GetCharacteristic() != nullptr) {
127+ characteristicUuid = descriptor.GetCharacteristic()->GetUuid().ToString();
128+ if (descriptor.GetCharacteristic()->GetService() != nullptr) {
129+ serviceUuid = descriptor.GetCharacteristic()->GetService()->GetUuid().ToString();
130+ }
131+ }
132+ size_t valueSize = 0;
133+ const auto &valueData = descriptor.GetValue(&valueSize);
134+ ::ohos::bluetooth::ble::DescriptorWriteRequest request{
135+ taihe::string(device.GetDeviceAddr()),
136+ requestId,
137+ 0,
138+ false,
139+ false,
140+ taihe::array<uint8_t>(taihe::copy_data, valueData.get(), valueSize),
141+ taihe::string(descriptor.GetUuid().ToString()),
142+ taihe::string(characteristicUuid),
143+ taihe::string(serviceUuid)
144+ };
145+ descriptorWriteEvent_.PublishEvent(request);
82}146}
83 147 
84void TaiheGattServerCallback::OnDescriptorReadRequest(const BluetoothRemoteDevice &device,148void TaiheGattServerCallback::OnDescriptorReadRequest(const BluetoothRemoteDevice &device,
@@ -86,12 +150,30 @@ void TaiheGattServerCallback::OnDescriptorReadRequest(const BluetoothRemoteDevic
86{150{
87 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",151 HILOGI("enter, remote device address: %{public}s, requestId: %{public}d",
88 GET_ENCRYPT_ADDR(device), requestId);152 GET_ENCRYPT_ADDR(device), requestId);
153+ std::string characteristicUuid;
154+ std::string serviceUuid;
155+ if (descriptor.GetCharacteristic() != nullptr) {
156+ characteristicUuid = descriptor.GetCharacteristic()->GetUuid().ToString();
157+ if (descriptor.GetCharacteristic()->GetService() != nullptr) {
158+ serviceUuid = descriptor.GetCharacteristic()->GetService()->GetUuid().ToString();
159+ }
160+ }
161+ ::ohos::bluetooth::ble::DescriptorReadRequest request{
162+ taihe::string(device.GetDeviceAddr()),
163+ requestId,
164+ 0,
165+ taihe::string(descriptor.GetUuid().ToString()),
166+ taihe::string(characteristicUuid),
167+ taihe::string(serviceUuid)
168+ };
169+ descriptorReadEvent_.PublishEvent(request);
89}170}
90 171 
91void TaiheGattServerCallback::OnMtuUpdate(const BluetoothRemoteDevice &device, int mtu)172void TaiheGattServerCallback::OnMtuUpdate(const BluetoothRemoteDevice &device, int mtu)
92{173{
93 HILOGI("enter, remote device address: %{public}s, mtu: %{public}d",174 HILOGI("enter, remote device address: %{public}s, mtu: %{public}d",
94 GET_ENCRYPT_ADDR(device), mtu);175 GET_ENCRYPT_ADDR(device), mtu);
176+ bleMtuChangeEvent_.PublishEvent(mtu);
95}177}
96 178 
97void TaiheGattServerCallback::OnNotificationCharacteristicChanged(const BluetoothRemoteDevice &device, int ret)179void TaiheGattServerCallback::OnNotificationCharacteristicChanged(const BluetoothRemoteDevice &device, int ret)
@@ -100,5 +182,25 @@ void TaiheGattServerCallback::OnNotificationCharacteristicChanged(const Bluetoot
100 auto taiheRet = std::make_shared<TaiheNativeInt>(ret);182 auto taiheRet = std::make_shared<TaiheNativeInt>(ret);
101 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_SERVER_NOTIFY_CHARACTERISTIC, taiheRet, ret);183 AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_SERVER_NOTIFY_CHARACTERISTIC, taiheRet, ret);
102}184}
185+ 
186+void TaiheGattServerCallback::OnBlePhyUpdate(const BluetoothRemoteDevice &device,
187+ int32_t txPhy, int32_t rxPhy, int32_t status)
188+{
189+ HILOGI("remote device address: %{public}s, txPhy: %{public}d, rxPhy: %{public}d, status: %{public}d",
190+ GET_ENCRYPT_ADDR(device), txPhy, rxPhy, status);
191+ AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_SERVER_SET_PHY, nullptr, status);
192+ ::ohos::bluetooth::ble::PhyValue phyValue{
193+ ::ohos::bluetooth::ble::BlePhy::from_value(txPhy),
194+ ::ohos::bluetooth::ble::BlePhy::from_value(rxPhy)
195+ };
196+ blePhyUpdateEvent_.PublishEvent(phyValue);
197+}
198+ 
199+void TaiheGattServerCallback::OnBlePhyRead(int32_t txPhy, int32_t rxPhy, int32_t status)
200+{
201+ HILOGI("txPhy: %{public}d, rxPhy: %{public}d, status: %{public}d", txPhy, rxPhy, status);
202+ auto taihePhyValue = std::make_shared<TaiheNativePhyValue>(txPhy, rxPhy);
203+ AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GATT_SERVER_READ_PHY, taihePhyValue, status);
204+}
103} // namespace Bluetooth205} // namespace Bluetooth
104} // namespace OHOS206} // namespace OHOS
@@ -0,0 +1,109 @@
1+# Copyright (C) 2025 Huawei Device Co., Ltd.
2+# Licensed under the Apache License, Version 2.0 (the "License");
3+# you may not use this file except in compliance with the License.
4+# You may obtain a copy of the License at
5+#
6+# http://www.apache.org/licenses/LICENSE-2.0
7+#
8+# Unless required by applicable law or agreed to in writing, software
9+# distributed under the License is distributed on an "AS IS" BASIS,
10+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+# See the License for the specific language governing permissions and
12+# limitations under the License.
13+ 
14+import("//build/config/components/ets_frontend/ets2abc_config.gni")
15+import("//build/ohos.gni")
16+import("//build/ohos/taihe_idl/taihe.gni")
17+ 
18+SUBSYSTEM_DIR = "//foundation/communication"
19+ 
20+copy_taihe_idl("bluetooth_common_taihe") {
21+ sources = [ "idl/ohos.bluetooth.common.taihe" ]
22+}
23+ 
24+subsystem_name = "communication"
25+part_name = "bluetooth"
26+taihe_generated_file_path_common = "$taihe_file_path/out/$subsystem_name/$part_name/common"
27+ 
28+ohos_taihe("run_taihe") {
29+ taihe_generated_file_path = "${taihe_generated_file_path_common}"
30+ deps = [ ":bluetooth_common_taihe" ]
31+ outputs = [
32+ "$taihe_generated_file_path/src/ohos.bluetooth.common.ani.cpp",
33+ "$taihe_generated_file_path/src/ohos.bluetooth.common.abi.c",
34+ ]
35+}
36+ 
37+taihe_shared_library("bluetoothCommon_taihe_native") {
38+ cflags_cc = [
39+ "-Os",
40+ "-fno-rtti",
41+ "-fno-exceptions",
42+ "-fdata-sections",
43+ "-ffunction-sections",
44+ "-fno-unwind-tables",
45+ "-fno-asynchronous-unwind-tables",
46+ "-fno-merge-all-constants",
47+ "-flto",
48+ ]
49+ ldflags = [
50+ "-Wl,--as-needed",
51+ "-Wl,--gc-sections",
52+ ]
53+ shlib_type = "ani"
54+ taihe_generated_file_path = "${taihe_generated_file_path_common}"
55+ part_name = "$part_name"
56+ subsystem_name = "$subsystem_name"
57+ sources = get_target_outputs(":run_taihe")
58+ include_dirs = [
59+ "include",
60+ "src",
61+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include",
62+ "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include"
63+ ]
64+ sources += [
65+ "src/ani_constructor.cpp",
66+ "src/ohos.bluetooth.common.impl.cpp",
67+ ]
68+ deps = [
69+ ":run_taihe",
70+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner:btframework",
71+ ]
72+ external_deps = [
73+ "c_utils:utils",
74+ "hilog:libhilog",
75+ ]
76+ sanitize = {
77+ cfi = true # Enable/disable control flow integrity detection
78+ boundary_sanitize = true # Enable boundary san detection
79+ cfi_cross_dso = true # Cross-SO CFI Checks
80+ cfi_vcall_icall_only = true # CFI optimization, restrict CFI detection scope
81+ integer_overflow = true # Enable integer overflow detection
82+ ubsan = true # Enable some Ubsan options
83+ debug = false
84+ }
85+}
86+ 
87+generate_static_abc("bluetoothCommon_abc") {
88+ base_url = "${taihe_generated_file_path_common}"
89+ files = [ "${taihe_generated_file_path_common}/@ohos.bluetooth.common.ets" ]
90+ is_boot_abc = "True"
91+ device_dst_file = "/system/framework/bluetoothCommon_abc.abc"
92+ dependencies = [ ":run_taihe" ]
93+}
94+ 
95+ohos_prebuilt_etc("bluetoothCommon_etc") {
96+ source = "$target_out_dir/bluetoothCommon_abc.abc"
97+ module_install_dir = "framework"
98+ part_name = "$part_name"
99+ subsystem_name = "$subsystem_name"
100+ deps = [ ":bluetoothCommon_abc" ]
101+}
102+ 
103+group("bluetoothCommon_taihe") {
104+ deps = [
105+ ":bluetoothCommon_etc",
106+ ":bluetoothCommon_taihe_native"
107+ ]
108+ # deps = [":run_taihe"]
109+}
@@ -0,0 +1,20 @@
1+@!namespace("@ohos.bluetooth.common", "common")
2+@!sts_inject("""
3+static { loadLibraryWithPermissionCheck("bluetoothCommon_taihe_native.z", "@ohos.bluetooth.common") }
4+""")
5+ 
6+struct BluetoothAddress{
7+ address: String;
8+ addressType: BluetoothAddressType;
9+ rawAddressType: Optional<BluetoothRawAddressType>;
10+}
11+ 
12+enum BluetoothAddressType: i32 {
13+ VIRTUAL = 1,
14+ REAL = 2,
15+}
16+ 
17+enum BluetoothRawAddressType: i32 {
18+ PUBLIC = 0,
19+ RANDOM = 1,
20+}
@@ -0,0 +1,29 @@
1+/*
2+ * Copyright (C) 2025 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.bluetooth.common.ani.hpp"
17+ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
18+{
19+ ani_env *env;
20+ if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
21+ return ANI_ERROR;
22+ }
23+ if (ANI_OK != ohos::bluetooth::common::ANIRegister(env)) {
24+ std::cerr << "Error from ohos::bluetooth::common::ANIRegister" << std::endl;
25+ return ANI_ERROR;
26+ }
27+ *result = ANI_VERSION_1;
28+ return ANI_OK;
29+}
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2025 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.bluetooth.common.proj.hpp"
17+#include "ohos.bluetooth.common.impl.hpp"
18+#include "taihe/runtime.hpp"
19+#include "stdexcept"
20+ 
21+using namespace taihe;
22+using namespace ohos::bluetooth::common;
23+ 
24+namespace {
25+// To be implemented.
26+} // namespace
27+ 
28+// Since these macros are auto-generate, lint will cause false positive.
29+// NOLINTBEGIN
30+// NOLINTEND
@@ -18,6 +18,7 @@
18static { loadLibraryWithPermissionCheck("bluetoothConnection_taihe_native.z", "@ohos.bluetooth.connection") }18static { loadLibraryWithPermissionCheck("bluetoothConnection_taihe_native.z", "@ohos.bluetooth.connection") }
19""")19""")
20from ohos.bluetooth.constant use MajorClass, MajorMinorClass, ProfileConnectionState, ProfileId, ProfileUuids;20from ohos.bluetooth.constant use MajorClass, MajorMinorClass, ProfileConnectionState, ProfileId, ProfileUuids;
21+from ohos.bluetooth.common use BluetoothAddress;
21 22 
22@!sts_inject("""23@!sts_inject("""
23export function on(type: string, cb: (arg_0: Object) => void): void {24export function on(type: string, cb: (arg_0: Object) => void): void {
@@ -269,4 +270,65 @@ function CancelPairedDeviceSync(deviceId: String): void;
269 270 
270@gen_async("pairCredibleDevice")271@gen_async("pairCredibleDevice")
271@gen_promise("pairCredibleDevice")272@gen_promise("pairCredibleDevice")
272-function PairCredibleDeviceSync(deviceId: String, transport: BluetoothTransport): void;273+function PairCredibleDeviceSync(deviceId: String, transport: BluetoothTransport): void;
274+ 
275+function SetLocalName(name: String): void;
276+ 
277+@gen_promise("startPairOutOfBand")
278+function StartPairOutOfBandSync(deviceId: String, transport: BluetoothTransport, p192Data: Optional<OobData>, p256Data: Optional<OobData>): void;
279+ 
280+@gen_promise("generateLocalOobData")
281+function GenerateLocalOobDataSync(transport: BluetoothTransport): OobData;
282+ 
283+function GetVirtualAddressByHash(algorithmType: HashAlgorithmType, hashValue: String): String;
284+ 
285+@gen_promise("pairDeviceOutOfBand")
286+function PairDeviceOutOfBandSync(transport: BluetoothTransport, p192Data: OobDataNullValue, p256Data: OobDataNullValue): void;
287+ 
288+function GetCarKeyDfxData(): String;
289+function GetRemoteDeviceTransport(deviceId: String): BluetoothTransport;
290+function SetCarKeyDfxData(deviceId: String, action: CarKeyActionType): void;
291+ 
292+function OnAclStateChange(callback: (data: AclStateResult) => void): void;
293+function OffAclStateChange(callback: Optional<(data: AclStateResult) => void>): void;
294+function OnScanModeChange(callback: (data: ScanMode) => void): void;
295+function OffScanModeChange(callback: Optional<(data: ScanMode) => void>): void;
296+ 
297+struct OobData {
298+ deviceId: BluetoothAddress;
299+ confirmationHash: @arraybuffer Array<u8>;
300+ randomizerHash: Optional<@arraybuffer Array<u8>>;
301+ deviceName: Optional<String>;
302+ deviceRole: Optional<DeviceRole>;
303+}
304+ 
305+enum DeviceRole: i32 {
306+ DEVICE_ROLE_PERIPHERAL_ONLY = 0,
307+ DEVICE_ROLE_CENTRAL_ONLY = 1,
308+ DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 2,
309+ DEVICE_ROLE_BOTH_PREFER_CENTRAL = 3
310+}
311+ 
312+enum HashAlgorithmType: i32 {
313+ HASH_ALGORITHM_SHA256 = 0
314+}
315+ 
316+enum CarKeyActionType: i32 {
317+ CAR_KEY_ACTION_ADD = 0,
318+ CAR_KEY_ACTION_DELETE = 1
319+}
320+ 
321+struct AclStateResult {
322+ deviceId: String;
323+ state: AclState;
324+}
325+ 
326+enum AclState: i32 {
327+ STATE_CONNECTED = 0,
328+ STATE_DISCONNECTED = 1
329+}
330+ 
331+union OobDataNullValue {
332+ data: OobData;
333+ @null nValue;
334+}
@@ -69,6 +69,10 @@ public:
69 std::vector<::taihe::optional<::taihe::callback<void(69 std::vector<::taihe::optional<::taihe::callback<void(
70 ::ohos::bluetooth::connection::BatteryInfo const& data)>>> remoteBatteryChangeVec = {};70 ::ohos::bluetooth::connection::BatteryInfo const& data)>>> remoteBatteryChangeVec = {};
71 std::shared_mutex remoteBatteryChangeLock;71 std::shared_mutex remoteBatteryChangeLock;
72+ 
73+ std::vector<::taihe::optional<::taihe::callback<void(
74+ ::ohos::bluetooth::connection::AclStateResult const& data)>>> aclStateChangeVec = {};
75+ std::shared_mutex aclStateChangeLock;
72};76};
73 77 
74class TaiheBluetoothConnectionObserver : public BluetoothHostObserver {78class TaiheBluetoothConnectionObserver : public BluetoothHostObserver {
@@ -100,6 +104,10 @@ public:
100 ::ohos::bluetooth::connection::PinRequiredParam const& data)>>> pinRequiredVec = {};104 ::ohos::bluetooth::connection::PinRequiredParam const& data)>>> pinRequiredVec = {};
101 std::shared_mutex pinRequiredLock;105 std::shared_mutex pinRequiredLock;
102 106 
107+ std::vector<::taihe::optional<::taihe::callback<void(
108+ ::ohos::bluetooth::connection::ScanMode data)>>> scanModeChangeVec = {};
109+ std::shared_mutex scanModeChangeLock;
110+ 
103private:111private:
104 void OnPairConfirmedCallBack(const std::shared_ptr<PairConfirmedCallBackInfo> &pairConfirmInfo);112 void OnPairConfirmedCallBack(const std::shared_ptr<PairConfirmedCallBackInfo> &pairConfirmInfo);
105 void OnDiscoveryResultCallBack(const BluetoothRemoteDevice &device);113 void OnDiscoveryResultCallBack(const BluetoothRemoteDevice &device);
@@ -21,10 +21,17 @@
21#include "ohos.bluetooth.connection.impl.hpp"21#include "ohos.bluetooth.connection.impl.hpp"
22#include "taihe/runtime.hpp"22#include "taihe/runtime.hpp"
23#include "stdexcept"23#include "stdexcept"
24+ 
25+ 
26+#include <future>
27+#include <regex>
28+#include <sstream>
29+#include <iomanip>
24#include "bluetooth_remote_device.h"30#include "bluetooth_remote_device.h"
25#include "bluetooth_host.h"31#include "bluetooth_host.h"
26#include "bluetooth_log.h"32#include "bluetooth_log.h"
27#include "bluetooth_errorcode.h"33#include "bluetooth_errorcode.h"
34+#include "bluetooth_oob_data.h"
28#include "taihe_bluetooth_connection_callback.h"35#include "taihe_bluetooth_connection_callback.h"
29#include "taihe_bluetooth_utils.h"36#include "taihe_bluetooth_utils.h"
30#include "taihe_event_module.h"37#include "taihe_event_module.h"
@@ -61,6 +68,153 @@ static void ConvertUuidsVectorToTaiheArray(std::vector<std::string> const& uuids
61 taihe::copy_data_t{}, profileUuidsVec.data(), profileUuidsVec.size());68 taihe::copy_data_t{}, profileUuidsVec.data(), profileUuidsVec.size());
62}69}
63 70 
71+constexpr int ADDRESS_BYTE_LEN = 6;
72+constexpr int ADDRESS_WITH_TYPE_BYTE_LEN = 7;
73+ 
74+static std::string HexByteToString(uint8_t value)
75+{
76+ std::stringstream ss;
77+ ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(value);
78+ return ss.str();
79+}
80+ 
81+static void GetAddressWithTypeFromAddress(const std::string &address, uint8_t rawAddressType,
82+ std::vector<uint8_t> &addressWithType)
83+{
84+ std::string hexAddrStr = std::regex_replace(address, std::regex(":"), "");
85+ for (size_t i = 0; i + 1 < hexAddrStr.length(); i += 2) {
86+ std::string byteStr = hexAddrStr.substr(i, 2);
87+ uint8_t byte = static_cast<uint8_t>(std::stoul(byteStr, nullptr, 16));
88+ addressWithType.push_back(byte);
89+ }
90+ addressWithType.push_back(rawAddressType);
91+}
92+ 
93+static std::string BuildAddressStringFromBytes(const std::vector<uint8_t> &data)
94+{
95+ std::string addr = "";
96+ if (data.size() != ADDRESS_BYTE_LEN) {
97+ HILOGE("Invalid address length");
98+ return addr;
99+ }
100+ for (size_t i = 0; i < ADDRESS_BYTE_LEN; i++) {
101+ addr += HexByteToString(data[i]);
102+ if (i < ADDRESS_BYTE_LEN - 1) {
103+ addr += ":";
104+ }
105+ }
106+ std::transform(addr.begin(), addr.end(), addr.begin(), ::toupper);
107+ return addr;
108+}
109+ 
110+static OobData ConvertTaiheOobDataToNative(
111+ const ::ohos::bluetooth::connection::OobData &taiheOobData, uint8_t oobType)
112+{
113+ OobData nativeOobData;
114+ std::string address = static_cast<std::string>(taiheOobData.deviceId.address);
115+ uint8_t rawAddressType = RawAddressType::RANDOM_ADDRESS;
116+ if (taiheOobData.deviceId.rawAddressType.has_value()) {
117+ rawAddressType = static_cast<uint8_t>(taiheOobData.deviceId.rawAddressType.value().get_value());
118+ }
119+ std::vector<uint8_t> addressWithType;
120+ GetAddressWithTypeFromAddress(address, rawAddressType, addressWithType);
121+ nativeOobData.SetAddressWithType(addressWithType);
122+ 
123+ std::vector<uint8_t> confirmHash;
124+ for (auto b : taiheOobData.confirmationHash) {
125+ confirmHash.push_back(b);
126+ }
127+ nativeOobData.SetConfirmationHash(confirmHash);
128+ 
129+ if (taiheOobData.randomizerHash.has_value()) {
130+ std::vector<uint8_t> randomHash;
131+ for (auto b : taiheOobData.randomizerHash.value()) {
132+ randomHash.push_back(b);
133+ }
134+ nativeOobData.SetRandomizerHash(randomHash);
135+ }
136+ 
137+ if (taiheOobData.deviceName.has_value()) {
138+ nativeOobData.SetDeviceName(static_cast<std::string>(taiheOobData.deviceName.value()));
139+ }
140+ 
141+ if (taiheOobData.deviceRole.has_value()) {
142+ nativeOobData.SetDeviceRole(static_cast<uint8_t>(taiheOobData.deviceRole.value().get_value()));
143+ }
144+ 
145+ nativeOobData.SetOobDataType(oobType);
146+ return nativeOobData;
147+}
148+ 
149+static ::ohos::bluetooth::connection::OobData ConvertNativeOobDataToTaihe(const OobData &nativeOobData)
150+{
151+ std::string address = "";
152+ uint8_t rawAddressType = RawAddressType::RANDOM_ADDRESS;
153+ if (nativeOobData.HasAddressWithType()) {
154+ std::vector<uint8_t> addressWithType = nativeOobData.GetAddressWithType();
155+ if (addressWithType.size() == ADDRESS_WITH_TYPE_BYTE_LEN) {
156+ std::vector<uint8_t> addressVec(addressWithType.begin(), addressWithType.begin() + ADDRESS_BYTE_LEN);
157+ address = BuildAddressStringFromBytes(addressVec);
158+ rawAddressType = addressWithType[ADDRESS_BYTE_LEN];
159+ }
160+ }
161+ 
162+ auto deviceId = ::ohos::bluetooth::common::BluetoothAddress{
163+ .address = ::taihe::string(address),
164+ .addressType = ::ohos::bluetooth::common::BluetoothAddressType(
165+ ::ohos::bluetooth::common::BluetoothAddressType::key_t::REAL),
166+ .rawAddressType = ::taihe::optional<::ohos::bluetooth::common::BluetoothRawAddressType>(
167+ std::in_place, ::ohos::bluetooth::common::BluetoothRawAddressType::from_value(rawAddressType)),
168+ };
169+ 
170+ std::vector<uint8_t> confirmHashVec =
171+ nativeOobData.HasConfirmHash() ? nativeOobData.GetConfirmationHash() : std::vector<uint8_t>{};
172+ 
173+ ::taihe::optional<::taihe::array<uint8_t>> randomizerHashOpt;
174+ if (nativeOobData.HasRandomHash()) {
175+ std::vector<uint8_t> randomHash = nativeOobData.GetRandomizerHash();
176+ randomizerHashOpt.emplace(::taihe::copy_data, randomHash.data(), randomHash.size());
177+ }
178+ 
179+ ::taihe::optional<::taihe::string> deviceNameOpt;
180+ if (nativeOobData.HasDeviceName()) {
181+ deviceNameOpt.emplace(nativeOobData.GetDeviceName());
182+ }
183+ 
184+ ::taihe::optional<::ohos::bluetooth::connection::DeviceRole> deviceRoleOpt;
185+ deviceRoleOpt.emplace(::ohos::bluetooth::connection::DeviceRole::from_value(nativeOobData.GetDeviceRole()));
186+ 
187+ return ::ohos::bluetooth::connection::OobData{
188+ .deviceId = deviceId,
189+ .confirmationHash = ::taihe::array<uint8_t>(::taihe::copy_data, confirmHashVec.data(), confirmHashVec.size()),
190+ .randomizerHash = randomizerHashOpt,
191+ .deviceName = deviceNameOpt,
192+ .deviceRole = deviceRoleOpt,
193+ };
194+}
195+ 
196+class TaiheOobCallback : public BluetoothOobCallback {
197+public:
198+ void OnGenerateLocalOobData(int32_t ret, const OobData &oobData) override
199+ {
200+ ret_ = ret;
201+ oobData_ = oobData;
202+ promise_.set_value();
203+ }
204+ 
205+ int32_t GetResult(OobData &oobData)
206+ {
207+ promise_.get_future().get();
208+ oobData = oobData_;
209+ return ret_;
210+ }
211+ 
212+private:
213+ std::promise<void> promise_;
214+ int32_t ret_ = BT_NO_ERROR;
215+ OobData oobData_;
216+};
217+ 
64taihe::string GetRemoteProductId(taihe::string_view deviceId)218taihe::string GetRemoteProductId(taihe::string_view deviceId)
65{219{
66 HILOGD("start");220 HILOGD("start");
@@ -734,6 +888,170 @@ void PairCredibleDeviceSync(taihe::string_view deviceId, ohos::bluetooth::connec
734 HILOGI("err: %{public}d", err);888 HILOGI("err: %{public}d", err);
735 TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);889 TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);
736}890}
891+ 
892+void SetLocalName(::taihe::string_view name) {
893+ HILOGD("enter");
894+ std::string localName = static_cast<std::string>(name);
895+ BluetoothHost *host = &BluetoothHost::GetDefaultHost();
896+ int32_t ret = host->SetLocalName(localName);
897+ TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
898+}
899+ 
900+void StartPairOutOfBandSync(::taihe::string_view deviceId, ::ohos::bluetooth::connection::BluetoothTransport transport, ::taihe::optional_view<::ohos::bluetooth::connection::OobData> p192Data, ::taihe::optional_view<::ohos::bluetooth::connection::OobData> p256Data) {
901+ HILOGD("enter");
902+ std::string remoteAddr = std::string(deviceId);
903+ bool checkRet = CheckDeviceIdParam(remoteAddr);
904+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
905+ 
906+ int32_t transportType = transport.get_value();
907+ BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr, transportType);
908+ 
909+ int32_t err = BT_ERR_INVALID_PARAM;
910+ if (p256Data.has_value()) {
911+ OobData nativeOobData = ConvertTaiheOobDataToNative(p256Data.value(), OobDataType::P256);
912+ err = remoteDevice.StartPairOutOfBand(nativeOobData);
913+ } else if (p192Data.has_value()) {
914+ OobData nativeOobData = ConvertTaiheOobDataToNative(p192Data.value(), OobDataType::P192);
915+ err = remoteDevice.StartPairOutOfBand(nativeOobData);
916+ }
917+ TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);
918+}
919+ 
920+::ohos::bluetooth::connection::OobData GenerateLocalOobDataSync(::ohos::bluetooth::connection::BluetoothTransport transport) {
921+ HILOGD("enter");
922+ int32_t transportType = transport.get_value();
923+ auto callback = std::make_shared<TaiheOobCallback>();
924+ int32_t err = BluetoothHost::GetDefaultHost().GenerateLocalOobData(transportType, callback);
925+ TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err, ConvertNativeOobDataToTaihe(OobData{}));
926+ 
927+ OobData nativeOobData;
928+ int32_t ret = callback->GetResult(nativeOobData);
929+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret, ConvertNativeOobDataToTaihe(OobData{}));
930+ 
931+ return ConvertNativeOobDataToTaihe(nativeOobData);
932+}
933+ 
934+::taihe::string GetVirtualAddressByHash(::ohos::bluetooth::connection::HashAlgorithmType algorithmType, ::taihe::string_view hashValue) {
935+ HILOGD("enter");
936+ int32_t hashAlgorithmType = algorithmType.get_value();
937+ std::string hash = static_cast<std::string>(hashValue);
938+ std::string virtualAddress;
939+ BluetoothHost *host = &BluetoothHost::GetDefaultHost();
940+ int32_t err = host->GetVirtualAddressByHash(hashAlgorithmType, hash, virtualAddress);
941+ TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err, virtualAddress);
942+ return virtualAddress;
943+}
944+ 
945+void PairDeviceOutOfBandSync(::ohos::bluetooth::connection::BluetoothTransport transport, ::ohos::bluetooth::connection::OobDataNullValue const& p192Data, ::ohos::bluetooth::connection::OobDataNullValue const& p256Data) {
946+ HILOGD("enter");
947+ int32_t transportType = transport.get_value();
948+ 
949+ int32_t err = BT_ERR_INVALID_PARAM;
950+ if (p256Data.holds_data()) {
951+ auto &taiheOobData = p256Data.get_data_ref();
952+ std::string address = static_cast<std::string>(taiheOobData.deviceId.address);
953+ OobData nativeOobData = ConvertTaiheOobDataToNative(taiheOobData, OobDataType::P256);
954+ BluetoothRemoteDevice remoteDevice(address, transportType);
955+ err = remoteDevice.StartPairOutOfBand(nativeOobData);
956+ } else if (p192Data.holds_data()) {
957+ auto &taiheOobData = p192Data.get_data_ref();
958+ std::string address = static_cast<std::string>(taiheOobData.deviceId.address);
959+ OobData nativeOobData = ConvertTaiheOobDataToNative(taiheOobData, OobDataType::P192);
960+ BluetoothRemoteDevice remoteDevice(address, transportType);
961+ err = remoteDevice.StartPairOutOfBand(nativeOobData);
962+ }
963+ TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);
964+}
965+ 
966+::taihe::string GetCarKeyDfxData() {
967+ HILOGD("enter");
968+ BluetoothHost *host = &BluetoothHost::GetDefaultHost();
969+ std::string dfxData;
970+ int32_t err = host->GetCarKeyDfxData(dfxData);
971+ TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err, dfxData);
972+ return dfxData;
973+}
974+ 
975+::ohos::bluetooth::connection::BluetoothTransport GetRemoteDeviceTransport(::taihe::string_view deviceId) {
976+ HILOGD("enter");
977+ std::string remoteAddr = std::string(deviceId);
978+ bool checkRet = CheckDeviceIdParam(remoteAddr);
979+ int32_t transport = 0;
980+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
981+ ::ohos::bluetooth::connection::BluetoothTransport::from_value(transport));
982+ 
983+ BluetoothRemoteDevice remoteDevice = BluetoothRemoteDevice(remoteAddr);
984+ int32_t err = remoteDevice.GetDeviceTransport(transport);
985+ TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err,
986+ ::ohos::bluetooth::connection::BluetoothTransport::from_value(transport));
987+ return ::ohos::bluetooth::connection::BluetoothTransport::from_value(transport);
988+}
989+ 
990+void SetCarKeyDfxData(::taihe::string_view deviceId, ::ohos::bluetooth::connection::CarKeyActionType action) {
991+ HILOGD("enter");
992+ std::string remoteAddr = std::string(deviceId);
993+ bool checkRet = CheckDeviceIdParam(remoteAddr);
994+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
995+ 
996+ int32_t actionValue = action.get_value();
997+ BluetoothHost *host = &BluetoothHost::GetDefaultHost();
998+ int32_t ret = host->SetCarKeyCardData(remoteAddr, actionValue);
999+ TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
1000+}
1001+ 
1002+void OnAclStateChange(::taihe::callback_view<void(::ohos::bluetooth::connection::AclStateResult const& data)> callback) {
1003+ std::unique_lock<std::shared_mutex> guard(g_remoteDeviceObserver->aclStateChangeLock);
1004+ auto aclStateChangeCb = ::taihe::optional<::taihe::callback<void(
1005+ ::ohos::bluetooth::connection::AclStateResult const& data)>>{std::in_place_t{}, callback};
1006+ auto& callbackVec = g_remoteDeviceObserver->aclStateChangeVec;
1007+ if (std::find(callbackVec.begin(), callbackVec.end(), aclStateChangeCb) != callbackVec.end()) {
1008+ return;
1009+ }
1010+ callbackVec.emplace_back(aclStateChangeCb);
1011+}
1012+ 
1013+void OffAclStateChange(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::connection::AclStateResult const& data)>> callback) {
1014+ std::unique_lock<std::shared_mutex> guard(g_remoteDeviceObserver->aclStateChangeLock);
1015+ auto& callbackVec = g_remoteDeviceObserver->aclStateChangeVec;
1016+ if (callback.has_value()) {
1017+ callbackVec.erase(
1018+ std::remove_if(callbackVec.begin(), callbackVec.end(),
1019+ [callback](const ::taihe::optional<
1020+ ::taihe::callback<void(::ohos::bluetooth::connection::AclStateResult const& data)>>& it) {
1021+ return it == callback;
1022+ }),
1023+ callbackVec.end());
1024+ } else {
1025+ callbackVec.clear();
1026+ }
1027+}
1028+ 
1029+void OnScanModeChange(::taihe::callback_view<void(::ohos::bluetooth::connection::ScanMode data)> callback) {
1030+ std::unique_lock<std::shared_mutex> guard(g_connectionObserver->scanModeChangeLock);
1031+ auto scanModeChangeCb = ::taihe::optional<::taihe::callback<void(
1032+ ::ohos::bluetooth::connection::ScanMode data)>>{std::in_place_t{}, callback};
1033+ auto& callbackVec = g_connectionObserver->scanModeChangeVec;
1034+ if (std::find(callbackVec.begin(), callbackVec.end(), scanModeChangeCb) != callbackVec.end()) {
1035+ return;
1036+ }
1037+ callbackVec.emplace_back(scanModeChangeCb);
1038+}
1039+ 
1040+void OffScanModeChange(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::connection::ScanMode data)>> callback) {
1041+ std::unique_lock<std::shared_mutex> guard(g_connectionObserver->scanModeChangeLock);
1042+ auto& callbackVec = g_connectionObserver->scanModeChangeVec;
1043+ if (callback.has_value()) {
1044+ callbackVec.erase(
1045+ std::remove_if(callbackVec.begin(), callbackVec.end(),
1046+ [callback](const ::taihe::optional<
1047+ ::taihe::callback<void(::ohos::bluetooth::connection::ScanMode data)>>& it) {
1048+ return it == callback;
1049+ }),
1050+ callbackVec.end());
1051+ } else {
1052+ callbackVec.clear();
1053+ }
1054+}
737} // Bluetooth1055} // Bluetooth
738} // OHOS1056} // OHOS
739 1057 
@@ -778,4 +1096,16 @@ TH_EXPORT_CPP_API_SetDevicePinCodeSync(OHOS::Bluetooth::SetDevicePinCodeSync);
778TH_EXPORT_CPP_API_CancelPairingDeviceSync(OHOS::Bluetooth::CancelPairingDeviceSync);1096TH_EXPORT_CPP_API_CancelPairingDeviceSync(OHOS::Bluetooth::CancelPairingDeviceSync);
779TH_EXPORT_CPP_API_CancelPairedDeviceSync(OHOS::Bluetooth::CancelPairedDeviceSync);1097TH_EXPORT_CPP_API_CancelPairedDeviceSync(OHOS::Bluetooth::CancelPairedDeviceSync);
780TH_EXPORT_CPP_API_PairCredibleDeviceSync(OHOS::Bluetooth::PairCredibleDeviceSync);1098TH_EXPORT_CPP_API_PairCredibleDeviceSync(OHOS::Bluetooth::PairCredibleDeviceSync);
1099+TH_EXPORT_CPP_API_SetLocalName(OHOS::Bluetooth::SetLocalName);
1100+TH_EXPORT_CPP_API_StartPairOutOfBandSync(OHOS::Bluetooth::StartPairOutOfBandSync);
1101+TH_EXPORT_CPP_API_GenerateLocalOobDataSync(OHOS::Bluetooth::GenerateLocalOobDataSync);
1102+TH_EXPORT_CPP_API_GetVirtualAddressByHash(OHOS::Bluetooth::GetVirtualAddressByHash);
1103+TH_EXPORT_CPP_API_PairDeviceOutOfBandSync(OHOS::Bluetooth::PairDeviceOutOfBandSync);
1104+TH_EXPORT_CPP_API_GetCarKeyDfxData(OHOS::Bluetooth::GetCarKeyDfxData);
1105+TH_EXPORT_CPP_API_GetRemoteDeviceTransport(OHOS::Bluetooth::GetRemoteDeviceTransport);
1106+TH_EXPORT_CPP_API_SetCarKeyDfxData(OHOS::Bluetooth::SetCarKeyDfxData);
1107+TH_EXPORT_CPP_API_OnAclStateChange(OHOS::Bluetooth::OnAclStateChange);
1108+TH_EXPORT_CPP_API_OffAclStateChange(OHOS::Bluetooth::OffAclStateChange);
1109+TH_EXPORT_CPP_API_OnScanModeChange(OHOS::Bluetooth::OnScanModeChange);
1110+TH_EXPORT_CPP_API_OffScanModeChange(OHOS::Bluetooth::OffScanModeChange);
781// NOLINTEND1111// NOLINTEND
@@ -49,7 +49,25 @@ std::shared_ptr<TaiheBluetoothRemoteDeviceObserver> TaiheBluetoothRemoteDeviceOb
49 49 
50void TaiheBluetoothRemoteDeviceObserver::OnAclStateChanged(50void TaiheBluetoothRemoteDeviceObserver::OnAclStateChanged(
51 const BluetoothRemoteDevice &device, int state, unsigned int reason)51 const BluetoothRemoteDevice &device, int state, unsigned int reason)
52-{}52+{
53+ std::shared_lock<std::shared_mutex> guard(aclStateChangeLock);
54+ int aclStateValue = (state == 0) ?
55+ static_cast<int>(::ohos::bluetooth::connection::AclState::key_t::STATE_DISCONNECTED) :
56+ static_cast<int>(::ohos::bluetooth::connection::AclState::key_t::STATE_CONNECTED);
57+ HILOGI("addr:%{public}s, state:%{public}d, reason:%{public}d", GET_ENCRYPT_ADDR(device), state, reason);
58+ 
59+ auto deviceId_ = static_cast<::taihe::string>(device.GetDeviceAddr());
60+ auto state_ = ::ohos::bluetooth::connection::AclState::from_value(aclStateValue);
61+ auto taiheResult = ::ohos::bluetooth::connection::AclStateResult{
62+ .deviceId = deviceId_,
63+ .state = state_,
64+ };
65+ for (auto callback : aclStateChangeVec) {
66+ if (callback) {
67+ (*callback)(taiheResult);
68+ }
69+ }
70+}
53 71 
54void TaiheBluetoothRemoteDeviceObserver::OnPairStatusChanged(const BluetoothRemoteDevice &device, int status, int cause)72void TaiheBluetoothRemoteDeviceObserver::OnPairStatusChanged(const BluetoothRemoteDevice &device, int status, int cause)
55{73{
@@ -211,7 +229,14 @@ void TaiheBluetoothConnectionObserver::OnPairConfirmed(const BluetoothRemoteDevi
211 229 
212void TaiheBluetoothConnectionObserver::OnScanModeChanged(int mode)230void TaiheBluetoothConnectionObserver::OnScanModeChanged(int mode)
213{231{
232+ std::shared_lock<std::shared_mutex> guard(scanModeChangeLock);
214 HILOGI("mode is %{public}d", mode);233 HILOGI("mode is %{public}d", mode);
234+ auto taiheResult = ::ohos::bluetooth::connection::ScanMode::from_value(mode);
235+ for (auto callback : scanModeChangeVec) {
236+ if (callback) {
237+ (*callback)(taiheResult);
238+ }
239+ }
215}240}
216 241 
217void TaiheBluetoothConnectionObserver::OnDeviceNameChanged(const std::string &deviceName)242void TaiheBluetoothConnectionObserver::OnDeviceNameChanged(const std::string &deviceName)
@@ -22,7 +22,8 @@ copy_taihe_idl("bluetooth_hfp_taihe") {
22 "idl/ohos.bluetooth.hfp.taihe"22 "idl/ohos.bluetooth.hfp.taihe"
23 ]23 ]
24 deps = [24 deps = [
25- "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_baseProfile:bluetooth_baseProfile_taihe"25+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_baseProfile:bluetooth_baseProfile_taihe",
26+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetooth_constant_taihe"
26 ]27 ]
27}28}
28 29 
@@ -71,6 +72,7 @@ taihe_shared_library("bluetoothHfp_taihe_native") {
71 "src/ani_constructor.cpp",72 "src/ani_constructor.cpp",
72 "src/ohos.bluetooth.hfp.impl.cpp",73 "src/ohos.bluetooth.hfp.impl.cpp",
73 "src/taihe_bluetooth_hfp_ag_observer.cpp",74 "src/taihe_bluetooth_hfp_ag_observer.cpp",
75+ "src/taihe_bluetooth_hfp_hf_observer.cpp",
74 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp",76 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp",
75 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp",77 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp",
76 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp"78 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp"
@@ -38,4 +38,23 @@ interface HandsFreeAudioGatewayProfile : BaseProfile {
38 Disconnect(deviceId: String): void;38 Disconnect(deviceId: String): void;
39}39}
40 40 
41-function CreateHfpAgProfile(): HandsFreeAudioGatewayProfile;41+function CreateHfpAgProfile(): HandsFreeAudioGatewayProfile;
42+ 
43+interface HandsFreeHfProfile : BaseProfile {
44+ @!sts_inject_into_class("""on(type: string, callback: object): void {
45+ if (type === "connectionStateChange") {
46+ this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void);
47+ }
48+ }
49+ """)
50+ 
51+ @!sts_inject_into_class("""off(type: string, callback?: object): void {
52+ if (type === "connectionStateChange") {
53+ this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined);
54+ }
55+ }
56+ """)
57+ Connect(deviceId: String): void;
58+ Disconnect(deviceId: String): void;
59+}
60+function CreateHfpHfProfile(): HandsFreeHfProfile;
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright (C) 2025 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+#ifndef TAIHE_BLUETOOTH_HFP_HF_OBSERVER_H_
17+#define TAIHE_BLUETOOTH_HFP_HF_OBSERVER_H_
18+ 
19+#include <shared_mutex>
20+#include "bluetooth_hfp_hf.h"
21+#include "ohos.bluetooth.hfp.proj.hpp"
22+#include "ohos.bluetooth.hfp.impl.hpp"
23+#include "taihe/runtime.hpp"
24+#include "stdexcept"
25+#include "taihe_event_module.h"
26+ 
27+namespace OHOS {
28+namespace Bluetooth {
29+ 
30+class TaiheHandsFreeUnitObserver : public HandsFreeUnitObserver {
31+public:
32+ void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state, int cause) override;
33+ void OnScoStateChanged(const BluetoothRemoteDevice &device, int state) override;
34+ 
35+ TaiheHandsFreeUnitObserver();
36+ ~TaiheHandsFreeUnitObserver() override = default;
37+ 
38+private:
39+ friend class HandsFreeHfProfileImpl;
40+ EventModule<void(::ohos::bluetooth::baseProfile::StateChangeParam const& data)> eventSubscribe_;
41+};
42+} // namespace Bluetooth
43+} // namespace OHOS
44+#endif /* TAIHE_BLUETOOTH_HFP_HF_OBSERVER_H_ */
@@ -23,8 +23,10 @@
23#include "stdexcept"23#include "stdexcept"
24#include "bluetooth_errorcode.h"24#include "bluetooth_errorcode.h"
25#include "bluetooth_hfp_ag.h"25#include "bluetooth_hfp_ag.h"
26+#include "bluetooth_hfp_hf.h"
26#include "bluetooth_log.h"27#include "bluetooth_log.h"
27#include "taihe_bluetooth_hfp_ag_observer.h"28#include "taihe_bluetooth_hfp_ag_observer.h"
29+#include "taihe_bluetooth_hfp_hf_observer.h"
28#include "taihe_bluetooth_utils.h"30#include "taihe_bluetooth_utils.h"
29 31 
30namespace OHOS {32namespace OHOS {
@@ -165,10 +167,143 @@ private:
165{167{
166 return taihe::make_holder<HandsFreeAudioGatewayProfileImpl, ohos::bluetooth::hfp::HandsFreeAudioGatewayProfile>();168 return taihe::make_holder<HandsFreeAudioGatewayProfileImpl, ohos::bluetooth::hfp::HandsFreeAudioGatewayProfile>();
167}169}
170+ 
171+class HandsFreeHfProfileImpl {
172+public:
173+ HandsFreeHfProfileImpl()
174+ {
175+ observer_ = std::make_shared<TaiheHandsFreeUnitObserver>();
176+ }
177+ 
178+ void OnConnectionStateChange(::taihe::callback_view<void(
179+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)> callback)
180+ {
181+ if (observer_) {
182+ observer_->eventSubscribe_.RegisterEvent(callback);
183+ }
184+ if (!isRegistered_) {
185+ HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
186+ profile->RegisterObserver(observer_);
187+ isRegistered_ = true;
188+ }
189+ }
190+ 
191+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
192+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>> callback)
193+ {
194+ if (observer_) {
195+ observer_->eventSubscribe_.DeregisterEvent(callback);
196+ }
197+ }
198+ 
199+ void Connect(taihe::string_view deviceId)
200+ {
201+ HILOGI("enter");
202+ std::string remoteAddr = std::string(deviceId);
203+ bool checkRet = CheckDeviceIdParam(remoteAddr);
204+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
205+ 
206+ HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
207+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
208+ int32_t errorCode = profile->Connect(device);
209+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
210+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
211+ }
212+ 
213+ void Disconnect(taihe::string_view deviceId)
214+ {
215+ HILOGI("enter");
216+ std::string remoteAddr = std::string(deviceId);
217+ bool checkRet = CheckDeviceIdParam(remoteAddr);
218+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
219+ 
220+ HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
221+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
222+ int32_t errorCode = profile->Disconnect(device);
223+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
224+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
225+ }
226+ 
227+ ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(taihe::string_view deviceId)
228+ {
229+ HILOGD("enter");
230+ std::string remoteAddr = std::string(deviceId);
231+ bool checkRet = CheckDeviceIdParam(remoteAddr);
232+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
233+ ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
234+ 
235+ HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
236+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
237+ int32_t state = profile->GetDeviceState(device);
238+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
239+ return ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
240+ }
241+ 
242+ taihe::array<taihe::string> GetConnectedDevices()
243+ {
244+ HILOGI("enter");
245+ HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
246+ std::vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };
247+ std::vector<BluetoothRemoteDevice> devices = profile->GetDevicesByStates(states);
248+ 
249+ std::vector<std::string> deviceVector;
250+ for (auto &device : devices) {
251+ deviceVector.push_back(device.GetDeviceAddr());
252+ }
253+ 
254+ return deviceVector.empty() ? taihe::array<taihe::string>{}
255+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
256+ }
257+ 
258+ ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(taihe::string_view deviceId)
259+ {
260+ HILOGD("start");
261+ std::string remoteAddr = std::string(deviceId);
262+ bool checkRet = CheckDeviceIdParam(remoteAddr);
263+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
264+ ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
265+ 
266+ int strategy = 0;
267+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
268+ HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
269+ int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);
270+ HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);
271+ TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err,
272+ ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
273+ 
274+ return ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
275+ }
276+ 
277+ void SetConnectionStrategySync(taihe::string_view deviceId,
278+ ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
279+ {
280+ HILOGD("start");
281+ std::string remoteAddr = std::string(deviceId);
282+ int32_t connStrategy = strategy.get_value();
283+ bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
284+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
285+ 
286+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
287+ HandsFreeUnit *profile = HandsFreeUnit::GetProfile();
288+ int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);
289+ HILOGI("err: %{public}d", err);
290+ TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);
291+ }
292+ 
293+private:
294+ std::shared_ptr<TaiheHandsFreeUnitObserver> observer_ = nullptr;
295+ bool isRegistered_ = false;
296+};
297+ 
298+::ohos::bluetooth::hfp::HandsFreeHfProfile CreateHfpHfProfile()
299+{
300+ return taihe::make_holder<HandsFreeHfProfileImpl, ohos::bluetooth::hfp::HandsFreeHfProfile>();
301+}
168} // namespace Bluetooth302} // namespace Bluetooth
169} // namespace OHOS303} // namespace OHOS
170 304 
171// Since these macros are auto-generate, lint will cause false positive.305// Since these macros are auto-generate, lint will cause false positive.
172// NOLINTBEGIN306// NOLINTBEGIN
173TH_EXPORT_CPP_API_CreateHfpAgProfile(OHOS::Bluetooth::CreateHfpAgProfile);307TH_EXPORT_CPP_API_CreateHfpAgProfile(OHOS::Bluetooth::CreateHfpAgProfile);
308+TH_EXPORT_CPP_API_CreateHfpHfProfile(OHOS::Bluetooth::CreateHfpHfProfile);
174// NOLINTEND309// NOLINTEND
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2025 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+#ifndef LOG_TAG
17+#define LOG_TAG "bt_taihe_hfp_hf_observer"
18+#endif
19+ 
20+#include "ohos.bluetooth.hfp.proj.hpp"
21+#include "ohos.bluetooth.hfp.impl.hpp"
22+#include "bluetooth_utils.h"
23+#include "bluetooth_log.h"
24+#include "taihe_bluetooth_hfp_hf_observer.h"
25+#include "taihe/runtime.hpp"
26+#include "taihe_event_module.h"
27+#include "stdexcept"
28+ 
29+namespace OHOS {
30+namespace Bluetooth {
31+ 
32+TaiheHandsFreeUnitObserver::TaiheHandsFreeUnitObserver()
33+{}
34+ 
35+void TaiheHandsFreeUnitObserver::OnConnectionStateChanged(const BluetoothRemoteDevice &device,
36+ int state, int cause)
37+{
38+ std::shared_lock<std::shared_mutex> guard(eventSubscribe_.lock_);
39+ HILOGD("enter, remote device address: %{public}s, state: %{public}d, cause: %{public}d",
40+ GET_ENCRYPT_ADDR(device), state, cause);
41+ ::taihe::string deviceId_(device.GetDeviceAddr());
42+ int32_t profileConnectionState = TaiheUtils::GetProfileConnectionState(state);
43+ auto state_ = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState);
44+ auto cause_ = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(cause);
45+ auto taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam {
46+ .deviceId = deviceId_,
47+ .state = state_,
48+ .cause = cause_,
49+ };
50+ for (auto callback : eventSubscribe_.callbackVec_) {
51+ if (callback) {
52+ (*callback)(taiheResult);
53+ }
54+ }
55+}
56+ 
57+void TaiheHandsFreeUnitObserver::OnScoStateChanged(const BluetoothRemoteDevice &device, int state)
58+{
59+ HILOGD("address: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state);
60+}
61+ 
62+} // namespace Bluetooth
63+} // namespace OHOS
@@ -64,6 +64,8 @@ taihe_shared_library("bluetoothHid_taihe_native") {
64 "include",64 "include",
65 "src",65 "src",
66 "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include",66 "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include",
67+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/parcel",
68+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/common",
67 "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include",69 "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include",
68 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common"70 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common"
69 ]71 ]
@@ -71,6 +73,10 @@ taihe_shared_library("bluetoothHid_taihe_native") {
71 "src/ani_constructor.cpp",73 "src/ani_constructor.cpp",
72 "src/ohos.bluetooth.hid.impl.cpp",74 "src/ohos.bluetooth.hid.impl.cpp",
73 "src/taihe_bluetooth_hid_host_observer.cpp",75 "src/taihe_bluetooth_hid_host_observer.cpp",
76+ "src/taihe_bluetooth_hid_device_observer.cpp",
77+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/parcel/bluetooth_hid_device_sdp_parcel.cpp",
78+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/parcel/bluetooth_hid_device_qos_parcel.cpp",
79+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/common/hid_device_utils.cpp",
74 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp",80 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp",
75 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp",81 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp",
76 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp"82 "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp"
@@ -19,6 +19,7 @@ static { loadLibraryWithPermissionCheck("bluetoothHid_taihe_native.z", "@ohos.bl
19""")19""")
20 20 
21from ohos.bluetooth.baseProfile use BaseProfile;21from ohos.bluetooth.baseProfile use BaseProfile;
22+from ohos.bluetooth.common use BluetoothAddress;
22@!sts_inject_into_module("import {baseProfile} from './@ohos.bluetooth.baseProfile';")23@!sts_inject_into_module("import {baseProfile} from './@ohos.bluetooth.baseProfile';")
23interface HidHostProfile : BaseProfile {24interface HidHostProfile : BaseProfile {
24 @!sts_inject_into_class("""on(type: string, callback: object): void {25 @!sts_inject_into_class("""on(type: string, callback: object): void {
@@ -37,4 +38,119 @@ interface HidHostProfile : BaseProfile {
37 Connect(deviceId: String): void;38 Connect(deviceId: String): void;
38 Disconnect(deviceId: String): void;39 Disconnect(deviceId: String): void;
39}40}
40-function CreateHidHostProfile(): HidHostProfile;41+function CreateHidHostProfile(): HidHostProfile;
42+ 
43+union UndefinedType {
44+ @undefined undefined;
45+}
46+ 
47+interface HidDeviceProfile : BaseProfile {
48+ @!sts_inject_into_class("""on(type: string, callback: object): void {
49+ if (type === "connectionStateChange") {
50+ this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void);
51+ }
52+ }
53+ """)
54+ 
55+ @!sts_inject_into_class("""off(type: string, callback?: object): void {
56+ if (type === "connectionStateChange") {
57+ this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined);
58+ }
59+ }
60+ """)
61+ Connect(deviceId: BluetoothAddress): void;
62+ Disconnect(): void;
63+ ReportError(error: ErrorReason): void;
64+ UnregisterHidDevice(): void;
65+ SendReport(id: i32, reportData: @arraybuffer Array<u8>): void;
66+ ReplyReport(type: ReportType, id: i32, reportData: @arraybuffer Array<u8>): void;
67+ OnSetProtocol(callback: (data: ProtocolData) => void): void;
68+ OffSetProtocol(callback: Optional<(data: ProtocolData) => void>): void;
69+ OnInterruptDataReceived(callback: (data: InterruptData) => void): void;
70+ OffInterruptDataReceived(callback: Optional<(data: InterruptData) => void>): void;
71+ RegisterHidDevice(sdp: HidDeviceSdp, inQos: HidDeviceQos, outQos: HidDeviceQos, callback:(data:bool)=>void): void;
72+ OnSetReport(callback: (data: SetReportData) => void): void;
73+ OffSetReport(callback: Optional<(data: SetReportData) => void>): void;
74+ OnGetReport(callback: (data: GetReportData) => void): void;
75+ OffGetReport(callback: Optional<(data: GetReportData) => void>): void;
76+ OnVirtualCableUnplug(callback:(data: UndefinedType) => void): void;
77+ OffVirtualCableUnplug(callback: Optional<(data: UndefinedType) => void>): void;
78+}
79+function CreateHidDeviceProfile(): HidDeviceProfile;
80+ 
81+enum ErrorReason: i32 {
82+ RSP_SUCCESS = 0,
83+ RSP_NOT_READY = 1,
84+ RSP_INVALID_REPORT_ID = 2,
85+ RSP_UNSUPPORTED_REQ = 3,
86+ RSP_INVALID_PARAM = 4,
87+ RSP_UNKNOWN = 14
88+}
89+ 
90+struct ProtocolData {
91+ protocol: ProtocolType;
92+}
93+ 
94+enum ProtocolType: i32 {
95+ PROTOCOL_BOOT_MODE = 0,
96+ PROTOCOL_REPORT_MODE = 1
97+}
98+ 
99+struct InterruptData {
100+ id: i32;
101+ data: @arraybuffer Array<u8>;
102+}
103+ 
104+struct HidDeviceSdp {
105+ name: String;
106+ description: String;
107+ provider: String;
108+ subclass: Subclass;
109+ descriptors: @arraybuffer Array<u8>;
110+}
111+ 
112+enum Subclass: i32 {
113+ SUBCLASS_UNCATEGORIZED = 0,
114+ SUBCLASS_JOYSTICK = 1,
115+ SUBCLASS_GAMEPAD = 2,
116+ SUBCLASS_REMOTE_CONTROL = 3,
117+ SUBCLASS_SENSING_DEVICE = 4,
118+ SUBCLASS_DIGITIZER_TABLET = 5,
119+ SUBCLASS_CARD_READER = 6,
120+ SUBCLASS_KEYBOARD = 64,
121+ SUBCLASS_MOUSE = 128,
122+ SUBCLASS_COMBO = 192
123+}
124+ 
125+struct HidDeviceQos {
126+ serviceType: Optional<ServiceType>;
127+ tokenRate: Optional<i32>;
128+ tokenBucketSize: Optional<i32>;
129+ peakBandwidth: Optional<i32>;
130+ latency: Optional<i32>;
131+ delayVariation: Optional<i32>;
132+}
133+ 
134+enum ServiceType: i32 {
135+ SERVICE_NO_TRAFFIC = 0,
136+ SERVICE_BEST_EFFORT = 1,
137+ SERVICE_GUARANTEED = 2
138+}
139+ 
140+struct SetReportData {
141+ type: ReportType;
142+ id: i32;
143+ data: @arraybuffer Array<u8>;
144+}
145+ 
146+struct GetReportData {
147+ type: ReportType;
148+ id: i32;
149+ bufferSize: i32;
150+}
151+ 
152+enum ReportType: i32 {
153+ REPORT_TYPE_INPUT = 1,
154+ REPORT_TYPE_OUTPUT = 2,
155+ REPORT_TYPE_FEATURE = 3
156+}
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (C) 2025 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+#ifndef TAIHE_BLUETOOTH_HID_DEVICE_OBSERVER_H_
17+#define TAIHE_BLUETOOTH_HID_DEVICE_OBSERVER_H_
18+ 
19+#include <string>
20+#include <vector>
21+#include "bluetooth_hid_device.h"
22+#include "ohos.bluetooth.hid.proj.hpp"
23+#include "ohos.bluetooth.hid.impl.hpp"
24+#include "taihe/runtime.hpp"
25+#include "stdexcept"
26+#include "taihe_event_subscribe_module.h"
27+ 
28+namespace OHOS {
29+namespace Bluetooth {
30+const char * const STR_BT_HID_DEVICE_OBSERVER_APP_STATUS_CHANGE = "appStatusChange";
31+const char * const STR_BT_HID_DEVICE_CONNECT_STATE_CHANGE = "connectionStateChange";
32+const char * const STR_BT_HID_DEVICE_OBSERVER_APP_GET_REPORT = "getReport";
33+const char * const STR_BT_HID_DEVICE_OBSERVER_APP_SET_REPORT = "setReport";
34+const char * const STR_BT_HID_DEVICE_OBSERVER_INTERRUPT_DATA_RECEIVED = "interruptDataReceived";
35+const char * const STR_BT_HID_DEVICE_OBSERVER_SET_PROTOCOL = "setProtocol";
36+const char * const STR_BT_HID_DEVICE_OBSERVER_VIRTUAL_CABLE_UNPLUG = "virtualCableUnplug";
37+ 
38+class TaiheBluetoothHidDeviceObserver : public HidDeviceObserver {
39+public:
40+ void OnAppStatusChanged(int state) override;
41+ void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state) override;
42+ void OnGetReport(int type, int id, uint16_t bufferSize) override;
43+ void OnSetProtocol(int protocol) override;
44+ void OnInterruptDataReceived(int id, const std::vector<uint8_t> &data) override;
45+ void OnSetReport(int type, int id, const std::vector<uint8_t> &data) override;
46+ void OnVirtualCableUnplug() override;
47+ 
48+ TaiheBluetoothHidDeviceObserver();
49+ ~TaiheBluetoothHidDeviceObserver() override = default;
50+ 
51+ TaiheEventSubscribeModule eventSubscribe_;
52+};
53+} // namespace Bluetooth
54+} // namespace OHOS
55+#endif /* TAIHE_BLUETOOTH_HID_DEVICE_OBSERVER_H_ */
@@ -23,9 +23,13 @@
23#include "stdexcept"23#include "stdexcept"
24#include "bluetooth_errorcode.h"24#include "bluetooth_errorcode.h"
25#include "bluetooth_hid_host.h"25#include "bluetooth_hid_host.h"
26+#include "bluetooth_hid_device.h"
27+#include "bluetooth_address_info.h"
26#include "bluetooth_log.h"28#include "bluetooth_log.h"
27#include "taihe_bluetooth_hid_host_observer.h"29#include "taihe_bluetooth_hid_host_observer.h"
30+#include "taihe_bluetooth_hid_device_observer.h"
28#include "taihe_bluetooth_utils.h"31#include "taihe_bluetooth_utils.h"
32+#include "hid_device_utils.h"
29 33 
30namespace OHOS {34namespace OHOS {
31namespace Bluetooth {35namespace Bluetooth {
@@ -57,36 +61,44 @@ public:
57 void Connect(taihe::string_view deviceId)61 void Connect(taihe::string_view deviceId)
58 {62 {
59 HILOGI("enter");63 HILOGI("enter");
64+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_SERVICE_DISCONNECTED,
65+ BT_ERR_INVALID_STATE, BT_ERR_PROFILE_DISABLED, BT_ERR_INTERNAL_ERROR };
66+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
60 std::string remoteAddr = std::string(deviceId);67 std::string remoteAddr = std::string(deviceId);
61 bool checkRet = CheckDeviceIdParam(remoteAddr);68 bool checkRet = CheckDeviceIdParam(remoteAddr);
62- TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);69+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
63 70 
64 HidHost *profile = HidHost::GetProfile();71 HidHost *profile = HidHost::GetProfile();
65 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);72 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
66 int32_t errorCode = profile->Connect(device);73 int32_t errorCode = profile->Connect(device);
67 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());74 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
68- TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);75+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
69 }76 }
70 77 
71 void Disconnect(taihe::string_view deviceId)78 void Disconnect(taihe::string_view deviceId)
72 {79 {
73 HILOGI("Disconnect called");80 HILOGI("Disconnect called");
81+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_SERVICE_DISCONNECTED,
82+ BT_ERR_INVALID_STATE, BT_ERR_PROFILE_DISABLED, BT_ERR_INTERNAL_ERROR };
83+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
74 std::string remoteAddr = std::string(deviceId);84 std::string remoteAddr = std::string(deviceId);
75 bool checkRet = CheckDeviceIdParam(remoteAddr);85 bool checkRet = CheckDeviceIdParam(remoteAddr);
76- TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);86+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
77 87 
78 HidHost *profile = HidHost::GetProfile();88 HidHost *profile = HidHost::GetProfile();
79 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);89 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
80 int32_t errorCode = profile->Disconnect(device);90 int32_t errorCode = profile->Disconnect(device);
81 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());91 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
82- TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);92+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
83 }93 }
84 94 
85 ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(taihe::string_view deviceId)95 ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(taihe::string_view deviceId)
86 {96 {
97+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
98+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
87 std::string remoteAddr = std::string(deviceId);99 std::string remoteAddr = std::string(deviceId);
88 bool checkRet = CheckDeviceIdParam(remoteAddr);100 bool checkRet = CheckDeviceIdParam(remoteAddr);
89- TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,101+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
90 ohos::bluetooth::constant::ProfileConnectionState::from_value(0));102 ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
91 103 
92 HidHost *profile = HidHost::GetProfile();104 HidHost *profile = HidHost::GetProfile();
@@ -94,7 +106,7 @@ public:
94 int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);106 int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
95 int32_t errorCode = profile->GetDeviceState(device, state);107 int32_t errorCode = profile->GetDeviceState(device, state);
96 int32_t profileState = TaiheUtils::GetProfileConnectionState(state);108 int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
97- TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,109+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode,
98 ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));110 ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
99 111 
100 return ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);112 return ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
@@ -103,12 +115,14 @@ public:
103 taihe::array<taihe::string> GetConnectedDevices()115 taihe::array<taihe::string> GetConnectedDevices()
104 {116 {
105 HILOGI("enter");117 HILOGI("enter");
118+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
119+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
106 HidHost *profile = HidHost::GetProfile();120 HidHost *profile = HidHost::GetProfile();
107 std::vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };121 std::vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };
108 std::vector<BluetoothRemoteDevice> devices;122 std::vector<BluetoothRemoteDevice> devices;
109 int errorCode = profile->GetDevicesByStates(states, devices);123 int errorCode = profile->GetDevicesByStates(states, devices);
110 HILOGI("errorCode:%{public}s, devices size:%{public}zu", GetTaiheErrMsg(errorCode).c_str(), devices.size());124 HILOGI("errorCode:%{public}s, devices size:%{public}zu", GetTaiheErrMsg(errorCode).c_str(), devices.size());
111- TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, taihe::array<taihe::string>{});125+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode, taihe::array<taihe::string>{});
112 126 
113 std::vector<std::string> deviceVector;127 std::vector<std::string> deviceVector;
114 for (auto &device: devices) {128 for (auto &device: devices) {
@@ -122,9 +136,11 @@ public:
122 ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(taihe::string_view deviceId)136 ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(taihe::string_view deviceId)
123 {137 {
124 HILOGD("start");138 HILOGD("start");
139+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
140+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
125 std::string remoteAddr = std::string(deviceId);141 std::string remoteAddr = std::string(deviceId);
126 bool checkRet = CheckDeviceIdParam(remoteAddr);142 bool checkRet = CheckDeviceIdParam(remoteAddr);
127- TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,143+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
128 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));144 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
129 145 
130 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);146 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
@@ -132,7 +148,7 @@ public:
132 int strategy = 0;148 int strategy = 0;
133 int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);149 int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);
134 HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);150 HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);
135- TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err,151+ TAIHE_BT_ASSERT_RETURN_VERIFY(err == BT_NO_ERROR, err,
136 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));152 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
137 153 
138 return ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);154 return ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
@@ -142,16 +158,18 @@ public:
142 ohos::bluetooth::baseProfile::ConnectionStrategy strategy)158 ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
143 {159 {
144 HILOGD("start");160 HILOGD("start");
161+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
162+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
145 std::string remoteAddr = std::string(deviceId);163 std::string remoteAddr = std::string(deviceId);
146 int32_t connStrategy = strategy.get_value();164 int32_t connStrategy = strategy.get_value();
147 bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);165 bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
148- TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);166+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
149 167 
150 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);168 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
151 HidHost *profile = HidHost::GetProfile();169 HidHost *profile = HidHost::GetProfile();
152 int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);170 int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);
153 HILOGI("err: %{public}d", err);171 HILOGI("err: %{public}d", err);
154- TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);172+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(err == BT_NO_ERROR, err);
155 }173 }
156private:174private:
157 std::shared_ptr<TaiheBluetoothHidHostObserver> observer_ = nullptr;175 std::shared_ptr<TaiheBluetoothHidHostObserver> observer_ = nullptr;
@@ -163,10 +181,380 @@ private:
163 // as the parameters in the constructor of the actual implementation class.181 // as the parameters in the constructor of the actual implementation class.
164 return taihe::make_holder<HidHostProfileImpl, ::ohos::bluetooth::hid::HidHostProfile>();182 return taihe::make_holder<HidHostProfileImpl, ::ohos::bluetooth::hid::HidHostProfile>();
165}183}
184+ 
185+class HidDeviceProfileImpl {
186+public:
187+ HidDeviceProfileImpl()
188+ {
189+ observer_ = std::make_shared<TaiheBluetoothHidDeviceObserver>();
190+ HidDevice *profile = HidDevice::GetProfile();
191+ profile->RegisterObserver(observer_);
192+ }
193+ 
194+ void OnConnectionStateChange(::taihe::callback_view<void(
195+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)> callback)
196+ {
197+ if (observer_) {
198+ observer_->eventSubscribe_.RegisterEvent<void(
199+ ::ohos::bluetooth::baseProfile::StateChangeParam const&)>(
200+ STR_BT_HID_DEVICE_CONNECT_STATE_CHANGE, callback);
201+ }
202+ }
203+ 
204+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
205+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>> callback)
206+ {
207+ if (observer_) {
208+ observer_->eventSubscribe_.DeregisterEvent<void(
209+ ::ohos::bluetooth::baseProfile::StateChangeParam const&)>(
210+ STR_BT_HID_DEVICE_CONNECT_STATE_CHANGE, callback);
211+ }
212+ }
213+ 
214+ void OnSetProtocol(::taihe::callback_view<void(
215+ ::ohos::bluetooth::hid::ProtocolData const& data)> callback)
216+ {
217+ if (observer_) {
218+ observer_->eventSubscribe_.RegisterEvent<void(
219+ ::ohos::bluetooth::hid::ProtocolData const&)>(
220+ STR_BT_HID_DEVICE_OBSERVER_SET_PROTOCOL, callback);
221+ }
222+ }
223+ 
224+ void OffSetProtocol(::taihe::optional_view<::taihe::callback<void(
225+ ::ohos::bluetooth::hid::ProtocolData const& data)>> callback)
226+ {
227+ if (observer_) {
228+ observer_->eventSubscribe_.DeregisterEvent<void(
229+ ::ohos::bluetooth::hid::ProtocolData const&)>(
230+ STR_BT_HID_DEVICE_OBSERVER_SET_PROTOCOL, callback);
231+ }
232+ }
233+ 
234+ void OnInterruptDataReceived(::taihe::callback_view<void(
235+ ::ohos::bluetooth::hid::InterruptData const& data)> callback)
236+ {
237+ if (observer_) {
238+ observer_->eventSubscribe_.RegisterEvent<void(
239+ ::ohos::bluetooth::hid::InterruptData const&)>(
240+ STR_BT_HID_DEVICE_OBSERVER_INTERRUPT_DATA_RECEIVED, callback);
241+ }
242+ }
243+ 
244+ void OffInterruptDataReceived(::taihe::optional_view<::taihe::callback<void(
245+ ::ohos::bluetooth::hid::InterruptData const& data)>> callback)
246+ {
247+ if (observer_) {
248+ observer_->eventSubscribe_.DeregisterEvent<void(
249+ ::ohos::bluetooth::hid::InterruptData const&)>(
250+ STR_BT_HID_DEVICE_OBSERVER_INTERRUPT_DATA_RECEIVED, callback);
251+ }
252+ }
253+ 
254+ void OnSetReport(::taihe::callback_view<void(
255+ ::ohos::bluetooth::hid::SetReportData const& data)> callback)
256+ {
257+ if (observer_) {
258+ observer_->eventSubscribe_.RegisterEvent<void(
259+ ::ohos::bluetooth::hid::SetReportData const&)>(
260+ STR_BT_HID_DEVICE_OBSERVER_APP_SET_REPORT, callback);
261+ }
262+ }
263+ 
264+ void OffSetReport(::taihe::optional_view<::taihe::callback<void(
265+ ::ohos::bluetooth::hid::SetReportData const& data)>> callback)
266+ {
267+ if (observer_) {
268+ observer_->eventSubscribe_.DeregisterEvent<void(
269+ ::ohos::bluetooth::hid::SetReportData const&)>(
270+ STR_BT_HID_DEVICE_OBSERVER_APP_SET_REPORT, callback);
271+ }
272+ }
273+ 
274+ void OnGetReport(::taihe::callback_view<void(
275+ ::ohos::bluetooth::hid::GetReportData const& data)> callback)
276+ {
277+ if (observer_) {
278+ observer_->eventSubscribe_.RegisterEvent<void(
279+ ::ohos::bluetooth::hid::GetReportData const&)>(
280+ STR_BT_HID_DEVICE_OBSERVER_APP_GET_REPORT, callback);
281+ }
282+ }
283+ 
284+ void OffGetReport(::taihe::optional_view<::taihe::callback<void(
285+ ::ohos::bluetooth::hid::GetReportData const& data)>> callback)
286+ {
287+ if (observer_) {
288+ observer_->eventSubscribe_.DeregisterEvent<void(
289+ ::ohos::bluetooth::hid::GetReportData const&)>(
290+ STR_BT_HID_DEVICE_OBSERVER_APP_GET_REPORT, callback);
291+ }
292+ }
293+ 
294+ void OnVirtualCableUnplug(::taihe::callback_view<void(::ohos::bluetooth::hid::UndefinedType const& data)> callback)
295+ {
296+ if (observer_) {
297+ observer_->eventSubscribe_.RegisterEvent<void(
298+ ::ohos::bluetooth::hid::UndefinedType const&)>(
299+ STR_BT_HID_DEVICE_OBSERVER_VIRTUAL_CABLE_UNPLUG, callback);
300+ }
301+ }
302+ 
303+ void OffVirtualCableUnplug(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::hid::UndefinedType const& data)>> callback)
304+ {
305+ if (observer_) {
306+ observer_->eventSubscribe_.DeregisterEvent<void(
307+ ::ohos::bluetooth::hid::UndefinedType const&)>(
308+ STR_BT_HID_DEVICE_OBSERVER_VIRTUAL_CABLE_UNPLUG, callback);
309+ }
310+ }
311+ 
312+ void Connect(::ohos::bluetooth::common::BluetoothAddress const& deviceId)
313+ {
314+ HILOGI("enter");
315+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
316+ BT_ERR_PROFILE_DISABLED, BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER };
317+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
318+ AddressInfo addressInfo;
319+ addressInfo.SetAddress(std::string(deviceId.address));
320+ addressInfo.SetAddressType(static_cast<uint8_t>(deviceId.addressType.get_key()));
321+ if (deviceId.rawAddressType.has_value()) {
322+ addressInfo.SetRawAddressType(static_cast<uint8_t>(deviceId.rawAddressType.value().get_key()));
323+ }
324+ HidDevice *profile = HidDevice::GetProfile();
325+ int32_t errorCode = profile->Connect(addressInfo);
326+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
327+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
328+ }
329+ 
330+ void Disconnect()
331+ {
332+ HILOGI("enter");
333+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
334+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER };
335+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
336+ HidDevice *profile = HidDevice::GetProfile();
337+ int32_t errorCode = profile->Disconnect();
338+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
339+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
340+ }
341+ 
342+ void ReportError(::ohos::bluetooth::hid::ErrorReason error)
343+ {
344+ HILOGI("enter");
345+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
346+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER, BT_ERR_HID_DEVICE_NOT_CONNECTED };
347+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
348+ HidDevice *profile = HidDevice::GetProfile();
349+ int32_t errorCode = profile->ReportError(static_cast<ErrorReason>(error.get_value()));
350+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
351+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
352+ }
353+ 
354+ void UnregisterHidDevice()
355+ {
356+ HILOGI("enter");
357+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
358+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER };
359+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
360+ if (observer_) {
361+ observer_->eventSubscribe_.DeregisterAllCallback(
362+ STR_BT_HID_DEVICE_OBSERVER_APP_STATUS_CHANGE);
363+ }
364+ HidDevice *profile = HidDevice::GetProfile();
365+ int32_t errorCode = profile->UnregisterHidDevice();
366+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
367+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
368+ }
369+ 
370+ void SendReport(int32_t id, ::taihe::array_view<uint8_t> reportData)
371+ {
372+ HILOGI("enter");
373+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
374+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER, BT_ERR_HID_DEVICE_NOT_CONNECTED };
375+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
376+ std::vector<uint8_t> data;
377+ if (reportData.size() > 0) {
378+ data.assign(reportData.data(), reportData.data() + reportData.size());
379+ }
380+ HidDevice *profile = HidDevice::GetProfile();
381+ int32_t errorCode = profile->SendReport(id, data);
382+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
383+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
384+ }
385+ 
386+ void ReplyReport(::ohos::bluetooth::hid::ReportType type, int32_t id, ::taihe::array_view<uint8_t> reportData)
387+ {
388+ HILOGI("enter");
389+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
390+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER, BT_ERR_HID_DEVICE_NOT_CONNECTED };
391+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
392+ std::vector<uint8_t> data;
393+ if (reportData.size() > 0) {
394+ data.assign(reportData.data(), reportData.data() + reportData.size());
395+ }
396+ HidDevice *profile = HidDevice::GetProfile();
397+ int32_t errorCode = profile->ReplyReport(static_cast<ReportType>(type.get_value()), id, data);
398+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
399+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
400+ }
401+ 
402+ void RegisterHidDevice(::ohos::bluetooth::hid::HidDeviceSdp const& sdp,
403+ ::ohos::bluetooth::hid::HidDeviceQos const& inQos,
404+ ::ohos::bluetooth::hid::HidDeviceQos const& outQos,
405+ ::taihe::callback_view<void(bool data)> callback)
406+ {
407+ HILOGI("enter");
408+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
409+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APPLICATION_NOT_IN_FOREGROUND,
410+ BT_ERR_HID_APP_HAS_BEEN_REGISTERED, BT_ERR_HID_APP_NOT_REGISTER,
411+ BT_ERR_HID_DEVICE_NOT_CONNECTED };
412+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
413+ 
414+ // Validate SDP fields
415+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSDPSettingParam(std::string(sdp.name), MAX_NAME_SIZE),
416+ BT_ERR_INVALID_PARAM);
417+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSDPSettingParam(std::string(sdp.description), MAX_DESCRIPTION_SIZE),
418+ BT_ERR_INVALID_PARAM);
419+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSDPSettingParam(std::string(sdp.provider), MAX_PROVIDER_SIZE),
420+ BT_ERR_INVALID_PARAM);
421+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSubclass(sdp.subclass.get_value()),
422+ BT_ERR_INVALID_PARAM);
423+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(sdp.descriptors.size() > 0 && sdp.descriptors.size() <= MAX_DESCRIPTOR_SIZE,
424+ BT_ERR_INVALID_PARAM);
425+ 
426+ // Validate QoS serviceType
427+ if (inQos.serviceType.has_value()) {
428+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidServiceType(inQos.serviceType.value().get_value()),
429+ BT_ERR_INVALID_PARAM);
430+ }
431+ if (outQos.serviceType.has_value()) {
432+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidServiceType(outQos.serviceType.value().get_value()),
433+ BT_ERR_INVALID_PARAM);
434+ }
435+ 
436+ BluetoothHidDeviceSdp sdpSetting(
437+ bluetooth::SdpSetting(std::string(sdp.name), std::string(sdp.description),
438+ std::string(sdp.provider), sdp.subclass.get_value(),
439+ std::vector<uint8_t>(sdp.descriptors.data(), sdp.descriptors.data() + sdp.descriptors.size())));
440+ auto convertQos = [](::ohos::bluetooth::hid::HidDeviceQos const& qos) {
441+ int32_t serviceType = static_cast<int32_t>(ServiceType::SERVICE_BEST_EFFORT);
442+ if (qos.serviceType.has_value()) {
443+ serviceType = static_cast<int32_t>(qos.serviceType.value().get_key());
444+ }
445+ int32_t tokenRate = qos.tokenRate.value_or(0);
446+ int32_t tokenBucketSize = qos.tokenBucketSize.value_or(0);
447+ int32_t peakBandwidth = qos.peakBandwidth.value_or(0);
448+ int32_t latency = qos.latency.value_or(-1);
449+ int32_t delayVariation = qos.delayVariation.value_or(-1);
450+ return BluetoothHidDeviceQos(
451+ bluetooth::QosSetting(serviceType, tokenRate, tokenBucketSize,
452+ peakBandwidth, latency, delayVariation));
453+ };
454+ BluetoothHidDeviceQos inQosSetting = convertQos(inQos);
455+ BluetoothHidDeviceQos outQosSetting = convertQos(outQos);
456+ 
457+ HidDevice *profile = HidDevice::GetProfile();
458+ int32_t errorCode = profile->RegisterHidDevice(sdpSetting, inQosSetting, outQosSetting);
459+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
460+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
461+ if (observer_) {
462+ observer_->eventSubscribe_.RegisterEvent<void(bool)>(
463+ STR_BT_HID_DEVICE_OBSERVER_APP_STATUS_CHANGE, callback);
464+ }
465+ }
466+ 
467+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(::taihe::string_view deviceId)
468+ {
469+ HILOGD("enter");
470+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
471+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
472+ std::string remoteAddr = std::string(deviceId);
473+ bool checkRet = CheckDeviceIdParam(remoteAddr);
474+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
475+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
476+ 
477+ HidDevice *profile = HidDevice::GetProfile();
478+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
479+ int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
480+ int32_t errorCode = profile->GetConnectionState(device, state);
481+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
482+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode,
483+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
484+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
485+ }
486+ 
487+ ::taihe::array<::taihe::string> GetConnectedDevices()
488+ {
489+ HILOGI("enter");
490+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
491+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
492+ HidDevice *profile = HidDevice::GetProfile();
493+ std::vector<BluetoothRemoteDevice> devices;
494+ int errorCode = profile->GetConnectedDevices(devices);
495+ HILOGI("errorCode:%{public}s, devices size:%{public}zu",
496+ GetTaiheErrMsg(errorCode).c_str(), devices.size());
497+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode, taihe::array<taihe::string>{});
498+ 
499+ std::vector<std::string> deviceVector;
500+ for (auto &device : devices) {
501+ deviceVector.push_back(device.GetDeviceAddr());
502+ }
503+ return deviceVector.empty() ? taihe::array<taihe::string>{}
504+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
505+ }
506+ 
507+ ::ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(::taihe::string_view deviceId)
508+ {
509+ HILOGD("start");
510+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
511+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
512+ std::string remoteAddr = std::string(deviceId);
513+ bool checkRet = CheckDeviceIdParam(remoteAddr);
514+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
515+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
516+ 
517+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
518+ HidDevice *profile = HidDevice::GetProfile();
519+ int strategy = 0;
520+ int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);
521+ HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);
522+ TAIHE_BT_ASSERT_RETURN_VERIFY(err == BT_NO_ERROR, err,
523+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
524+ return ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
525+ }
526+ 
527+ void SetConnectionStrategySync(::taihe::string_view deviceId,
528+ ::ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
529+ {
530+ HILOGD("start");
531+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
532+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
533+ std::string remoteAddr = std::string(deviceId);
534+ int32_t connStrategy = strategy.get_value();
535+ bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
536+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
537+ 
538+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
539+ HidDevice *profile = HidDevice::GetProfile();
540+ int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);
541+ HILOGI("err: %{public}d", err);
542+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(err == BT_NO_ERROR, err);
543+ }
544+ 
545+private:
546+ std::shared_ptr<TaiheBluetoothHidDeviceObserver> observer_ = nullptr;
547+};
548+ 
549+::ohos::bluetooth::hid::HidDeviceProfile CreateHidDeviceProfile()
550+{
551+ return taihe::make_holder<HidDeviceProfileImpl, ::ohos::bluetooth::hid::HidDeviceProfile>();
552+}
166} // namespace Bluetooth553} // namespace Bluetooth
167} // namespace OHOS554} // namespace OHOS
168 555 
169// Since these macros are auto-generate, lint will cause false positive.556// Since these macros are auto-generate, lint will cause false positive.
170// NOLINTBEGIN557// NOLINTBEGIN
171TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile);558TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile);
559+TH_EXPORT_CPP_API_CreateHidDeviceProfile(OHOS::Bluetooth::CreateHidDeviceProfile);
172// NOLINTEND560// NOLINTEND
@@ -0,0 +1,129 @@
1+/*
2+ * Copyright (C) 2025 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+#ifndef LOG_TAG
17+#define LOG_TAG "bt_taihe_hid_device_observer"
18+#endif
19+ 
20+#include "ohos.bluetooth.hid.proj.hpp"
21+#include "ohos.bluetooth.hid.impl.hpp"
22+#include "bluetooth_utils.h"
23+#include "bluetooth_log.h"
24+#include "taihe_bluetooth_hid_device_observer.h"
25+#include "taihe/runtime.hpp"
26+#include "stdexcept"
27+ 
28+namespace OHOS {
29+namespace Bluetooth {
30+ 
31+TaiheBluetoothHidDeviceObserver::TaiheBluetoothHidDeviceObserver()
32+ : eventSubscribe_({STR_BT_HID_DEVICE_OBSERVER_APP_STATUS_CHANGE,
33+ STR_BT_HID_DEVICE_CONNECT_STATE_CHANGE,
34+ STR_BT_HID_DEVICE_OBSERVER_APP_GET_REPORT,
35+ STR_BT_HID_DEVICE_OBSERVER_APP_SET_REPORT,
36+ STR_BT_HID_DEVICE_OBSERVER_INTERRUPT_DATA_RECEIVED,
37+ STR_BT_HID_DEVICE_OBSERVER_SET_PROTOCOL,
38+ STR_BT_HID_DEVICE_OBSERVER_VIRTUAL_CABLE_UNPLUG},
39+ "bluetoothHid_taihe")
40+{}
41+ 
42+void TaiheBluetoothHidDeviceObserver::OnAppStatusChanged(int state)
43+{
44+ HILOGI("state: %{public}d", state);
45+ auto &module = eventSubscribe_.GetModule<void(bool)>(STR_BT_HID_DEVICE_OBSERVER_APP_STATUS_CHANGE);
46+ module.PublishEvent(state != 0);
47+ if (state == HID_DEVICE_UNREGISTERED) {
48+ eventSubscribe_.DeregisterAllCallback(STR_BT_HID_DEVICE_OBSERVER_APP_STATUS_CHANGE);
49+ }
50+}
51+ 
52+void TaiheBluetoothHidDeviceObserver::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state)
53+{
54+ HILOGD("enter, remote device address: %{public}s, state: %{public}d",
55+ GET_ENCRYPT_ADDR(device), state);
56+ ::taihe::string deviceId_(device.GetDeviceAddr());
57+ int32_t profileConnectionState = TaiheUtils::GetProfileConnectionState(state);
58+ auto state_ = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState);
59+ auto taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam {
60+ .deviceId = deviceId_,
61+ .state = state_,
62+ .cause = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(0),
63+ };
64+ auto &module = eventSubscribe_.GetModule<void(
65+ ::ohos::bluetooth::baseProfile::StateChangeParam const&)>(STR_BT_HID_DEVICE_CONNECT_STATE_CHANGE);
66+ module.PublishEvent(taiheResult);
67+}
68+ 
69+void TaiheBluetoothHidDeviceObserver::OnGetReport(int type, int id, uint16_t bufferSize)
70+{
71+ HILOGD("type: %{public}d, id: %{public}d, bufferSize: %{public}d", type, id, bufferSize);
72+ auto taiheResult = ::ohos::bluetooth::hid::GetReportData {
73+ .type = ::ohos::bluetooth::hid::ReportType::from_value(type),
74+ .id = id,
75+ .bufferSize = static_cast<int32_t>(bufferSize),
76+ };
77+ auto &module = eventSubscribe_.GetModule<void(
78+ ::ohos::bluetooth::hid::GetReportData const&)>(STR_BT_HID_DEVICE_OBSERVER_APP_GET_REPORT);
79+ module.PublishEvent(taiheResult);
80+}
81+ 
82+void TaiheBluetoothHidDeviceObserver::OnSetProtocol(int protocol)
83+{
84+ HILOGD("protocol: %{public}d", protocol);
85+ auto taiheResult = ::ohos::bluetooth::hid::ProtocolData {
86+ .protocol = ::ohos::bluetooth::hid::ProtocolType::from_value(protocol),
87+ };
88+ auto &module = eventSubscribe_.GetModule<void(
89+ ::ohos::bluetooth::hid::ProtocolData const&)>(STR_BT_HID_DEVICE_OBSERVER_SET_PROTOCOL);
90+ module.PublishEvent(taiheResult);
91+}
92+ 
93+void TaiheBluetoothHidDeviceObserver::OnInterruptDataReceived(int id, const std::vector<uint8_t> &data)
94+{
95+ HILOGD("id: %{public}d, data size: %{public}zu", id, data.size());
96+ auto taiheResult = ::ohos::bluetooth::hid::InterruptData {
97+ .id = id,
98+ .data = data.empty() ? taihe::array<uint8_t>{}
99+ : taihe::array<uint8_t>(taihe::copy_data_t{}, data.data(), data.size()),
100+ };
101+ auto &module = eventSubscribe_.GetModule<void(
102+ ::ohos::bluetooth::hid::InterruptData const&)>(STR_BT_HID_DEVICE_OBSERVER_INTERRUPT_DATA_RECEIVED);
103+ module.PublishEvent(taiheResult);
104+}
105+ 
106+void TaiheBluetoothHidDeviceObserver::OnSetReport(int type, int id, const std::vector<uint8_t> &data)
107+{
108+ HILOGD("type: %{public}d, id: %{public}d, data size: %{public}zu", type, id, data.size());
109+ auto taiheResult = ::ohos::bluetooth::hid::SetReportData {
110+ .type = ::ohos::bluetooth::hid::ReportType::from_value(type),
111+ .id = id,
112+ .data = data.empty() ? taihe::array<uint8_t>{}
113+ : taihe::array<uint8_t>(taihe::copy_data_t{}, data.data(), data.size()),
114+ };
115+ auto &module = eventSubscribe_.GetModule<void(
116+ ::ohos::bluetooth::hid::SetReportData const&)>(STR_BT_HID_DEVICE_OBSERVER_APP_SET_REPORT);
117+ module.PublishEvent(taiheResult);
118+}
119+ 
120+void TaiheBluetoothHidDeviceObserver::OnVirtualCableUnplug()
121+{
122+ HILOGD("enter");
123+ auto &module = eventSubscribe_.GetModule<void(
124+ ::ohos::bluetooth::hid::UndefinedType const&)>(STR_BT_HID_DEVICE_OBSERVER_VIRTUAL_CABLE_UNPLUG);
125+ module.PublishEvent(::ohos::bluetooth::hid::UndefinedType::make_undefined());
126+}
127+ 
128+} // namespace Bluetooth
129+} // namespace OHOS
@@ -0,0 +1,120 @@
1+# Copyright (C) 2025 Huawei Device Co., Ltd.
2+# Licensed under the Apache License, Version 2.0 (the "License");
3+# you may not use this file except in compliance with the License.
4+# You may obtain a copy of the License at
5+#
6+# http://www.apache.org/licenses/LICENSE-2.0
7+#
8+# Unless required by applicable law or agreed to in writing, software
9+# distributed under the License is distributed on an "AS IS" BASIS,
10+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+# See the License for the specific language governing permissions and
12+# limitations under the License.
13+ 
14+import("//build/config/components/ets_frontend/ets2abc_config.gni")
15+import("//build/ohos.gni")
16+import("//build/ohos/taihe_idl/taihe.gni")
17+ 
18+SUBSYSTEM_DIR = "//foundation/communication"
19+ 
20+copy_taihe_idl("bluetooth_map_taihe") {
21+ sources = [
22+ "idl/ohos.bluetooth.map.taihe"
23+ ]
24+ deps = [
25+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_baseProfile:bluetooth_baseProfile_taihe"
26+ ]
27+}
28+ 
29+subsystem_name = "communication"
30+part_name = "bluetooth"
31+taihe_generated_file_path_map = "$taihe_file_path/out/$subsystem_name/$part_name/map"
32+ 
33+ohos_taihe("run_taihe") {
34+ taihe_generated_file_path = "${taihe_generated_file_path_map}"
35+ deps = [ ":bluetooth_map_taihe" ]
36+ outputs = [
37+ "$taihe_generated_file_path/src/ohos.bluetooth.map.ani.cpp",
38+ "$taihe_generated_file_path/src/ohos.bluetooth.map.abi.c",
39+ ]
40+}
41+ 
42+taihe_shared_library("bluetoothMap_taihe_native") {
43+ cflags_cc = [
44+ "-Os",
45+ "-fno-rtti",
46+ "-fno-exceptions",
47+ "-fdata-sections",
48+ "-ffunction-sections",
49+ "-fno-unwind-tables",
50+ "-fno-asynchronous-unwind-tables",
51+ "-fno-merge-all-constants",
52+ "-flto",
53+ ]
54+ ldflags = [
55+ "-Wl,--as-needed",
56+ "-Wl,--gc-sections",
57+ ]
58+ shlib_type = "ani"
59+ taihe_generated_file_path = "${taihe_generated_file_path_map}"
60+ part_name = "$part_name"
61+ subsystem_name = "$subsystem_name"
62+ sources = get_target_outputs(":run_taihe")
63+ include_dirs = [
64+ "include",
65+ "src",
66+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include",
67+ "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include",
68+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common"
69+ ]
70+ sources += [
71+ "src/ohos.bluetooth.map.impl.cpp",
72+ "src/taihe_bluetooth_map_mse_observer.cpp",
73+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp",
74+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp",
75+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp"
76+ ]
77+ deps = [
78+ ":run_taihe",
79+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner:btframework",
80+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_baseProfile:bluetoothBaseProfile_taihe_native"
81+ ]
82+ external_deps = [
83+ "c_utils:utils",
84+ "hilog:libhilog",
85+ "ipc:ipc_single",
86+ ]
87+ sanitize = {
88+ cfi = true # Enable/disable control flow integrity detection
89+ boundary_sanitize = true # Enable boundary san detection
90+ cfi_cross_dso = true # Cross-SO CFI Checks
91+ cfi_vcall_icall_only = true # CFI optimization, restrict CFI detection scope
92+ integer_overflow = true # Enable integer overflow detection
93+ ubsan = true # Enable some Ubsan options
94+ debug = false
95+ }
96+}
97+ 
98+generate_static_abc("bluetoothMap_abc") {
99+ base_url = "${taihe_generated_file_path_map}"
100+ files = [ "${taihe_generated_file_path_map}/@ohos.bluetooth.map.ets" ]
101+ is_boot_abc = "True"
102+ device_dst_file = "/system/framework/bluetoothMap_abc.abc"
103+ dependencies = [ ":run_taihe" ]
104+}
105+ 
106+ohos_prebuilt_etc("bluetoothMap_etc") {
107+ source = "$target_out_dir/bluetoothMap_abc.abc"
108+ module_install_dir = "framework"
109+ part_name = "$part_name"
110+ subsystem_name = "$subsystem_name"
111+ deps = [ ":bluetoothMap_abc" ]
112+}
113+ 
114+group("bluetoothMap_taihe") {
115+ deps = [
116+ ":bluetoothMap_etc",
117+ ":bluetoothMap_taihe_native"
118+ ]
119+ # deps = [":run_taihe"]
120+}