已开启
ble_bluetooth_change_test #1992
ble_bluetooth_change_test #1992
已开启
王乾宇创建于 7月24日
73 个文件变更+6046-15
Mbundle.json+8-1
@@ -102,7 +102,14 @@
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_bas:bluetoothBas_taihe",
108+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_map:bluetoothMap_taihe",
109+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_opp:bluetoothOpp_taihe",
110+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_pan:bluetoothPan_taihe",
111+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_pbap:bluetoothPbap_taihe",
112+ "//foundation/communication/bluetooth/frameworks/ets/taihe/bluetooth_socket:bluetoothSocket_taihe"
106 ],113 ],
107 "service_group": [114 "service_group": [
108 "//foundation/communication/bluetooth/tools/ohos-bluetoothTool:ohos-bluetoothTool",115 "//foundation/communication/bluetooth/tools/ohos-bluetoothTool:ohos-bluetoothTool",
Mframeworks/ets/taihe/bluetooth_a2dp/idl/ohos.bluetooth.a2dp.taihe+15-0
@@ -45,6 +45,8 @@ interface A2dpSourceProfile : BaseProfile {
45 45 
46 Disconnect(deviceId: String): void;46 Disconnect(deviceId: String): void;
47 47 
48+ GetCurrentFullCodecInfo(deviceId: String): Array<CodecInfoList>;
49+ 
48 @promise GetAutoPlayDisabledDuration(deviceId: String): i32;50 @promise GetAutoPlayDisabledDuration(deviceId: String): i32;
49 51 
50 @promise DisableAutoPlay(deviceId: String, duration: i32): void;52 @promise DisableAutoPlay(deviceId: String, duration: i32): void;
@@ -105,6 +107,11 @@ enum PlayingState: i32 {
105 STATE_PLAYING107 STATE_PLAYING
106}108}
107 109 
110+enum CodecFrameLength: i32 {
111+ CODEC_FRAME_LENGTH_5MS = 0,
112+ CODEC_FRAME_LENGTH_10MS = 1
113+}
114+ 
108struct CodecInfo {115struct CodecInfo {
109 codecType: CodecType;116 codecType: CodecType;
110 codecBitsPerSample: CodecBitsPerSample;117 codecBitsPerSample: CodecBitsPerSample;
@@ -112,4 +119,12 @@ struct CodecInfo {
112 codecSampleRate: CodecSampleRate;119 codecSampleRate: CodecSampleRate;
113}120}
114 121 
122+struct CodecInfoList {
123+ codecType: CodecType;
124+ codecBitsPerSampleArray: Array<CodecBitsPerSample>;
125+ codecChannelModeArray: Array<CodecChannelMode>;
126+ codecSampleRateArray: Array<CodecSampleRate>;
127+ codecFrameLengthArray: Array<CodecFrameLength>;
128+}
129+ 
115function CreateA2dpSrcProfile(): A2dpSourceProfile;130function CreateA2dpSrcProfile(): A2dpSourceProfile;
Mframeworks/ets/taihe/bluetooth_a2dp/src/ohos.bluetooth.a2dp.impl.cpp+114-0
@@ -148,6 +148,120 @@ public:
148 TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);148 TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
149 }149 }
150 150 
151+ static taihe::array<ohos::bluetooth::a2dp::CodecBitsPerSample> ConvertCodecBitsPerSampleToTaihe(uint8_t bitsPerSample)
152+ {
153+ std::vector<ohos::bluetooth::a2dp::CodecBitsPerSample> bitsVec;
154+ 
155+ if (bitsPerSample == A2dpUserCodecBitsPerSample::A2DP_SAMPLE_BITS_NONE_USER) {
156+ bitsVec.push_back(ohos::bluetooth::a2dp::CodecBitsPerSample::key_t::CODEC_BITS_PER_SAMPLE_NONE);
157+ }
158+ if (static_cast<uint8_t>(bitsPerSample) & A2dpUserCodecBitsPerSample::A2DP_SAMPLE_BITS_16_USER) {
159+ bitsVec.push_back(ohos::bluetooth::a2dp::CodecBitsPerSample::key_t::CODEC_BITS_PER_SAMPLE_16);
160+ }
161+ if (static_cast<uint8_t>(bitsPerSample) & A2dpUserCodecBitsPerSample::A2DP_SAMPLE_BITS_24_USER) {
162+ bitsVec.push_back(ohos::bluetooth::a2dp::CodecBitsPerSample::key_t::CODEC_BITS_PER_SAMPLE_24);
163+ }
164+ if (static_cast<uint8_t>(bitsPerSample) & A2dpUserCodecBitsPerSample::A2DP_SAMPLE_BITS_32_USER) {
165+ bitsVec.push_back(ohos::bluetooth::a2dp::CodecBitsPerSample::key_t::CODEC_BITS_PER_SAMPLE_32);
166+ }
167+ 
168+ return taihe::array<ohos::bluetooth::a2dp::CodecBitsPerSample>{
169+ taihe::copy_data_t{}, bitsVec.data(), bitsVec.size()};
170+ }
171+ 
172+ static taihe::array<ohos::bluetooth::a2dp::CodecChannelMode> ConvertCodecChannelModeToTaihe(uint8_t channelMode)
173+ {
174+ std::vector<ohos::bluetooth::a2dp::CodecChannelMode> channelVec;
175+ 
176+ if (channelMode == A2dpUserCodecChannelMode::A2DP_CHANNEL_MODE_NONE_USER) {
177+ channelVec.push_back(ohos::bluetooth::a2dp::CodecChannelMode::key_t::CODEC_CHANNEL_MODE_NONE);
178+ }
179+ if (static_cast<uint8_t>(channelMode) & A2dpUserCodecChannelMode::A2DP_SBC_CHANNEL_MODE_MONO_USER) {
180+ channelVec.push_back(ohos::bluetooth::a2dp::CodecChannelMode::key_t::CODEC_CHANNEL_MODE_MONO);
181+ }
182+ if (static_cast<uint8_t>(channelMode) & A2dpUserCodecChannelMode::A2DP_SBC_CHANNEL_MODE_MONO_STEREO_USER) {
183+ channelVec.push_back(ohos::bluetooth::a2dp::CodecChannelMode::key_t::CODEC_CHANNEL_MODE_STEREO);
184+ }
185+ 
186+ return taihe::array<ohos::bluetooth::a2dp::CodecChannelMode>{
187+ taihe::copy_data_t{}, channelVec.data(), channelVec.size()};
188+ }
189+ 
190+ static taihe::array<ohos::bluetooth::a2dp::CodecSampleRate> ConvertCodecSampleRateToTaihe(uint32_t sampleRate)
191+ {
192+ std::vector<ohos::bluetooth::a2dp::CodecSampleRate> rateVec;
193+ 
194+ if (sampleRate == A2dpUserCodecSampleRate::A2DP_SAMPLE_RATE_NONE_USER) {
195+ rateVec.push_back(ohos::bluetooth::a2dp::CodecSampleRate::key_t::CODEC_SAMPLE_RATE_NONE);
196+ }
197+ if (static_cast<uint32_t>(sampleRate) & A2dpUserCodecSampleRate::A2DP_SBC_SAMPLE_RATE_44100_USER) {
198+ rateVec.push_back(ohos::bluetooth::a2dp::CodecSampleRate::key_t::CODEC_SAMPLE_RATE_44100);
199+ }
200+ if (static_cast<uint32_t>(sampleRate) & A2dpUserCodecSampleRate::A2DP_L2HCV2_SAMPLE_RATE_48000_USER) {
201+ rateVec.push_back(ohos::bluetooth::a2dp::CodecSampleRate::key_t::CODEC_SAMPLE_RATE_48000);
202+ }
203+ if (static_cast<uint32_t>(sampleRate) & A2dpUserCodecSampleRate::A2DP_L2HCV2_SAMPLE_RATE_96000_USER) {
204+ rateVec.push_back(ohos::bluetooth::a2dp::CodecSampleRate::key_t::CODEC_SAMPLE_RATE_96000);
205+ }
206+ 
207+ return taihe::array<ohos::bluetooth::a2dp::CodecSampleRate>{
208+ taihe::copy_data_t{}, rateVec.data(), rateVec.size()};
209+ }
210+ 
211+ static taihe::array<ohos::bluetooth::a2dp::CodecFrameLength> ConvertCodecFrameLengthToTaihe(uint8_t codecType)
212+ {
213+ std::vector<ohos::bluetooth::a2dp::CodecFrameLength> frameLenVec;
214+ 
215+ // 仅 L2HC ST 和 L2HC V2 支持帧长配置,固定为 10ms
216+ if (codecType == A2DP_CODEC_TYPE_L2HCST_USER || codecType == A2DP_CODEC_TYPE_L2HCV2_USER) {
217+ frameLenVec.push_back(ohos::bluetooth::a2dp::CodecFrameLength::key_t::CODEC_FRAME_LENGTH_10MS);
218+ }
219+ 
220+ return taihe::array<ohos::bluetooth::a2dp::CodecFrameLength>{
221+ taihe::copy_data_t{}, frameLenVec.data(), frameLenVec.size()};
222+ }
223+ 
224+ taihe::array<ohos::bluetooth::a2dp::CodecInfoList> GetCurrentFullCodecInfo(taihe::string_view deviceId)
225+ {
226+ HILOGI("start");
227+ std::string remoteAddr = static_cast<std::string>(deviceId);
228+ bool checkRet = CheckDeviceIdParam(remoteAddr);
229+ 
230+ taihe::array<ohos::bluetooth::a2dp::CodecInfoList> result = {};
231+ 
232+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM, result);
233+ 
234+ A2dpCodecStatus a2dpCodecStatus;
235+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
236+ A2dpSource *profile = A2dpSource::GetProfile();
237+ a2dpCodecStatus = profile->GetCodecStatus(remoteDevice);
238+ 
239+ std::vector<ohos::bluetooth::a2dp::CodecInfoList> codecInfoListVec;
240+ 
241+ for (const auto& cap : a2dpCodecStatus.codecInfoConfirmedCap) {
242+ ohos::bluetooth::a2dp::CodecInfoList codecInfoList = {
243+ ohos::bluetooth::a2dp::CodecType::key_t::CODEC_TYPE_INVALID
244+ };
245+ 
246+ codecInfoList.codecType = ohos::bluetooth::a2dp::CodecType::from_value(cap.codecType);
247+
248+ codecInfoList.codecBitsPerSampleArray = ConvertCodecBitsPerSampleToTaihe(cap.bitsPerSample);
249+ 
250+ codecInfoList.codecChannelModeArray = ConvertCodecChannelModeToTaihe(cap.channelMode);
251+ 
252+ codecInfoList.codecSampleRateArray = ConvertCodecSampleRateToTaihe(cap.sampleRate);
253+ 
254+ codecInfoList.codecFrameLengthArray = ConvertCodecFrameLengthToTaihe(cap.codecType);
255+
256+ codecInfoListVec.push_back(codecInfoList);
257+ }
258+ 
259+ result = taihe::array<ohos::bluetooth::a2dp::CodecInfoList>{
260+ taihe::copy_data_t{}, codecInfoListVec.data(), codecInfoListVec.size()};
261+ 
262+ return result;
263+ }
264+ 
151 int32_t GetAutoPlayDisabledDuration(taihe::string_view deviceId)265 int32_t GetAutoPlayDisabledDuration(taihe::string_view deviceId)
152 {266 {
153 std::string remoteAddr = static_cast<std::string>(deviceId);267 std::string remoteAddr = static_cast<std::string>(deviceId);
Mframeworks/ets/taihe/bluetooth_access/idl/ohos.bluetooth.access.taihe+5-1
@@ -81,4 +81,8 @@ function GetLocalAddress(): String;
81 81 
82@gen_async("factoryReset")82@gen_async("factoryReset")
83@gen_promise("factoryReset")83@gen_promise("factoryReset")
84-function FactoryResetSync(): void;84+function FactoryResetSync(): void;
85+ 
86+function IsBluetoothSupported(): bool;
87+ 
88+function ConvertUuid(uuid: String): String;
Mframeworks/ets/taihe/bluetooth_access/src/ohos.bluetooth.access.impl.cpp+34-0
@@ -32,6 +32,9 @@
32namespace OHOS {32namespace OHOS {
33namespace Bluetooth {33namespace Bluetooth {
34std::shared_ptr<TaiheBluetoothAccessObserver> g_accessCallback = TaiheBluetoothAccessObserver::GetInstance();34std::shared_ptr<TaiheBluetoothAccessObserver> g_accessCallback = TaiheBluetoothAccessObserver::GetInstance();
35+constexpr int STR_LEN_OF_2_BYTES_UUID = 4;
36+constexpr int STR_LEN_OF_4_BYTES_UUID = 8;
37+constexpr int STR_LEN_OF_16_BYTES_UUID = 36;
35 38 
36void RestrictBluetooth()39void RestrictBluetooth()
37{40{
@@ -208,6 +211,35 @@ void FactoryResetSync()
208 HILOGI("factoryReset ret: %{public}d", ret);211 HILOGI("factoryReset ret: %{public}d", ret);
209 TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);212 TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
210}213}
214+ 
215+bool IsBluetoothSupported() {
216+ HILOGI("enter");
217+ bool isSupported = BluetoothHost::GetDefaultHost().IsBluetoothSupported();
218+ HILOGI("IsBluetoothSupported: %{public}d", isSupported);
219+ return isSupported;
220+}
221+ 
222+::taihe::string ConvertUuid(::taihe::string uuid)
223+{
224+ HILOGI("enter");
225+ ::taihe::string completeUuid = "";
226+ std::string uuidForCheck(uuid);
227+ std::string completeUuidCheck = "";
228+ if (uuidForCheck.size() != STR_LEN_OF_2_BYTES_UUID && uuidForCheck.size() != STR_LEN_OF_4_BYTES_UUID &&
229+ uuidForCheck.size() != STR_LEN_OF_16_BYTES_UUID) {
230+ HILOGE("invalid param");
231+ return completeUuid;
232+ }
233+ if (uuidForCheck.size() == STR_LEN_OF_2_BYTES_UUID) {
234+ completeUuidCheck = "0000" + uuidForCheck + "-0000-1000-8000-00805f9b34fb";
235+ } else if (uuidForCheck.size() == STR_LEN_OF_4_BYTES_UUID) {
236+ completeUuidCheck = uuidForCheck + "-0000-1000-8000-00805f9b34fb";
237+ } else {
238+ completeUuidCheck = uuidForCheck;
239+ }
240+ completeUuid = completeUuidCheck;
241+ return completeUuid;
242+}
211} // Bluetooth243} // Bluetooth
212} // OHOS244} // OHOS
213 245 
@@ -228,4 +260,6 @@ TH_EXPORT_CPP_API_DeletePersistentDeviceId(OHOS::Bluetooth::DeletePersistentDevi
228TH_EXPORT_CPP_API_AddPersistentDeviceId(OHOS::Bluetooth::AddPersistentDeviceId);260TH_EXPORT_CPP_API_AddPersistentDeviceId(OHOS::Bluetooth::AddPersistentDeviceId);
229TH_EXPORT_CPP_API_NotifyDialogResult(OHOS::Bluetooth::NotifyDialogResult);261TH_EXPORT_CPP_API_NotifyDialogResult(OHOS::Bluetooth::NotifyDialogResult);
230TH_EXPORT_CPP_API_FactoryResetSync(OHOS::Bluetooth::FactoryResetSync);262TH_EXPORT_CPP_API_FactoryResetSync(OHOS::Bluetooth::FactoryResetSync);
263+TH_EXPORT_CPP_API_IsBluetoothSupported(OHOS::Bluetooth::IsBluetoothSupported);
264+TH_EXPORT_CPP_API_ConvertUuid(OHOS::Bluetooth::ConvertUuid);
231// NOLINTEND265// NOLINTEND
Aframeworks/ets/taihe/bluetooth_bas/BUILD.gn+119-0
@@ -0,0 +1,119 @@
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_bas_taihe") {
21+ sources = [
22+ "idl/ohos.bluetooth.bas.taihe"
23+ ]
24+ deps = [
25+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_baseProfile:bluetooth_baseProfile_taihe",
26+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_common:bluetooth_common_taihe"
27+ ]
28+}
29+ 
30+subsystem_name = "communication"
31+part_name = "bluetooth"
32+taihe_generated_file_path_bas = "$taihe_file_path/out/$subsystem_name/$part_name/bas"
33+ 
34+ohos_taihe("run_taihe") {
35+ taihe_generated_file_path = "${taihe_generated_file_path_bas}"
36+ deps = [ ":bluetooth_bas_taihe" ]
37+ outputs = [
38+ "$taihe_generated_file_path/src/ohos.bluetooth.bas.ani.cpp",
39+ "$taihe_generated_file_path/src/ohos.bluetooth.bas.abi.c",
40+ ]
41+}
42+ 
43+taihe_shared_library("bluetoothBas_taihe_native") {
44+ cflags_cc = [
45+ "-Os",
46+ "-fno-rtti",
47+ "-fno-exceptions",
48+ "-fdata-sections",
49+ "-ffunction-sections",
50+ "-fno-unwind-tables",
51+ "-fno-asynchronous-unwind-tables",
52+ "-fno-merge-all-constants",
53+ "-flto",
54+ ]
55+ ldflags = [
56+ "-Wl,--as-needed",
57+ "-Wl,--gc-sections",
58+ ]
59+ shlib_type = "ani"
60+ taihe_generated_file_path = "${taihe_generated_file_path_bas}"
61+ part_name = "$part_name"
62+ subsystem_name = "$subsystem_name"
63+ sources = get_target_outputs(":run_taihe")
64+ include_dirs = [
65+ "include",
66+ "src",
67+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include",
68+ "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include",
69+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common"
70+ ]
71+ sources += [
72+ "src/ohos.bluetooth.bas.impl.cpp",
73+ "src/taihe_bluetooth_bas_observer.cpp",
74+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp",
75+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp"
76+ ]
77+ deps = [
78+ ":run_taihe",
79+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner:btframework",
80+ ]
81+ external_deps = [
82+ "c_utils:utils",
83+ "hilog:libhilog",
84+ "ipc:ipc_single",
85+ ]
86+ sanitize = {
87+ cfi = true # Enable/disable control flow integrity detection
88+ boundary_sanitize = true # Enable boundary san detection
89+ cfi_cross_dso = true # Cross-SO CFI Checks
90+ cfi_vcall_icall_only = true # CFI optimization, restrict CFI detection scope
91+ integer_overflow = true # Enable integer overflow detection
92+ ubsan = true # Enable some Ubsan options
93+ debug = false
94+ }
95+}
96+ 
97+generate_static_abc("bluetoothBas_abc") {
98+ base_url = "${taihe_generated_file_path_bas}"
99+ files = [ "${taihe_generated_file_path_bas}/@ohos.bluetooth.bas.ets" ]
100+ is_boot_abc = "True"
101+ device_dst_file = "/system/framework/bluetoothBas_abc.abc"
102+ dependencies = [ ":run_taihe" ]
103+}
104+ 
105+ohos_prebuilt_etc("bluetoothBas_etc") {
106+ source = "$target_out_dir/bluetoothBas_abc.abc"
107+ module_install_dir = "framework"
108+ part_name = "$part_name"
109+ subsystem_name = "$subsystem_name"
110+ deps = [ ":bluetoothBas_abc" ]
111+}
112+ 
113+group("bluetoothBas_taihe") {
114+ deps = [
115+ ":bluetoothBas_etc",
116+ ":bluetoothBas_taihe_native"
117+ ]
118+ # deps = [":run_taihe"]
119+}
Aframeworks/ets/taihe/bluetooth_bas/idl/ohos.bluetooth.bas.taihe+21-0
@@ -0,0 +1,21 @@
1+@!namespace("@ohos.bluetooth.bas", "bas")
2+@!sts_inject("""
3+static { loadLibraryWithPermissionCheck("bluetoothBas_taihe_native.z", "@ohos.bluetooth.bas") }
4+""")
5+ 
6+from ohos.bluetooth.baseProfile use BaseProfile;
7+from ohos.bluetooth.common use BluetoothAddress;
8+ 
9+function isBasSupported(): bool;
10+ 
11+@promise function getRemoteDeviceBatteryInfo(deviceId: BluetoothAddress): BatteryInfo;
12+ 
13+function OnBatteryChange(callback:(data: BatteryInfo) => void): void;
14+function OffBatteryChange(callback: Optional<(data: BatteryInfo) => void>): void;
15+ 
16+struct BatteryInfo {
17+ deviceId: BluetoothAddress;
18+ batteryLevel: i32;
19+}
20+ 
21+ 
Aframeworks/ets/taihe/bluetooth_bas/include/taihe_bluetooth_bas_observer.h+52-0
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (C) 2026 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_BAS_OBSERVER_H_
17+#define TAIHE_BLUETOOTH_BAS_OBSERVER_H_
18+ 
19+#include <future>
20+#include <memory>
21+#include <mutex>
22+ 
23+#include "bluetooth_bas_host.h"
24+#include "ohos.bluetooth.bas.BatteryInfo.proj.1.hpp"
25+#include "ohos.bluetooth.common.BluetoothRawAddressType.proj.1.hpp"
26+#include "taihe_event_module.h"
27+ 
28+namespace OHOS {
29+namespace Bluetooth {
30+ 
31+class TaiheBasCallback : public BluetoothRemoteDeviceBatteryObserver {
32+public:
33+ TaiheBasCallback();
34+ ~TaiheBasCallback() override = default;
35+ 
36+ static std::shared_ptr<TaiheBasCallback> GetInstance(void);
37+ 
38+ void OnGetBatteryLevelEvent(const BluetoothRemoteDevice &device, int32_t batteryLevel) override;
39+ void OnBatteryLevelChanged(const BluetoothRemoteDevice &device, int32_t batteryLevel) override;
40+ 
41+ // Equivalent to NAPI's eventSubscribe_ for onBatteryChange/offBatteryChange
42+ EventModule<void(::ohos::bluetooth::bas::BatteryInfo const&)> batteryChangeEventModule_;
43+ 
44+ // Equivalent to NAPI's asyncWorkMap_ for getRemoteDeviceBatteryInfo
45+ // OnGetBatteryLevelEvent resolves this promise to unblock the caller
46+ std::shared_ptr<std::promise<::ohos::bluetooth::bas::BatteryInfo>> batteryLevelPromise_;
47+ std::mutex batteryLevelPromiseLock_;
48+};
49+ 
50+} // namespace Bluetooth
51+} // namespace OHOS
52+#endif // TAIHE_BLUETOOTH_BAS_OBSERVER_H_
Aframeworks/ets/taihe/bluetooth_bas/src/ohos.bluetooth.bas.impl.cpp+148-0
@@ -0,0 +1,148 @@
1+/*
2+ * Copyright (C) 2026 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_bas_impl"
18+#endif
19+ 
20+#include "ohos.bluetooth.bas.impl.hpp"
21+#include "ohos.bluetooth.bas.proj.hpp"
22+#include "taihe/runtime.hpp"
23+ 
24+#include <chrono>
25+#include <map>
26+#include <mutex>
27+#include <string>
28+ 
29+#include "bluetooth_bas_host.h"
30+#include "bluetooth_errorcode.h"
31+#include "bluetooth_log.h"
32+#include "bluetooth_remote_device.h"
33+#include "bluetooth_utils.h"
34+#include "taihe_bluetooth_bas_observer.h"
35+#include "taihe_bluetooth_error.h"
36+#include "taihe_bluetooth_utils.h"
37+ 
38+using namespace OHOS::Bluetooth;
39+ 
40+namespace {
41+// Equivalent to NAPI's g_basObserver
42+std::shared_ptr<OHOS::Bluetooth::TaiheBasCallback> g_basCallback = OHOS::Bluetooth::TaiheBasCallback::GetInstance();
43+std::once_flag g_registerObserverFlag;
44+constexpr int32_t BATTERY_LEVEL_TIMEOUT_SECONDS = 10;
45+ 
46+// Equivalent to NAPI's RegisterAccessObserverToHost
47+void EnsureObserverRegistered()
48+{
49+ std::call_once(g_registerObserverFlag, []() {
50+ BluetoothBasHost::GetProfile()->RegisterBatteryObserver(g_basCallback);
51+ });
52+}
53+ 
54+// Equivalent to NAPI NapiBas::IsBasSupported
55+bool isBasSupported()
56+{
57+ HILOGI("enter");
58+ EnsureObserverRegistered();
59+ bool isSupported = false;
60+ int32_t ret = BluetoothBasHost::GetProfile()->IsBasSupported(isSupported);
61+ TAIHE_BT_ASSERT_RETURN(ret == BT_NO_ERROR, ret, false);
62+ return isSupported;
63+}
64+ 
65+// Equivalent to NAPI NapiBas::GetRemoteDeviceBatteryInfo
66+// @promise generates a Promise wrapper in ETS that runs this on a worker thread via launch(),
67+// so this function can block until OnGetBatteryLevelEvent resolves the promise.
68+::ohos::bluetooth::bas::BatteryInfo getRemoteDeviceBatteryInfo(
69+ ::ohos::bluetooth::common::BluetoothAddress const& deviceId)
70+{
71+ HILOGI("enter");
72+ EnsureObserverRegistered();
73+ 
74+ // Set up promise for async result (equivalent to NAPI's asyncWorkMap_.TryPush)
75+ auto promise = std::make_shared<std::promise<::ohos::bluetooth::bas::BatteryInfo>>();
76+ auto future = promise->get_future();
77+ {
78+ std::lock_guard<std::mutex> guard(g_basCallback->batteryLevelPromiseLock_);
79+ g_basCallback->batteryLevelPromise_ = promise;
80+ }
81+ 
82+ // Call GetBatteryLevel to initiate async request (matches NAPI)
83+ std::string addrStr(deviceId.address.c_str());
84+ int32_t ret = BluetoothBasHost::GetProfile()->GetBatteryLevel(addrStr);
85+ if (ret != BT_NO_ERROR) {
86+ std::lock_guard<std::mutex> guard(g_basCallback->batteryLevelPromiseLock_);
87+ g_basCallback->batteryLevelPromise_.reset();
88+ TAIHE_BT_ASSERT_RETURN(false, ret, (::ohos::bluetooth::bas::BatteryInfo{deviceId, -1}));
89+ }
90+ 
91+ // Wait for OnGetBatteryLevelEvent callback to resolve the promise
92+ auto status = future.wait_for(std::chrono::seconds(BATTERY_LEVEL_TIMEOUT_SECONDS));
93+ {
94+ std::lock_guard<std::mutex> guard(g_basCallback->batteryLevelPromiseLock_);
95+ g_basCallback->batteryLevelPromise_.reset();
96+ }
97+ 
98+ if (status == std::future_status::timeout) {
99+ HILOGE("getRemoteDeviceBatteryInfo timeout");
100+ TAIHE_BT_ASSERT_RETURN(false, BT_ERR_INTERNAL_ERROR, (::ohos::bluetooth::bas::BatteryInfo{deviceId, -1}));
101+ }
102+ 
103+ return future.get();
104+}
105+ 
106+// Equivalent to NAPI NapiBas::OnBatteryChange
107+void OnBatteryChange(::taihe::callback_view<void(::ohos::bluetooth::bas::BatteryInfo const& data)> callback)
108+{
109+ HILOGI("enter");
110+ EnsureObserverRegistered();
111+ 
112+ // Register callback (equivalent to NAPI's eventSubscribe_.RegisterWithName)
113+ g_basCallback->batteryChangeEventModule_.RegisterEvent(callback);
114+ 
115+ // Get connected device battery infos and notify immediately (matches NAPI)
116+ std::map<std::string, int32_t> batteryInfos;
117+ int32_t ret = BluetoothBasHost::GetProfile()->GetConnectedDeviceBatteryInfos(batteryInfos);
118+ if (ret != BT_NO_ERROR) {
119+ HILOGE("GetConnectedDeviceBatteryInfos failed, ret: %{public}d", ret);
120+ return;
121+ }
122+ const int32_t maxBatteryLevel = 100;
123+ for (const auto & [deviceAddr, batteryLevel] : batteryInfos) {
124+ if (batteryLevel < 0 || batteryLevel > maxBatteryLevel || !IsValidAddress(deviceAddr)) {
125+ continue;
126+ }
127+ BluetoothRemoteDevice remoteDevice(deviceAddr, BTTransport::ADAPTER_BLE);
128+ g_basCallback->OnBatteryLevelChanged(remoteDevice, batteryLevel);
129+ }
130+}
131+ 
132+// Equivalent to NAPI NapiBas::OffBatteryChange
133+void OffBatteryChange(
134+ ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::bas::BatteryInfo const& data)>> callback)
135+{
136+ HILOGI("enter");
137+ // Deregister callback (equivalent to NAPI's eventSubscribe_.DeregisterWithName)
138+ g_basCallback->batteryChangeEventModule_.DeregisterEvent(callback);
139+}
140+} // namespace
141+ 
142+// Since these macros are auto-generate, lint will cause false positive.
143+// NOLINTBEGIN
144+TH_EXPORT_CPP_API_isBasSupported(isBasSupported);
145+TH_EXPORT_CPP_API_getRemoteDeviceBatteryInfo(getRemoteDeviceBatteryInfo);
146+TH_EXPORT_CPP_API_OnBatteryChange(OnBatteryChange);
147+TH_EXPORT_CPP_API_OffBatteryChange(OffBatteryChange);
148+// NOLINTEND
Aframeworks/ets/taihe/bluetooth_bas/src/taihe_bluetooth_bas_observer.cpp+79-0
@@ -0,0 +1,79 @@
1+/*
2+ * Copyright (C) 2026 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_bas_observer"
18+#endif
19+ 
20+#include "taihe_bluetooth_bas_observer.h"
21+ 
22+#include <string>
23+ 
24+#include "bluetooth_errorcode.h"
25+#include "bluetooth_log.h"
26+#include "bluetooth_remote_device.h"
27+#include "bluetooth_utils.h"
28+#include "taihe/string.hpp"
29+ 
30+namespace OHOS {
31+namespace Bluetooth {
32+ 
33+TaiheBasCallback::TaiheBasCallback()
34+{}
35+ 
36+std::shared_ptr<TaiheBasCallback> TaiheBasCallback::GetInstance(void)
37+{
38+ static std::shared_ptr<TaiheBasCallback> instance = std::make_shared<TaiheBasCallback>();
39+ return instance;
40+}
41+ 
42+// Equivalent to NAPI NapiBasCallback::OnGetBatteryLevelEvent
43+// Resolves the async work (promise) from getRemoteDeviceBatteryInfo
44+void TaiheBasCallback::OnGetBatteryLevelEvent(const BluetoothRemoteDevice &device, int32_t batteryLevel)
45+{
46+ HILOGI("enter, device: %{public}s, batteryLevel: %{public}d", GET_ENCRYPT_ADDR(device), batteryLevel);
47+ std::lock_guard<std::mutex> guard(batteryLevelPromiseLock_);
48+ if (batteryLevelPromise_) {
49+ std::string addrStr = device.GetDeviceAddr();
50+ ::ohos::bluetooth::common::BluetoothAddress address{
51+ ::taihe::string(addrStr),
52+ ::ohos::bluetooth::common::BluetoothAddressType(
53+ ::ohos::bluetooth::common::BluetoothAddressType::key_t::REAL),
54+ ::taihe::optional<::ohos::bluetooth::common::BluetoothRawAddressType>{}
55+ };
56+ ::ohos::bluetooth::bas::BatteryInfo info{address, batteryLevel};
57+ batteryLevelPromise_->set_value(info);
58+ batteryLevelPromise_.reset();
59+ }
60+}
61+ 
62+// Equivalent to NAPI NapiBasCallback::OnBatteryLevelChanged
63+// Publishes event to registered onBatteryChange callbacks
64+void TaiheBasCallback::OnBatteryLevelChanged(const BluetoothRemoteDevice &device, int32_t batteryLevel)
65+{
66+ HILOGI("enter, device: %{public}s, batteryLevel: %{public}d", GET_ENCRYPT_ADDR(device), batteryLevel);
67+ std::string addrStr = device.GetDeviceAddr();
68+ ::ohos::bluetooth::common::BluetoothAddress address{
69+ ::taihe::string(addrStr),
70+ ::ohos::bluetooth::common::BluetoothAddressType(
71+ ::ohos::bluetooth::common::BluetoothAddressType::key_t::REAL),
72+ ::taihe::optional<::ohos::bluetooth::common::BluetoothRawAddressType>{}
73+ };
74+ ::ohos::bluetooth::bas::BatteryInfo info{address, batteryLevel};
75+ batteryChangeEventModule_.PublishEvent(info);
76+}
77+ 
78+} // namespace Bluetooth
79+} // namespace OHOS
Mframeworks/ets/taihe/bluetooth_ble/BUILD.gn+3-1
@@ -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 = [
Mframeworks/ets/taihe/bluetooth_ble/idl/ohos.bluetooth.ble.taihe+135-0
@@ -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;
Mframeworks/ets/taihe/bluetooth_ble/include/taihe_bluetooth_ble_advertise_callback.h+4-2
@@ -22,9 +22,9 @@
22#include "event_handler.h"22#include "event_handler.h"
23#include "ohos.bluetooth.ble.impl.hpp"23#include "ohos.bluetooth.ble.impl.hpp"
24#include "ohos.bluetooth.ble.proj.hpp"24#include "ohos.bluetooth.ble.proj.hpp"
25-#include "stdexcept"
26-#include "taihe_async_callback.h"
27#include "taihe/runtime.hpp"25#include "taihe/runtime.hpp"
26+#include "taihe_async_callback.h"
27+#include "taihe_event_module.h"
28 28 
29namespace OHOS {29namespace OHOS {
30namespace Bluetooth {30namespace Bluetooth {
@@ -45,6 +45,8 @@ public:
45 45 
46 TaiheAsyncWorkMap asyncWorkMap_ {};46 TaiheAsyncWorkMap asyncWorkMap_ {};
47 47 
48+ EventModule<void(::ohos::bluetooth::ble::AdvertisingStateChangeInfo const&)> advertisingStateChangeEvent_ {};
49+ 
48 int advHandle_ = -1;50 int advHandle_ = -1;
49};51};
50} // namespace Bluetooth52} // namespace Bluetooth
Mframeworks/ets/taihe/bluetooth_ble/include/taihe_bluetooth_ble_central_manager_callback.h+7-0
@@ -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
Mframeworks/ets/taihe/bluetooth_ble/include/taihe_bluetooth_ble_scanner.h+2-0
@@ -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 {
Mframeworks/ets/taihe/bluetooth_ble/include/taihe_bluetooth_gatt_client.h+41-0
@@ -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_;
Mframeworks/ets/taihe/bluetooth_ble/include/taihe_bluetooth_gatt_client_callback.h+18-0
@@ -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};
Mframeworks/ets/taihe/bluetooth_ble/include/taihe_bluetooth_gatt_server.h+22-0
@@ -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 {
Mframeworks/ets/taihe/bluetooth_ble/include/taihe_bluetooth_gatt_server_callback.h+17-0
@@ -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
Mframeworks/ets/taihe/bluetooth_ble/src/ohos.bluetooth.ble.impl.cpp+39-1
@@ -23,14 +23,15 @@
23#include "bluetooth_log.h"23#include "bluetooth_log.h"
24#include "bluetooth_remote_device.h"24#include "bluetooth_remote_device.h"
25#include "bluetooth_utils.h"25#include "bluetooth_utils.h"
26-#include "stdexcept"
27#include "taihe_bluetooth_ble_advertise_callback.h"26#include "taihe_bluetooth_ble_advertise_callback.h"
27+#include "taihe_bluetooth_ble_central_manager_callback.h"
28#include "taihe_bluetooth_ble_scanner.h"28#include "taihe_bluetooth_ble_scanner.h"
29#include "taihe_bluetooth_ble_utils.h"29#include "taihe_bluetooth_ble_utils.h"
30#include "taihe_bluetooth_error.h"30#include "taihe_bluetooth_error.h"
31#include "taihe_bluetooth_gatt_client.h"31#include "taihe_bluetooth_gatt_client.h"
32#include "taihe_bluetooth_gatt_server.h"32#include "taihe_bluetooth_gatt_server.h"
33#include "taihe_bluetooth_utils.h"33#include "taihe_bluetooth_utils.h"
34+#include "taihe_event_module.h"
34#include "taihe_parser_utils.h"35#include "taihe_parser_utils.h"
35#include "taihe/array.hpp"36#include "taihe/array.hpp"
36#include "taihe/optional.hpp"37#include "taihe/optional.hpp"
@@ -681,6 +682,38 @@ void EnableAdvertisingAsync(const ohos::bluetooth::ble::AdvertisingEnableParams
681 TAIHE_BT_ASSERT_RETURN_VOID(false, result.errorCode);682 TAIHE_BT_ASSERT_RETURN_VOID(false, result.errorCode);
682 }683 }
683}684}
685+ 
686+void StopAdvertisingSync(int32_t advertisingId) {
687+ HILOGI("enter, advertisingId: %{public}d", advertisingId);
688+ std::shared_ptr<BleAdvertiser> bleAdvertiser = BleAdvertiserGetInstance();
689+ TAIHE_BT_ASSERT_RETURN_VOID(bleAdvertiser != nullptr, BT_ERR_INTERNAL_ERROR);
690+ 
691+ auto callback = bleAdvertiser->GetAdvObserver(static_cast<uint32_t>(advertisingId));
692+ TAIHE_BT_ASSERT_RETURN_VOID(callback != nullptr, BT_ERR_INVALID_PARAM);
693+ 
694+ int ret = bleAdvertiser->StopAdvertising(callback);
695+ TAIHE_BT_ASSERT_RETURN_VOID(ret == BT_NO_ERROR, ret);
696+}
697+ 
698+void OnAdvertisingStateChange(::taihe::callback_view<void(::ohos::bluetooth::ble::AdvertisingStateChangeInfo const& data)> callback) {
699+ HILOGI("enter");
700+ TaiheBluetoothBleAdvertiseCallback::GetInstance()->advertisingStateChangeEvent_.RegisterEvent(callback);
701+}
702+ 
703+void OffAdvertisingStateChange(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::AdvertisingStateChangeInfo const& data)>> callback) {
704+ HILOGI("enter");
705+ TaiheBluetoothBleAdvertiseCallback::GetInstance()->advertisingStateChangeEvent_.DeregisterEvent(callback);
706+}
707+ 
708+void OnBleDeviceFind(::taihe::callback_view<void(::taihe::array_view<::ohos::bluetooth::ble::ScanResult> data)> callback) {
709+ HILOGI("enter");
710+ TaiheBluetoothBleCentralManagerCallback::GetInstance().moduleBleDeviceFindEvent_.RegisterEvent(callback);
711+}
712+ 
713+void OffBLEDeviceFind(::taihe::optional_view<::taihe::callback<void(::taihe::array_view<::ohos::bluetooth::ble::ScanResult> data)>> callback) {
714+ HILOGI("enter");
715+ TaiheBluetoothBleCentralManagerCallback::GetInstance().moduleBleDeviceFindEvent_.DeregisterEvent(callback);
716+}
684} // Bluetooth717} // Bluetooth
685} // OHOS718} // OHOS
686 719 
@@ -700,4 +733,9 @@ TH_EXPORT_CPP_API_DisableAdvertisingPromise(OHOS::Bluetooth::DisableAdvertisingP
700TH_EXPORT_CPP_API_DisableAdvertisingAsync(OHOS::Bluetooth::DisableAdvertisingAsync);733TH_EXPORT_CPP_API_DisableAdvertisingAsync(OHOS::Bluetooth::DisableAdvertisingAsync);
701TH_EXPORT_CPP_API_EnableAdvertisingPromise(OHOS::Bluetooth::EnableAdvertisingPromise);734TH_EXPORT_CPP_API_EnableAdvertisingPromise(OHOS::Bluetooth::EnableAdvertisingPromise);
702TH_EXPORT_CPP_API_EnableAdvertisingAsync(OHOS::Bluetooth::EnableAdvertisingAsync);735TH_EXPORT_CPP_API_EnableAdvertisingAsync(OHOS::Bluetooth::EnableAdvertisingAsync);
736+TH_EXPORT_CPP_API_StopAdvertisingSync(OHOS::Bluetooth::StopAdvertisingSync);
737+TH_EXPORT_CPP_API_OnAdvertisingStateChange(OHOS::Bluetooth::OnAdvertisingStateChange);
738+TH_EXPORT_CPP_API_OffAdvertisingStateChange(OHOS::Bluetooth::OffAdvertisingStateChange);
739+TH_EXPORT_CPP_API_OnBleDeviceFind(OHOS::Bluetooth::OnBleDeviceFind);
740+TH_EXPORT_CPP_API_OffBLEDeviceFind(OHOS::Bluetooth::OffBLEDeviceFind);
703// NOLINTEND741// NOLINTEND
Mframeworks/ets/taihe/bluetooth_ble/src/taihe_bluetooth_ble_advertise_callback.cpp+20-0
@@ -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)
Mframeworks/ets/taihe/bluetooth_ble/src/taihe_bluetooth_ble_central_manager_callback.cpp+57-0
@@ -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)
Mframeworks/ets/taihe/bluetooth_ble/src/taihe_bluetooth_ble_scanner.cpp+12-0
@@ -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
Mframeworks/ets/taihe/bluetooth_ble/src/taihe_bluetooth_gatt_client.cpp+416-3
@@ -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 },
@@ -269,7 +273,7 @@ static TaihePromiseAndCallback TaiheReadDescriptorValue(const ohos::bluetooth::b
269 int ret = BT_ERR_INTERNAL_ERROR;273 int ret = BT_ERR_INTERNAL_ERROR;
270 if (gattClient) {274 if (gattClient) {
271 ret = gattClient->ReadDescriptor(*descriptor);275 ret = gattClient->ReadDescriptor(*descriptor);
272- ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret)); // Adaptation for old sdk276+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
273 }277 }
274 return TaiheAsyncWorkRet(ret);278 return TaiheAsyncWorkRet(ret);
275 };279 };
@@ -337,7 +341,7 @@ static TaihePromiseAndCallback TaiheSetCharacteristicChangeIndication(
337 int ret = BT_ERR_INTERNAL_ERROR;341 int ret = BT_ERR_INTERNAL_ERROR;
338 if (gattClient) {342 if (gattClient) {
339 ret = gattClient->SetIndicateCharacteristic(*character, enable);343 ret = gattClient->SetIndicateCharacteristic(*character, enable);
340- ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret)); // Adaptation for old sdk344+ ret = GetSDKAdaptedStatusCode(GattClientDeviceImpl::GattStatusFromService(ret));
341 }345 }
342 return TaiheAsyncWorkRet(ret);346 return TaiheAsyncWorkRet(ret);
343 };347 };
@@ -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
Mframeworks/ets/taihe/bluetooth_ble/src/taihe_bluetooth_gatt_client_callback.cpp+73-0
@@ -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
Mframeworks/ets/taihe/bluetooth_ble/src/taihe_bluetooth_gatt_server.cpp+269-0
@@ -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
Mframeworks/ets/taihe/bluetooth_ble/src/taihe_bluetooth_gatt_server_callback.cpp+102-0
@@ -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
Aframeworks/ets/taihe/bluetooth_common/BUILD.gn+109-0
@@ -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+}
Aframeworks/ets/taihe/bluetooth_common/idl/ohos.bluetooth.common.taihe+20-0
@@ -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+}
Aframeworks/ets/taihe/bluetooth_common/src/ani_constructor.cpp+29-0
@@ -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+}
Aframeworks/ets/taihe/bluetooth_common/src/ohos.bluetooth.common.impl.cpp+30-0
@@ -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
Mframeworks/ets/taihe/bluetooth_connection/idl/ohos.bluetooth.connection.taihe+63-1
@@ -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+}
Mframeworks/ets/taihe/bluetooth_connection/include/taihe_bluetooth_connection_callback.h+8-0
@@ -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);
Mframeworks/ets/taihe/bluetooth_connection/src/ohos.bluetooth.connection.impl.cpp+330-0
@@ -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
Mframeworks/ets/taihe/bluetooth_connection/src/taihe_bluetooth_connection_callback.cpp+26-1
@@ -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)
Mframeworks/ets/taihe/bluetooth_hfp/BUILD.gn+3-1
@@ -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"
Mframeworks/ets/taihe/bluetooth_hfp/idl/ohos.bluetooth.hfp.taihe+20-1
@@ -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;
Aframeworks/ets/taihe/bluetooth_hfp/include/taihe_bluetooth_hfp_hf_observer.h+44-0
@@ -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_ */
Mframeworks/ets/taihe/bluetooth_hfp/src/ohos.bluetooth.hfp.impl.cpp+135-0
@@ -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
Aframeworks/ets/taihe/bluetooth_hfp/src/taihe_bluetooth_hfp_hf_observer.cpp+63-0
@@ -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
Mframeworks/ets/taihe/bluetooth_hid/BUILD.gn+6-0
@@ -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"
Mframeworks/ets/taihe/bluetooth_hid/idl/ohos.bluetooth.hid.taihe+122-1
@@ -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,124 @@ 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+interface HidDeviceProfile : 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: BluetoothAddress): void;
58+ Disconnect(deviceId: String): void;
59+ ReportError(error: ErrorReason): void;
60+ UnregisterHidDevice(): void;
61+ SendReport(id: i32, reportData: @arraybuffer Array<u8>): void;
62+ ReplyReport(type: ReportType, id: i32, reportData: @arraybuffer Array<u8>): void;
63+ OnSetProtocol(callback: (data: ProtocolData) => void): void;
64+ OffSetProtocol(callback: Optional<(data: ProtocolData) => void>): void;
65+ OnInterruptDataReceived(callback: (data: InterruptData) => void): void;
66+ OffInterruptDataReceived(callback: Optional<(data: InterruptData) => void>): void;
67+ 
68+ @gen_async("registerHidDevice")
69+ RegisterHidDeviceSync(sdp: HidDeviceSdp, inQos: HidDeviceQos, outQos: HidDeviceQos): bool;
70+ 
71+ OnSetReport(callback: (data: SetReportData) => void): void;
72+ OffSetReport(callback: Optional<(data: SetReportData) => void>): void;
73+ OnGetReport(callback: (data: GetReportData) => void): void;
74+ OffGetReport(callback: Optional<(data: GetReportData) => void>): void;
75+ OnVirtualCableUnplug(callback:() => void): void;
76+ OffVirtualCableUnplug(callback: Optional<() => void>): void;
77+}
78+function CreateHidDeviceProfile(): HidDeviceProfile;
79+ 
80+enum ErrorReason: i32 {
81+ RSP_SUCCESS = 0,
82+ RSP_NOT_READY = 1,
83+ RSP_INVALID_REPORT_ID = 2,
84+ RSP_UNSUPPORTED_REQ = 3,
85+ RSP_INVALID_PARAM = 4,
86+ RSP_UNKNOWN = 14
87+}
88+ 
89+struct ProtocolData {
90+ protocol: ProtocolType;
91+}
92+ 
93+enum ProtocolType: i32 {
94+ PROTOCOL_BOOT_MODE = 0,
95+ PROTOCOL_REPORT_MODE = 1
96+}
97+ 
98+struct InterruptData {
99+ id: i32;
100+ data: @arraybuffer Array<u8>;
101+}
102+ 
103+struct HidDeviceSdp {
104+ name: String;
105+ description: String;
106+ provider: String;
107+ subclass: Subclass;
108+ descriptors: @arraybuffer Array<u8>;
109+}
110+ 
111+enum Subclass: i32 {
112+ SUBCLASS_UNCATEGORIZED = 0,
113+ SUBCLASS_JOYSTICK = 1,
114+ SUBCLASS_GAMEPAD = 2,
115+ SUBCLASS_REMOTE_CONTROL = 3,
116+ SUBCLASS_SENSING_DEVICE = 4,
117+ SUBCLASS_DIGITIZER_TABLET = 5,
118+ SUBCLASS_CARD_READER = 6,
119+ SUBCLASS_KEYBOARD = 64,
120+ SUBCLASS_MOUSE = 128,
121+ SUBCLASS_COMBO = 192
122+}
123+ 
124+struct HidDeviceQos {
125+ serviceType: Optional<ServiceType>;
126+ tokenRate: Optional<i32>;
127+ tokenBucketSize: Optional<i32>;
128+ peakBandwidth: Optional<i32>;
129+ latency: Optional<i32>;
130+ delayVariation: Optional<i32>;
131+}
132+ 
133+enum ServiceType: String {
134+ MEETING = "Meeting",
135+ WATCHING = "Watching",
136+ REPAYMENT = "Repayment",
137+ LIVE = "Live",
138+ SHOPPING = "Shopping",
139+ TRIP = "Trip",
140+ CLASS = "Class",
141+ SPORTS_EVENTS = "SportsEvents",
142+ SPORTS_EXERCISE = "SportsExercise"
143+}
144+ 
145+struct SetReportData {
146+ type: ReportType;
147+ id: i32;
148+ data: @arraybuffer Array<u8>;
149+}
150+ 
151+struct GetReportData {
152+ type: ReportType;
153+ id: i32;
154+ bufferSize: i32;
155+}
156+ 
157+enum ReportType: i32 {
158+ REPORT_TYPE_INPUT = 1,
159+ REPORT_TYPE_OUTPUT = 2,
160+ REPORT_TYPE_FEATURE = 3
161+}
Aframeworks/ets/taihe/bluetooth_hid/include/taihe_bluetooth_hid_device_observer.h+53-0
@@ -0,0 +1,53 @@
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 <shared_mutex>
20+#include "bluetooth_hid_device.h"
21+#include "ohos.bluetooth.hid.proj.hpp"
22+#include "ohos.bluetooth.hid.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 TaiheBluetoothHidDeviceObserver : public HidDeviceObserver {
31+public:
32+ void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state) override;
33+ void OnGetReport(int type, int id, uint16_t bufferSize) override;
34+ void OnSetProtocol(int protocol) override;
35+ void OnInterruptDataReceived(int id, const std::vector<uint8_t> &data) override;
36+ void OnSetReport(int type, int id, const std::vector<uint8_t> &data) override;
37+ void OnVirtualCableUnplug() override;
38+ 
39+ TaiheBluetoothHidDeviceObserver();
40+ ~TaiheBluetoothHidDeviceObserver() override = default;
41+ 
42+private:
43+ friend class HidDeviceProfileImpl;
44+ EventModule<void(::ohos::bluetooth::baseProfile::StateChangeParam const& data)> connectionStateChange_;
45+ EventModule<void(::ohos::bluetooth::hid::ProtocolData const& data)> setProtocol_;
46+ EventModule<void(::ohos::bluetooth::hid::InterruptData const& data)> interruptDataReceived_;
47+ EventModule<void(::ohos::bluetooth::hid::SetReportData const& data)> setReport_;
48+ EventModule<void(::ohos::bluetooth::hid::GetReportData const& data)> getReport_;
49+ EventModule<void()> virtualCableUnplug_;
50+};
51+} // namespace Bluetooth
52+} // namespace OHOS
53+#endif /* TAIHE_BLUETOOTH_HID_DEVICE_OBSERVER_H_ */
Mframeworks/ets/taihe/bluetooth_hid/src/ohos.bluetooth.hid.impl.cpp+286-0
@@ -23,8 +23,11 @@
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"
29 32 
30namespace OHOS {33namespace OHOS {
@@ -163,10 +166,293 @@ private:
163 // as the parameters in the constructor of the actual implementation class.166 // as the parameters in the constructor of the actual implementation class.
164 return taihe::make_holder<HidHostProfileImpl, ::ohos::bluetooth::hid::HidHostProfile>();167 return taihe::make_holder<HidHostProfileImpl, ::ohos::bluetooth::hid::HidHostProfile>();
165}168}
169+ 
170+class HidDeviceProfileImpl {
171+public:
172+ HidDeviceProfileImpl()
173+ {
174+ observer_ = std::make_shared<TaiheBluetoothHidDeviceObserver>();
175+ HidDevice *profile = HidDevice::GetProfile();
176+ profile->RegisterObserver(observer_);
177+ }
178+ 
179+ void OnConnectionStateChange(::taihe::callback_view<void(
180+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)> callback)
181+ {
182+ if (observer_) {
183+ observer_->connectionStateChange_.RegisterEvent(callback);
184+ }
185+ }
186+ 
187+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
188+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>> callback)
189+ {
190+ if (observer_) {
191+ observer_->connectionStateChange_.DeregisterEvent(callback);
192+ }
193+ }
194+ 
195+ void OnSetProtocol(::taihe::callback_view<void(
196+ ::ohos::bluetooth::hid::ProtocolData const& data)> callback)
197+ {
198+ if (observer_) {
199+ observer_->setProtocol_.RegisterEvent(callback);
200+ }
201+ }
202+ 
203+ void OffSetProtocol(::taihe::optional_view<::taihe::callback<void(
204+ ::ohos::bluetooth::hid::ProtocolData const& data)>> callback)
205+ {
206+ if (observer_) {
207+ observer_->setProtocol_.DeregisterEvent(callback);
208+ }
209+ }
210+ 
211+ void OnInterruptDataReceived(::taihe::callback_view<void(
212+ ::ohos::bluetooth::hid::InterruptData const& data)> callback)
213+ {
214+ if (observer_) {
215+ observer_->interruptDataReceived_.RegisterEvent(callback);
216+ }
217+ }
218+ 
219+ void OffInterruptDataReceived(::taihe::optional_view<::taihe::callback<void(
220+ ::ohos::bluetooth::hid::InterruptData const& data)>> callback)
221+ {
222+ if (observer_) {
223+ observer_->interruptDataReceived_.DeregisterEvent(callback);
224+ }
225+ }
226+ 
227+ void OnSetReport(::taihe::callback_view<void(
228+ ::ohos::bluetooth::hid::SetReportData const& data)> callback)
229+ {
230+ if (observer_) {
231+ observer_->setReport_.RegisterEvent(callback);
232+ }
233+ }
234+ 
235+ void OffSetReport(::taihe::optional_view<::taihe::callback<void(
236+ ::ohos::bluetooth::hid::SetReportData const& data)>> callback)
237+ {
238+ if (observer_) {
239+ observer_->setReport_.DeregisterEvent(callback);
240+ }
241+ }
242+ 
243+ void OnGetReport(::taihe::callback_view<void(
244+ ::ohos::bluetooth::hid::GetReportData const& data)> callback)
245+ {
246+ if (observer_) {
247+ observer_->getReport_.RegisterEvent(callback);
248+ }
249+ }
250+ 
251+ void OffGetReport(::taihe::optional_view<::taihe::callback<void(
252+ ::ohos::bluetooth::hid::GetReportData const& data)>> callback)
253+ {
254+ if (observer_) {
255+ observer_->getReport_.DeregisterEvent(callback);
256+ }
257+ }
258+ 
259+ void OnVirtualCableUnplug(::taihe::callback_view<void()> callback)
260+ {
261+ if (observer_) {
262+ observer_->virtualCableUnplug_.RegisterEvent(callback);
263+ }
264+ }
265+ 
266+ void OffVirtualCableUnplug(::taihe::optional_view<::taihe::callback<void()>> callback)
267+ {
268+ if (observer_) {
269+ observer_->virtualCableUnplug_.DeregisterEvent(callback);
270+ }
271+ }
272+ 
273+ void Connect(::ohos::bluetooth::common::BluetoothAddress const& deviceId)
274+ {
275+ HILOGI("enter");
276+ AddressInfo addressInfo;
277+ addressInfo.SetAddress(std::string(deviceId.address));
278+ addressInfo.SetAddressType(static_cast<uint8_t>(deviceId.addressType.get_key()));
279+ if (deviceId.rawAddressType.has_value()) {
280+ addressInfo.SetRawAddressType(static_cast<uint8_t>(deviceId.rawAddressType.value().get_key()));
281+ }
282+ HidDevice *profile = HidDevice::GetProfile();
283+ int32_t errorCode = profile->Connect(addressInfo);
284+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
285+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
286+ }
287+ 
288+ void Disconnect(::taihe::string_view deviceId)
289+ {
290+ HILOGI("enter");
291+ HidDevice *profile = HidDevice::GetProfile();
292+ int32_t errorCode = profile->Disconnect();
293+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
294+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
295+ }
296+ 
297+ void ReportError(::ohos::bluetooth::hid::ErrorReason error)
298+ {
299+ HILOGI("enter");
300+ HidDevice *profile = HidDevice::GetProfile();
301+ int32_t errorCode = profile->ReportError(static_cast<ErrorReason>(error.get_value()));
302+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
303+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
304+ }
305+ 
306+ void UnregisterHidDevice()
307+ {
308+ HILOGI("enter");
309+ HidDevice *profile = HidDevice::GetProfile();
310+ int32_t errorCode = profile->UnregisterHidDevice();
311+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
312+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
313+ }
314+ 
315+ void SendReport(int32_t id, ::taihe::array_view<uint8_t> reportData)
316+ {
317+ HILOGI("enter");
318+ std::vector<uint8_t> data;
319+ if (reportData.size() > 0) {
320+ data.assign(reportData.data(), reportData.data() + reportData.size());
321+ }
322+ HidDevice *profile = HidDevice::GetProfile();
323+ int32_t errorCode = profile->SendReport(id, data);
324+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
325+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
326+ }
327+ 
328+ void ReplyReport(::ohos::bluetooth::hid::ReportType type, int32_t id, ::taihe::array_view<uint8_t> reportData)
329+ {
330+ HILOGI("enter");
331+ std::vector<uint8_t> data;
332+ if (reportData.size() > 0) {
333+ data.assign(reportData.data(), reportData.data() + reportData.size());
334+ }
335+ HidDevice *profile = HidDevice::GetProfile();
336+ int32_t errorCode = profile->ReplyReport(static_cast<ReportType>(type.get_value()), id, data);
337+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
338+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
339+ }
340+ 
341+ bool RegisterHidDeviceSync(::ohos::bluetooth::hid::HidDeviceSdp const& sdp,
342+ ::ohos::bluetooth::hid::HidDeviceQos const& inQos,
343+ ::ohos::bluetooth::hid::HidDeviceQos const& outQos)
344+ {
345+ HILOGI("enter");
346+ BluetoothHidDeviceSdp sdpSetting(
347+ bluetooth::SdpSetting(std::string(sdp.name), std::string(sdp.description),
348+ std::string(sdp.provider), sdp.subclass.get_value(),
349+ std::vector<uint8_t>(sdp.descriptors.data(), sdp.descriptors.data() + sdp.descriptors.size())));
350+ auto convertQos = [](::ohos::bluetooth::hid::HidDeviceQos const& qos) {
351+ int32_t serviceType = static_cast<int32_t>(ServiceType::SERVICE_BEST_EFFORT);
352+ if (qos.serviceType.has_value()) {
353+ serviceType = static_cast<int32_t>(qos.serviceType.value().get_key());
354+ }
355+ int32_t tokenRate = qos.tokenRate.value_or(0);
356+ int32_t tokenBucketSize = qos.tokenBucketSize.value_or(0);
357+ int32_t peakBandwidth = qos.peakBandwidth.value_or(0);
358+ int32_t latency = qos.latency.value_or(-1);
359+ int32_t delayVariation = qos.delayVariation.value_or(-1);
360+ return BluetoothHidDeviceQos(
361+ bluetooth::QosSetting(serviceType, tokenRate, tokenBucketSize,
362+ peakBandwidth, latency, delayVariation));
363+ };
364+ BluetoothHidDeviceQos inQosSetting = convertQos(inQos);
365+ BluetoothHidDeviceQos outQosSetting = convertQos(outQos);
366+ 
367+ HidDevice *profile = HidDevice::GetProfile();
368+ int32_t errorCode = profile->RegisterHidDevice(sdpSetting, inQosSetting, outQosSetting);
369+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
370+ return errorCode == BT_NO_ERROR;
371+ }
372+ 
373+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(::taihe::string_view deviceId)
374+ {
375+ HILOGD("enter");
376+ std::string remoteAddr = std::string(deviceId);
377+ bool checkRet = CheckDeviceIdParam(remoteAddr);
378+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
379+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
380+ 
381+ HidDevice *profile = HidDevice::GetProfile();
382+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
383+ int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
384+ int32_t errorCode = profile->GetConnectionState(device, state);
385+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
386+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
387+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
388+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
389+ }
390+ 
391+ ::taihe::array<::taihe::string> GetConnectedDevices()
392+ {
393+ HILOGI("enter");
394+ HidDevice *profile = HidDevice::GetProfile();
395+ std::vector<BluetoothRemoteDevice> devices;
396+ int errorCode = profile->GetConnectedDevices(devices);
397+ HILOGI("errorCode:%{public}s, devices size:%{public}zu",
398+ GetTaiheErrMsg(errorCode).c_str(), devices.size());
399+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, taihe::array<taihe::string>{});
400+ 
401+ std::vector<std::string> deviceVector;
402+ for (auto &device : devices) {
403+ deviceVector.push_back(device.GetDeviceAddr());
404+ }
405+ return deviceVector.empty() ? taihe::array<taihe::string>{}
406+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
407+ }
408+ 
409+ ::ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(::taihe::string_view deviceId)
410+ {
411+ HILOGD("start");
412+ std::string remoteAddr = std::string(deviceId);
413+ bool checkRet = CheckDeviceIdParam(remoteAddr);
414+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
415+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
416+ 
417+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
418+ HidDevice *profile = HidDevice::GetProfile();
419+ int strategy = 0;
420+ int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);
421+ HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);
422+ TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err,
423+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
424+ return ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
425+ }
426+ 
427+ void SetConnectionStrategySync(::taihe::string_view deviceId,
428+ ::ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
429+ {
430+ HILOGD("start");
431+ std::string remoteAddr = std::string(deviceId);
432+ int32_t connStrategy = strategy.get_value();
433+ bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
434+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
435+ 
436+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
437+ HidDevice *profile = HidDevice::GetProfile();
438+ int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);
439+ HILOGI("err: %{public}d", err);
440+ TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);
441+ }
442+ 
443+private:
444+ std::shared_ptr<TaiheBluetoothHidDeviceObserver> observer_ = nullptr;
445+};
446+ 
447+::ohos::bluetooth::hid::HidDeviceProfile CreateHidDeviceProfile()
448+{
449+ return taihe::make_holder<HidDeviceProfileImpl, ::ohos::bluetooth::hid::HidDeviceProfile>();
450+}
166} // namespace Bluetooth451} // namespace Bluetooth
167} // namespace OHOS452} // namespace OHOS
168 453 
169// Since these macros are auto-generate, lint will cause false positive.454// Since these macros are auto-generate, lint will cause false positive.
170// NOLINTBEGIN455// NOLINTBEGIN
171TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile);456TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile);
457+TH_EXPORT_CPP_API_CreateHidDeviceProfile(OHOS::Bluetooth::CreateHidDeviceProfile);
172// NOLINTEND458// NOLINTEND
Aframeworks/ets/taihe/bluetooth_hid/src/taihe_bluetooth_hid_device_observer.cpp+129-0
@@ -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+{}
33+ 
34+void TaiheBluetoothHidDeviceObserver::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state)
35+{
36+ std::shared_lock<std::shared_mutex> guard(connectionStateChange_.lock_);
37+ HILOGD("enter, remote device address: %{public}s, state: %{public}d",
38+ GET_ENCRYPT_ADDR(device), state);
39+ ::taihe::string deviceId_(device.GetDeviceAddr());
40+ int32_t profileConnectionState = TaiheUtils::GetProfileConnectionState(state);
41+ auto state_ = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState);
42+ auto taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam {
43+ .deviceId = deviceId_,
44+ .state = state_,
45+ .cause = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(0),
46+ };
47+ for (auto callback : connectionStateChange_.callbackVec_) {
48+ if (callback) {
49+ (*callback)(taiheResult);
50+ }
51+ }
52+}
53+ 
54+void TaiheBluetoothHidDeviceObserver::OnGetReport(int type, int id, uint16_t bufferSize)
55+{
56+ std::shared_lock<std::shared_mutex> guard(getReport_.lock_);
57+ HILOGD("type: %{public}d, id: %{public}d, bufferSize: %{public}d", type, id, bufferSize);
58+ auto taiheResult = ::ohos::bluetooth::hid::GetReportData {
59+ .type = ::ohos::bluetooth::hid::ReportType::from_value(type),
60+ .id = id,
61+ .bufferSize = static_cast<int32_t>(bufferSize),
62+ };
63+ for (auto callback : getReport_.callbackVec_) {
64+ if (callback) {
65+ (*callback)(taiheResult);
66+ }
67+ }
68+}
69+ 
70+void TaiheBluetoothHidDeviceObserver::OnSetProtocol(int protocol)
71+{
72+ std::shared_lock<std::shared_mutex> guard(setProtocol_.lock_);
73+ HILOGD("protocol: %{public}d", protocol);
74+ auto taiheResult = ::ohos::bluetooth::hid::ProtocolData {
75+ .protocol = ::ohos::bluetooth::hid::ProtocolType::from_value(protocol),
76+ };
77+ for (auto callback : setProtocol_.callbackVec_) {
78+ if (callback) {
79+ (*callback)(taiheResult);
80+ }
81+ }
82+}
83+ 
84+void TaiheBluetoothHidDeviceObserver::OnInterruptDataReceived(int id, const std::vector<uint8_t> &data)
85+{
86+ std::shared_lock<std::shared_mutex> guard(interruptDataReceived_.lock_);
87+ HILOGD("id: %{public}d, data size: %{public}zu", id, data.size());
88+ auto taiheResult = ::ohos::bluetooth::hid::InterruptData {
89+ .id = id,
90+ .data = data.empty() ? taihe::array<uint8_t>{}
91+ : taihe::array<uint8_t>(taihe::copy_data_t{}, data.data(), data.size()),
92+ };
93+ for (auto callback : interruptDataReceived_.callbackVec_) {
94+ if (callback) {
95+ (*callback)(taiheResult);
96+ }
97+ }
98+}
99+ 
100+void TaiheBluetoothHidDeviceObserver::OnSetReport(int type, int id, const std::vector<uint8_t> &data)
101+{
102+ std::shared_lock<std::shared_mutex> guard(setReport_.lock_);
103+ HILOGD("type: %{public}d, id: %{public}d, data size: %{public}zu", type, id, data.size());
104+ auto taiheResult = ::ohos::bluetooth::hid::SetReportData {
105+ .type = ::ohos::bluetooth::hid::ReportType::from_value(type),
106+ .id = id,
107+ .data = data.empty() ? taihe::array<uint8_t>{}
108+ : taihe::array<uint8_t>(taihe::copy_data_t{}, data.data(), data.size()),
109+ };
110+ for (auto callback : setReport_.callbackVec_) {
111+ if (callback) {
112+ (*callback)(taiheResult);
113+ }
114+ }
115+}
116+ 
117+void TaiheBluetoothHidDeviceObserver::OnVirtualCableUnplug()
118+{
119+ std::shared_lock<std::shared_mutex> guard(virtualCableUnplug_.lock_);
120+ HILOGD("enter");
121+ for (auto callback : virtualCableUnplug_.callbackVec_) {
122+ if (callback) {
123+ (*callback)();
124+ }
125+ }
126+}
127+ 
128+} // namespace Bluetooth
129+} // namespace OHOS
Aframeworks/ets/taihe/bluetooth_map/BUILD.gn+120-0
@@ -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+}
Aframeworks/ets/taihe/bluetooth_map/idl/ohos.bluetooth.map.taihe+47-0
@@ -0,0 +1,47 @@
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+@!namespace("@ohos.bluetooth.map", "map")
17+@!sts_inject("""
18+static { loadLibraryWithPermissionCheck("bluetoothMap_taihe_native.z", "@ohos.bluetooth.map") }
19+""")
20+from ohos.bluetooth.baseProfile use BaseProfile;
21+from ohos.bluetooth.constant use AccessAuthorization;
22+@!sts_inject_into_module("import {baseProfile} from './@ohos.bluetooth.baseProfile';")
23+ 
24+function CreateMapMseProfile(): MapMseProfile;
25+interface MapMseProfile : BaseProfile {
26+ @!sts_inject_into_class("""on(type: String, callback: object): void {
27+ if (type === "connectionStateChange") {
28+ this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void);
29+ }
30+ }
31+ """)
32+ 
33+ @!sts_inject_into_class("""off(type: String, callback?: object): void {
34+ if (type === "connectionStateChange") {
35+ this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined);
36+ }
37+ }
38+ """)
39+ 
40+ @gen_promise("getMessageAccessAuthorization")
41+ GetMessageAccessAuthorizationSync(deviceId: String): AccessAuthorization;
42+ 
43+ @gen_promise("setMessageAccessAuthorization")
44+ SetMessageAccessAuthorizationSync(deviceId: String, authorization: AccessAuthorization): void;
45+ 
46+ Disconnect(deviceId: String): void;
47+}
Aframeworks/ets/taihe/bluetooth_map/include/taihe_bluetooth_map_mse_observer.h+43-0
@@ -0,0 +1,43 @@
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_MAP_MSE_OBSERVER_H_
17+#define TAIHE_BLUETOOTH_MAP_MSE_OBSERVER_H_
18+ 
19+#include <shared_mutex>
20+#include "bluetooth_map_mse.h"
21+#include "ohos.bluetooth.map.proj.hpp"
22+#include "ohos.bluetooth.map.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 TaiheBluetoothMapMseObserver : public MapMseObserver {
31+public:
32+ void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int32_t state, int32_t cause) override;
33+ 
34+ TaiheBluetoothMapMseObserver();
35+ ~TaiheBluetoothMapMseObserver() override = default;
36+ 
37+private:
38+ friend class MapMseProfileImpl;
39+ EventModule<void(::ohos::bluetooth::baseProfile::StateChangeParam const& data)> connectionStateChange_;
40+};
41+} // namespace Bluetooth
42+} // namespace OHOS
43+#endif // TAIHE_BLUETOOTH_MAP_MSE_OBSERVER_H_
Aframeworks/ets/taihe/bluetooth_map/src/ohos.bluetooth.map.impl.cpp+192-0
@@ -0,0 +1,192 @@
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_map_impl_bluetooth"
18+#endif
19+ 
20+#include "ohos.bluetooth.map.proj.hpp"
21+#include "ohos.bluetooth.map.impl.hpp"
22+#include "taihe/runtime.hpp"
23+#include "stdexcept"
24+#include "bluetooth_errorcode.h"
25+#include "bluetooth_map_mse.h"
26+#include "bluetooth_log.h"
27+#include "bluetooth_utils.h"
28+#include "taihe_bluetooth_map_mse_observer.h"
29+#include "taihe_bluetooth_utils.h"
30+#include "taihe_event_module.h"
31+ 
32+namespace OHOS {
33+namespace Bluetooth {
34+ 
35+class MapMseProfileImpl {
36+public:
37+ MapMseProfileImpl()
38+ {
39+ observer_ = std::make_shared<TaiheBluetoothMapMseObserver>();
40+ MapMse *profile = MapMse::GetProfile();
41+ profile->RegisterObserver(observer_);
42+ }
43+ 
44+ void OnConnectionStateChange(::taihe::callback_view<void(
45+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)> callback)
46+ {
47+ if (observer_) {
48+ observer_->connectionStateChange_.RegisterEvent(callback);
49+ }
50+ }
51+ 
52+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
53+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>> callback)
54+ {
55+ if (observer_) {
56+ observer_->connectionStateChange_.DeregisterEvent(callback);
57+ }
58+ }
59+ 
60+ ::ohos::bluetooth::constant::AccessAuthorization GetMessageAccessAuthorizationSync(::taihe::string_view deviceId)
61+ {
62+ HILOGD("enter");
63+ std::string remoteAddr = std::string(deviceId);
64+ bool checkRet = CheckDeviceIdParam(remoteAddr);
65+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
66+ ::ohos::bluetooth::constant::AccessAuthorization::from_value(0));
67+ 
68+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
69+ MapMse *profile = MapMse::GetProfile();
70+ int32_t accessAuthorization = 0;
71+ int32_t errorCode = profile->GetMessageAccessAuthorization(remoteDevice, accessAuthorization);
72+ HILOGI("errorCode: %{public}d, accessAuthorization: %{public}d", errorCode, accessAuthorization);
73+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
74+ ::ohos::bluetooth::constant::AccessAuthorization::from_value(accessAuthorization));
75+ return ::ohos::bluetooth::constant::AccessAuthorization::from_value(accessAuthorization);
76+ }
77+ 
78+ void SetMessageAccessAuthorizationSync(::taihe::string_view deviceId,
79+ ::ohos::bluetooth::constant::AccessAuthorization authorization)
80+ {
81+ HILOGD("enter");
82+ std::string remoteAddr = std::string(deviceId);
83+ bool checkRet = CheckDeviceIdParam(remoteAddr);
84+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
85+ 
86+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
87+ MapMse *profile = MapMse::GetProfile();
88+ int32_t errorCode = profile->SetMessageAccessAuthorization(remoteDevice, authorization.get_value());
89+ HILOGI("errorCode: %{public}d", errorCode);
90+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
91+ }
92+ 
93+ void Disconnect(::taihe::string_view deviceId)
94+ {
95+ HILOGD("enter");
96+ std::string remoteAddr = std::string(deviceId);
97+ bool checkRet = CheckDeviceIdParam(remoteAddr);
98+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
99+ 
100+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
101+ MapMse *profile = MapMse::GetProfile();
102+ int32_t errorCode = profile->Disconnect(remoteDevice);
103+ HILOGI("errorCode: %{public}d", errorCode);
104+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
105+ }
106+ 
107+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(::taihe::string_view deviceId)
108+ {
109+ HILOGD("enter");
110+ std::string remoteAddr = std::string(deviceId);
111+ bool checkRet = CheckDeviceIdParam(remoteAddr);
112+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
113+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
114+ 
115+ MapMse *profile = MapMse::GetProfile();
116+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
117+ int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
118+ int32_t errorCode = profile->GetDeviceState(device, state);
119+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
120+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
121+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
122+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
123+ }
124+ 
125+ ::taihe::array<::taihe::string> GetConnectedDevices()
126+ {
127+ HILOGI("enter");
128+ MapMse *profile = MapMse::GetProfile();
129+ std::vector<int32_t> states = {static_cast<int32_t>(BTConnectState::CONNECTED)};
130+ std::vector<BluetoothRemoteDevice> devices;
131+ int32_t errorCode = profile->GetDevicesByStates(states, devices);
132+ HILOGI("errorCode: %{public}d, devices size: %{public}zu", errorCode, devices.size());
133+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, taihe::array<::taihe::string>{});
134+ 
135+ std::vector<std::string> deviceVector;
136+ for (auto &device : devices) {
137+ deviceVector.push_back(device.GetDeviceAddr());
138+ }
139+ return deviceVector.empty() ? taihe::array<::taihe::string>{}
140+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
141+ }
142+ 
143+ ::ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(::taihe::string_view deviceId)
144+ {
145+ HILOGD("enter");
146+ std::string remoteAddr = std::string(deviceId);
147+ bool checkRet = CheckDeviceIdParam(remoteAddr);
148+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
149+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
150+ 
151+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
152+ MapMse *profile = MapMse::GetProfile();
153+ int32_t strategy = 0;
154+ int32_t errorCode = profile->GetConnectionStrategy(remoteDevice, strategy);
155+ HILOGI("errorCode: %{public}d, strategy: %{public}d", errorCode, strategy);
156+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
157+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
158+ return ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
159+ }
160+ 
161+ void SetConnectionStrategySync(::taihe::string_view deviceId,
162+ ::ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
163+ {
164+ HILOGD("enter");
165+ std::string remoteAddr = std::string(deviceId);
166+ int32_t connStrategy = strategy.get_value();
167+ bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
168+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
169+ 
170+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
171+ MapMse *profile = MapMse::GetProfile();
172+ int32_t errorCode = profile->SetConnectionStrategy(remoteDevice, connStrategy);
173+ HILOGI("errorCode: %{public}d", errorCode);
174+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
175+ }
176+ 
177+private:
178+ std::shared_ptr<TaiheBluetoothMapMseObserver> observer_ = nullptr;
179+};
180+ 
181+::ohos::bluetooth::map::MapMseProfile CreateMapMseProfile()
182+{
183+ return taihe::make_holder<MapMseProfileImpl, ::ohos::bluetooth::map::MapMseProfile>();
184+}
185+ 
186+} // namespace Bluetooth
187+} // namespace OHOS
188+ 
189+// Since these macros are auto-generate, lint will cause false positive.
190+// NOLINTBEGIN
191+TH_EXPORT_CPP_API_CreateMapMseProfile(OHOS::Bluetooth::CreateMapMseProfile);
192+// NOLINTEND
Aframeworks/ets/taihe/bluetooth_map/src/taihe_bluetooth_map_mse_observer.cpp+56-0
@@ -0,0 +1,56 @@
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_map_mse_observer"
18+#endif
19+ 
20+#include "ohos.bluetooth.map.proj.hpp"
21+#include "ohos.bluetooth.map.impl.hpp"
22+#include "bluetooth_utils.h"
23+#include "bluetooth_log.h"
24+#include "taihe_bluetooth_map_mse_observer.h"
25+#include "taihe/runtime.hpp"
26+#include "taihe_bluetooth_utils.h"
27+#include "stdexcept"
28+ 
29+namespace OHOS {
30+namespace Bluetooth {
31+ 
32+TaiheBluetoothMapMseObserver::TaiheBluetoothMapMseObserver()
33+{}
34+ 
35+void TaiheBluetoothMapMseObserver::OnConnectionStateChanged(
36+ const BluetoothRemoteDevice &device, int32_t state, int32_t cause)
37+{
38+ std::shared_lock<std::shared_mutex> guard(connectionStateChange_.lock_);
39+ HILOGD("enter, remote device: %{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 taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam {
44+ .deviceId = deviceId_,
45+ .state = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState),
46+ .cause = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(cause),
47+ };
48+ for (auto callback : connectionStateChange_.callbackVec_) {
49+ if (callback) {
50+ (*callback)(taiheResult);
51+ }
52+ }
53+}
54+ 
55+} // namespace Bluetooth
56+} // namespace OHOS
Aframeworks/ets/taihe/bluetooth_opp/BUILD.gn+120-0
@@ -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_opp_taihe") {
21+ sources = [
22+ "idl/ohos.bluetooth.opp.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_opp = "$taihe_file_path/out/$subsystem_name/$part_name/opp"
32+ 
33+ohos_taihe("run_taihe") {
34+ taihe_generated_file_path = "${taihe_generated_file_path_opp}"
35+ deps = [ ":bluetooth_opp_taihe" ]
36+ outputs = [
37+ "$taihe_generated_file_path/src/ohos.bluetooth.opp.ani.cpp",
38+ "$taihe_generated_file_path/src/ohos.bluetooth.opp.abi.c",
39+ ]
40+}
41+ 
42+taihe_shared_library("bluetoothOpp_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_opp}"
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.opp.impl.cpp",
72+ "src/taihe_bluetooth_opp_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("bluetoothOpp_abc") {
99+ base_url = "${taihe_generated_file_path_opp}"
100+ files = [ "${taihe_generated_file_path_opp}/@ohos.bluetooth.opp.ets" ]
101+ is_boot_abc = "True"
102+ device_dst_file = "/system/framework/bluetoothOpp_abc.abc"
103+ dependencies = [ ":run_taihe" ]
104+}
105+ 
106+ohos_prebuilt_etc("bluetoothOpp_etc") {
107+ source = "$target_out_dir/bluetoothOpp_abc.abc"
108+ module_install_dir = "framework"
109+ part_name = "$part_name"
110+ subsystem_name = "$subsystem_name"
111+ deps = [ ":bluetoothOpp_abc" ]
112+}
113+ 
114+group("bluetoothOpp_taihe") {
115+ deps = [
116+ ":bluetoothOpp_etc",
117+ ":bluetoothOpp_taihe_native"
118+ ]
119+ # deps = [":run_taihe"]
120+}
Aframeworks/ets/taihe/bluetooth_opp/idl/ohos.bluetooth.opp.taihe+92-0
@@ -0,0 +1,92 @@
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+@!namespace("@ohos.bluetooth.opp", "opp")
17+@!sts_inject("""
18+static { loadLibraryWithPermissionCheck("bluetoothMap_taihe_native.z", "@ohos.bluetooth.opp") }
19+""")
20+from ohos.bluetooth.baseProfile use BaseProfile;
21+from ohos.bluetooth.constant use AccessAuthorization;
22+@!sts_inject_into_module("import {baseProfile} from './@ohos.bluetooth.baseProfile';")
23+ 
24+function CreateOppServerProfile(): OppServerProfile;
25+interface OppServerProfile : BaseProfile {
26+ @!sts_inject_into_class("""on(type: String, callback: object): void {
27+ if (type === "connectionStateChange") {
28+ this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void);
29+ }
30+ }
31+ """)
32+ 
33+ @!sts_inject_into_class("""off(type: String, callback?: object): void {
34+ if (type === "connectionStateChange") {
35+ this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined);
36+ }
37+ }
38+ """)
39+ 
40+ @gen_promise("setIncomingFileConfirmation")
41+ SetIncomingFileConfirmationSync(accept: bool, fileFd: i32): void;
42+ 
43+ @gen_promise("setLastReceivedFileUri")
44+ SetLastReceivedFileUriSync(uri: String): void;
45+ 
46+ @gen_promise("getCurrentTransferInformation")
47+ GetCurrentTransferInformationSync(): OppTransferInformation;
48+ 
49+ @gen_promise("cancelTransfer")
50+ CancelTransferSync(): void;
51+ 
52+ OnTransferStateChange(callback: (data: OppTransferInformation) => void): void;
53+ OffTransferStateChange(callback: Optional<(data: OppTransferInformation) => void>): void;
54+ 
55+ OnReceiveIncomingFile(callback: (data: OppTransferInformation) => void): void;
56+ OffReceiveIncomingFile(callback: Optional<(data: OppTransferInformation) => void>): void;
57+}
58+ 
59+struct OppTransferInformation {
60+ filePath: String;
61+ remoteDeviceName: String;
62+ remoteDeviceId: String;
63+ direction: DirectionType;
64+ status: TransferStatus;
65+ result: TransferResult;
66+ currentBytes: i64;
67+ totalBytes: i64;
68+ currentCount: i32;
69+ totalCount: i32;
70+}
71+ 
72+enum DirectionType: i32 {
73+ OUTBOUND = 0,
74+ INBOUND = 1
75+}
76+ 
77+enum TransferStatus: i32 {
78+ PENDING = 0,
79+ RUNNING = 1,
80+ FINISH = 2
81+}
82+ 
83+enum TransferResult: i32 {
84+ SUCCESS = 0,
85+ ERROR_UNSUPPORTED_TYPE = 1,
86+ ERROR_BAD_REQUEST = 2,
87+ ERROR_NOT_ACCEPTABLE = 3,
88+ ERROR_CANCELED = 4,
89+ ERROR_CONNECTION_FAILED = 5,
90+ ERROR_TRANSFER_FAILED = 6,
91+ ERROR_UNKNOWN = 7
92+}
Aframeworks/ets/taihe/bluetooth_opp/include/taihe_bluetooth_opp_observer.h+45-0
@@ -0,0 +1,45 @@
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_OPP_OBSERVER_H_
17+#define TAIHE_BLUETOOTH_OPP_OBSERVER_H_
18+ 
19+#include <shared_mutex>
20+#include "bluetooth_opp.h"
21+#include "ohos.bluetooth.opp.proj.hpp"
22+#include "ohos.bluetooth.opp.impl.hpp"
23+#include "taihe/runtime.hpp"
24+#include "taihe_event_module.h"
25+ 
26+namespace OHOS {
27+namespace Bluetooth {
28+ 
29+class TaiheBluetoothOppObserver : public OppObserver {
30+public:
31+ TaiheBluetoothOppObserver();
32+ ~TaiheBluetoothOppObserver() override = default;
33+ 
34+ void OnReceiveIncomingFileChanged(const BluetoothOppTransferInformation &transferInformation) override;
35+ void OnTransferStateChanged(const BluetoothOppTransferInformation &transferInformation) override;
36+ 
37+private:
38+ friend class OppServerProfileImpl;
39+ EventModule<void(::ohos::bluetooth::opp::OppTransferInformation const& data)> receiveIncomingFile_;
40+ EventModule<void(::ohos::bluetooth::opp::OppTransferInformation const& data)> transferStateChange_;
41+};
42+ 
43+} // namespace Bluetooth
44+} // namespace OHOS
45+#endif // TAIHE_BLUETOOTH_OPP_OBSERVER_H_
Aframeworks/ets/taihe/bluetooth_opp/src/ohos.bluetooth.opp.impl.cpp+221-0
@@ -0,0 +1,221 @@
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_opp_impl_bluetooth"
18+#endif
19+ 
20+#include "ohos.bluetooth.opp.proj.hpp"
21+#include "ohos.bluetooth.opp.impl.hpp"
22+#include "taihe/runtime.hpp"
23+#include "bluetooth_opp.h"
24+#include "bluetooth_errorcode.h"
25+#include "bluetooth_log.h"
26+#include "bluetooth_utils.h"
27+#include "taihe_bluetooth_opp_observer.h"
28+#include "taihe_bluetooth_utils.h"
29+#include "taihe_event_module.h"
30+ 
31+namespace OHOS {
32+namespace Bluetooth {
33+ 
34+namespace {
35+::ohos::bluetooth::opp::OppTransferInformation ConvertTransferInformation(
36+ const BluetoothOppTransferInformation &info)
37+{
38+ return ::ohos::bluetooth::opp::OppTransferInformation{
39+ ::taihe::string(info.GetFilePath()),
40+ ::taihe::string(info.GetDeviceName()),
41+ ::taihe::string(info.GetDeviceAddress()),
42+ ::ohos::bluetooth::opp::DirectionType::from_value(info.GetDirection()),
43+ ::ohos::bluetooth::opp::TransferStatus::from_value(info.GetStatus()),
44+ ::ohos::bluetooth::opp::TransferResult::from_value(info.GetResult()),
45+ static_cast<int64_t>(info.GetCurrentBytes()),
46+ static_cast<int64_t>(info.GetTotalBytes()),
47+ info.GetCurrentCount(),
48+ info.GetTotalCount(),
49+ };
50+}
51+} // namespace
52+ 
53+class OppServerProfileImpl {
54+public:
55+ OppServerProfileImpl()
56+ {
57+ observer_ = std::make_shared<TaiheBluetoothOppObserver>();
58+ Opp *profile = Opp::GetProfile();
59+ profile->RegisterObserver(observer_);
60+ }
61+ 
62+ void SetIncomingFileConfirmationSync(bool accept, int32_t fileFd)
63+ {
64+ HILOGI("enter, fileFd: %{public}d", fileFd);
65+ Opp *profile = Opp::GetProfile();
66+ int32_t errorCode = profile->SetIncomingFileConfirmation(accept, fileFd);
67+ HILOGI("errorCode: %{public}d", errorCode);
68+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
69+ }
70+ 
71+ void SetLastReceivedFileUriSync(::taihe::string_view uri)
72+ {
73+ HILOGI("enter");
74+ std::string uriStr = std::string(uri);
75+ Opp *profile = Opp::GetProfile();
76+ int32_t errorCode = profile->SetLastReceivedFileUri(uriStr);
77+ HILOGI("errorCode: %{public}d", errorCode);
78+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
79+ }
80+ 
81+ ::ohos::bluetooth::opp::OppTransferInformation GetCurrentTransferInformationSync()
82+ {
83+ HILOGI("enter");
84+ Opp *profile = Opp::GetProfile();
85+ BluetoothOppTransferInformation information;
86+ int32_t errorCode = profile->GetCurrentTransferInformation(information);
87+ HILOGI("errorCode: %{public}d", errorCode);
88+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
89+ (::ohos::bluetooth::opp::OppTransferInformation{
90+ ::taihe::string(""), ::taihe::string(""), ::taihe::string(""),
91+ ::ohos::bluetooth::opp::DirectionType::from_value(0),
92+ ::ohos::bluetooth::opp::TransferStatus::from_value(0),
93+ ::ohos::bluetooth::opp::TransferResult::from_value(0),
94+ 0, 0, 0, 0,
95+ }));
96+ return ConvertTransferInformation(information);
97+ }
98+ 
99+ void CancelTransferSync()
100+ {
101+ HILOGI("enter");
102+ Opp *profile = Opp::GetProfile();
103+ bool result = false;
104+ int32_t errorCode = profile->CancelTransfer(result);
105+ HILOGI("errorCode: %{public}d, result: %{public}d", errorCode, result);
106+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
107+ }
108+ 
109+ void OnTransferStateChange(::taihe::callback_view<void(
110+ ::ohos::bluetooth::opp::OppTransferInformation const& data)> callback)
111+ {
112+ if (observer_) {
113+ observer_->transferStateChange_.RegisterEvent(callback);
114+ }
115+ }
116+ 
117+ void OffTransferStateChange(::taihe::optional_view<::taihe::callback<void(
118+ ::ohos::bluetooth::opp::OppTransferInformation const& data)>> callback)
119+ {
120+ if (observer_) {
121+ observer_->transferStateChange_.DeregisterEvent(callback);
122+ }
123+ }
124+ 
125+ void OnReceiveIncomingFile(::taihe::callback_view<void(
126+ ::ohos::bluetooth::opp::OppTransferInformation const& data)> callback)
127+ {
128+ if (observer_) {
129+ observer_->receiveIncomingFile_.RegisterEvent(callback);
130+ }
131+ }
132+ 
133+ void OffReceiveIncomingFile(::taihe::optional_view<::taihe::callback<void(
134+ ::ohos::bluetooth::opp::OppTransferInformation const& data)>> callback)
135+ {
136+ if (observer_) {
137+ observer_->receiveIncomingFile_.DeregisterEvent(callback);
138+ }
139+ }
140+ 
141+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(::taihe::string_view deviceId)
142+ {
143+ HILOGI("enter");
144+ std::string remoteAddr = std::string(deviceId);
145+ bool checkRet = CheckDeviceIdParam(remoteAddr);
146+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
147+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
148+ 
149+ Opp *profile = Opp::GetProfile();
150+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
151+ int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
152+ int32_t errorCode = profile->GetDeviceState(device, state);
153+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
154+ HILOGI("errorCode: %{public}d, profileState: %{public}d", errorCode, profileState);
155+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
156+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
157+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
158+ }
159+ 
160+ ::taihe::array<::taihe::string> GetConnectedDevices()
161+ {
162+ HILOGI("enter");
163+ Opp *profile = Opp::GetProfile();
164+ std::vector<int32_t> states = {static_cast<int32_t>(BTConnectState::CONNECTED)};
165+ std::vector<BluetoothRemoteDevice> devices;
166+ int32_t errorCode = profile->GetDevicesByStates(states, devices);
167+ HILOGI("errorCode: %{public}d, devices size: %{public}zu", errorCode, devices.size());
168+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, taihe::array<::taihe::string>{});
169+ 
170+ std::vector<std::string> deviceVector;
171+ for (auto &device : devices) {
172+ deviceVector.push_back(device.GetDeviceAddr());
173+ }
174+ return deviceVector.empty() ? taihe::array<::taihe::string>{}
175+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
176+ }
177+ 
178+ ::ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(::taihe::string_view deviceId)
179+ {
180+ HILOGW("OPP does not support GetConnectionStrategy");
181+ TAIHE_BT_ASSERT_RETURN(false, BT_ERR_API_NOT_SUPPORT,
182+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
183+ }
184+ 
185+ void SetConnectionStrategySync(::taihe::string_view deviceId,
186+ ::ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
187+ {
188+ HILOGW("OPP does not support SetConnectionStrategy");
189+ TAIHE_BT_ASSERT_RETURN_VOID(false, BT_ERR_API_NOT_SUPPORT);
190+ }
191+ 
192+ void OnConnectionStateChange(::taihe::callback_view<void(
193+ ::ohos::bluetooth::baseProfile::StateChangeParam const& info)> callback)
194+ {
195+ // OPP observer doesn't have OnConnectionStateChanged, accept but never publish
196+ connectionStateChange_.RegisterEvent(callback);
197+ }
198+ 
199+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
200+ ::ohos::bluetooth::baseProfile::StateChangeParam const& info)>> callback)
201+ {
202+ connectionStateChange_.DeregisterEvent(callback);
203+ }
204+ 
205+private:
206+ std::shared_ptr<TaiheBluetoothOppObserver> observer_ = nullptr;
207+ EventModule<void(::ohos::bluetooth::baseProfile::StateChangeParam const& data)> connectionStateChange_;
208+};
209+ 
210+::ohos::bluetooth::opp::OppServerProfile CreateOppServerProfile()
211+{
212+ return taihe::make_holder<OppServerProfileImpl, ::ohos::bluetooth::opp::OppServerProfile>();
213+}
214+ 
215+} // namespace Bluetooth
216+} // namespace OHOS
217+ 
218+// Since these macros are auto-generate, lint will cause false positive.
219+// NOLINTBEGIN
220+TH_EXPORT_CPP_API_CreateOppServerProfile(OHOS::Bluetooth::CreateOppServerProfile);
221+// NOLINTEND
Aframeworks/ets/taihe/bluetooth_opp/src/taihe_bluetooth_opp_observer.cpp+78-0
@@ -0,0 +1,78 @@
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_opp_observer"
18+#endif
19+ 
20+#include "ohos.bluetooth.opp.proj.hpp"
21+#include "ohos.bluetooth.opp.impl.hpp"
22+#include "bluetooth_log.h"
23+#include "taihe_bluetooth_opp_observer.h"
24+#include "taihe/runtime.hpp"
25+ 
26+namespace OHOS {
27+namespace Bluetooth {
28+ 
29+namespace {
30+::ohos::bluetooth::opp::OppTransferInformation ConvertTransferInformation(
31+ const BluetoothOppTransferInformation &info)
32+{
33+ return ::ohos::bluetooth::opp::OppTransferInformation{
34+ ::taihe::string(info.GetFilePath()),
35+ ::taihe::string(info.GetDeviceName()),
36+ ::taihe::string(info.GetDeviceAddress()),
37+ ::ohos::bluetooth::opp::DirectionType::from_value(info.GetDirection()),
38+ ::ohos::bluetooth::opp::TransferStatus::from_value(info.GetStatus()),
39+ ::ohos::bluetooth::opp::TransferResult::from_value(info.GetResult()),
40+ static_cast<int64_t>(info.GetCurrentBytes()),
41+ static_cast<int64_t>(info.GetTotalBytes()),
42+ info.GetCurrentCount(),
43+ info.GetTotalCount(),
44+ };
45+}
46+} // namespace
47+ 
48+TaiheBluetoothOppObserver::TaiheBluetoothOppObserver()
49+{}
50+ 
51+void TaiheBluetoothOppObserver::OnReceiveIncomingFileChanged(
52+ const BluetoothOppTransferInformation &transferInformation)
53+{
54+ std::shared_lock<std::shared_mutex> guard(receiveIncomingFile_.lock_);
55+ HILOGI("enter");
56+ auto taiheResult = ConvertTransferInformation(transferInformation);
57+ for (auto callback : receiveIncomingFile_.callbackVec_) {
58+ if (callback) {
59+ (*callback)(taiheResult);
60+ }
61+ }
62+}
63+ 
64+void TaiheBluetoothOppObserver::OnTransferStateChanged(
65+ const BluetoothOppTransferInformation &transferInformation)
66+{
67+ std::shared_lock<std::shared_mutex> guard(transferStateChange_.lock_);
68+ HILOGI("enter");
69+ auto taiheResult = ConvertTransferInformation(transferInformation);
70+ for (auto callback : transferStateChange_.callbackVec_) {
71+ if (callback) {
72+ (*callback)(taiheResult);
73+ }
74+ }
75+}
76+ 
77+} // namespace Bluetooth
78+} // namespace OHOS
Aframeworks/ets/taihe/bluetooth_pan/BUILD.gn+120-0
@@ -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_pan_taihe") {
21+ sources = [
22+ "idl/ohos.bluetooth.pan.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_pan = "$taihe_file_path/out/$subsystem_name/$part_name/pan"
32+ 
33+ohos_taihe("run_taihe") {
34+ taihe_generated_file_path = "${taihe_generated_file_path_pan}"
35+ deps = [ ":bluetooth_pan_taihe" ]
36+ outputs = [
37+ "$taihe_generated_file_path/src/ohos.bluetooth.pan.ani.cpp",
38+ "$taihe_generated_file_path/src/ohos.bluetooth.pan.abi.c",
39+ ]
40+}
41+ 
42+taihe_shared_library("bluetoothPan_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_pan}"
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.pan.impl.cpp",
72+ "src/taihe_bluetooth_pan_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("bluetoothPan_abc") {
99+ base_url = "${taihe_generated_file_path_pan}"
100+ files = [ "${taihe_generated_file_path_pan}/@ohos.bluetooth.pan.ets" ]
101+ is_boot_abc = "True"
102+ device_dst_file = "/system/framework/bluetoothPan_abc.abc"
103+ dependencies = [ ":run_taihe" ]
104+}
105+ 
106+ohos_prebuilt_etc("bluetoothPan_etc") {
107+ source = "$target_out_dir/bluetoothPan_abc.abc"
108+ module_install_dir = "framework"
109+ part_name = "$part_name"
110+ subsystem_name = "$subsystem_name"
111+ deps = [ ":bluetoothPan_abc" ]
112+}
113+ 
114+group("bluetoothPan_taihe") {
115+ deps = [
116+ ":bluetoothPan_etc",
117+ ":bluetoothPan_taihe_native"
118+ ]
119+ # deps = [":run_taihe"]
120+}
Aframeworks/ets/taihe/bluetooth_pan/idl/ohos.bluetooth.pan.taihe+44-0
@@ -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+@!namespace("@ohos.bluetooth.pan", "pan")
17+@!sts_inject("""
18+static { loadLibraryWithPermissionCheck("bluetoothPan_taihe_native.z", "@ohos.bluetooth.pan") }
19+""")
20+from ohos.bluetooth.baseProfile use BaseProfile;
21+@!sts_inject_into_module("import {baseProfile} from './@ohos.bluetooth.baseProfile';")
22+ 
23+function CreatePanProfile(): PanProfile;
24+interface PanProfile : BaseProfile {
25+ @!sts_inject_into_class("""on(type: String, callback: object): void {
26+ if (type === "connectionStateChange") {
27+ this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void);
28+ }
29+ }
30+ """)
31+ 
32+ @!sts_inject_into_class("""off(type: String, callback?: object): void {
33+ if (type === "connectionStateChange") {
34+ this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined);
35+ }
36+ }
37+ """)
38+ 
39+ Connect(deviceId: String): void;
40+ Disconnect(deviceId: String): void;
41+ IsTetheringOn(): bool;
42+ SetTethering(enable: bool): void;
43+ IsPanSupported(): bool;
44+}
Aframeworks/ets/taihe/bluetooth_pan/include/taihe_bluetooth_pan_observer.h+43-0
@@ -0,0 +1,43 @@
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_PAN_OBSERVER_H_
17+#define TAIHE_BLUETOOTH_PAN_OBSERVER_H_
18+ 
19+#include <shared_mutex>
20+#include "bluetooth_pan.h"
21+#include "ohos.bluetooth.pan.proj.hpp"
22+#include "ohos.bluetooth.pan.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 TaiheBluetoothPanObserver : public PanObserver {
31+public:
32+ void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state, int cause, int role) override;
33+ 
34+ TaiheBluetoothPanObserver();
35+ ~TaiheBluetoothPanObserver() override = default;
36+ 
37+private:
38+ friend class PanProfileImpl;
39+ EventModule<void(::ohos::bluetooth::baseProfile::StateChangeParam const& data)> connectionStateChange_;
40+};
41+} // namespace Bluetooth
42+} // namespace OHOS
43+#endif // TAIHE_BLUETOOTH_PAN_OBSERVER_H_
Aframeworks/ets/taihe/bluetooth_pan/src/ohos.bluetooth.pan.impl.cpp+208-0
@@ -0,0 +1,208 @@
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_pan_impl_bluetooth"
18+#endif
19+ 
20+#include "ohos.bluetooth.pan.proj.hpp"
21+#include "ohos.bluetooth.pan.impl.hpp"
22+#include "taihe/runtime.hpp"
23+#include "stdexcept"
24+#include "bluetooth_errorcode.h"
25+#include "bluetooth_pan.h"
26+#include "bluetooth_log.h"
27+#include "bluetooth_utils.h"
28+#include "taihe_bluetooth_pan_observer.h"
29+#include "taihe_bluetooth_utils.h"
30+#include "taihe_event_module.h"
31+ 
32+namespace OHOS {
33+namespace Bluetooth {
34+ 
35+class PanProfileImpl {
36+public:
37+ PanProfileImpl()
38+ {
39+ observer_ = std::make_shared<TaiheBluetoothPanObserver>();
40+ Pan *profile = Pan::GetProfile();
41+ profile->RegisterObserver(observer_);
42+ }
43+ 
44+ void Connect(::taihe::string_view deviceId)
45+ {
46+ HILOGD("enter");
47+ std::string remoteAddr = std::string(deviceId);
48+ bool checkRet = CheckDeviceIdParam(remoteAddr);
49+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
50+ 
51+ Pan *profile = Pan::GetProfile();
52+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
53+ int32_t errorCode = profile->Connect(device);
54+ HILOGI("errorCode: %{public}d", errorCode);
55+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
56+ }
57+ 
58+ void Disconnect(::taihe::string_view deviceId)
59+ {
60+ HILOGD("enter");
61+ std::string remoteAddr = std::string(deviceId);
62+ bool checkRet = CheckDeviceIdParam(remoteAddr);
63+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
64+ 
65+ Pan *profile = Pan::GetProfile();
66+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
67+ int32_t errorCode = profile->Disconnect(device);
68+ HILOGI("errorCode: %{public}d", errorCode);
69+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
70+ }
71+ 
72+ bool IsTetheringOn()
73+ {
74+ HILOGD("enter");
75+ Pan *profile = Pan::GetProfile();
76+ bool result = false;
77+ int32_t errorCode = profile->IsTetheringOn(result);
78+ HILOGI("errorCode: %{public}d, result: %{public}d", errorCode, result);
79+ if (errorCode == BT_ERR_INTERNAL_ERROR) {
80+ return false;
81+ }
82+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, false);
83+ return result;
84+ }
85+ 
86+ void SetTethering(bool enable)
87+ {
88+ HILOGD("enter, enable: %{public}d", enable);
89+ Pan *profile = Pan::GetProfile();
90+ int32_t errorCode = profile->SetTethering(enable);
91+ HILOGI("errorCode: %{public}d", errorCode);
92+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
93+ }
94+ 
95+ bool IsPanSupported()
96+ {
97+ HILOGD("enter");
98+ Pan *profile = Pan::GetProfile();
99+ bool result = false;
100+ int32_t errorCode = profile->IsPanSupported(result);
101+ HILOGI("errorCode: %{public}d, result: %{public}d", errorCode, result);
102+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, false);
103+ return result;
104+ }
105+ 
106+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(::taihe::string_view deviceId)
107+ {
108+ HILOGD("enter");
109+ std::string remoteAddr = std::string(deviceId);
110+ bool checkRet = CheckDeviceIdParam(remoteAddr);
111+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
112+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
113+ 
114+ Pan *profile = Pan::GetProfile();
115+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
116+ int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
117+ int32_t errorCode = profile->GetDeviceState(device, state);
118+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
119+ HILOGI("errorCode: %{public}d, profileState: %{public}d", errorCode, profileState);
120+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
121+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
122+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
123+ }
124+ 
125+ ::taihe::array<::taihe::string> GetConnectedDevices()
126+ {
127+ HILOGI("enter");
128+ Pan *profile = Pan::GetProfile();
129+ std::vector<int32_t> states = {static_cast<int32_t>(BTConnectState::CONNECTED)};
130+ std::vector<BluetoothRemoteDevice> devices;
131+ int32_t errorCode = profile->GetDevicesByStates(states, devices);
132+ HILOGI("errorCode: %{public}d, devices size: %{public}zu", errorCode, devices.size());
133+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, taihe::array<::taihe::string>{});
134+ 
135+ std::vector<std::string> deviceVector;
136+ for (auto &device : devices) {
137+ deviceVector.push_back(device.GetDeviceAddr());
138+ }
139+ return deviceVector.empty() ? taihe::array<::taihe::string>{}
140+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
141+ }
142+ 
143+ ::ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(::taihe::string_view deviceId)
144+ {
145+ HILOGD("enter");
146+ std::string remoteAddr = std::string(deviceId);
147+ bool checkRet = CheckDeviceIdParam(remoteAddr);
148+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
149+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
150+ 
151+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
152+ Pan *profile = Pan::GetProfile();
153+ int32_t strategy = 0;
154+ int32_t errorCode = profile->GetConnectStrategy(remoteDevice, strategy);
155+ HILOGI("errorCode: %{public}d, strategy: %{public}d", errorCode, strategy);
156+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
157+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
158+ return ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
159+ }
160+ 
161+ void SetConnectionStrategySync(::taihe::string_view deviceId,
162+ ::ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
163+ {
164+ HILOGD("enter");
165+ std::string remoteAddr = std::string(deviceId);
166+ int32_t connStrategy = strategy.get_value();
167+ bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
168+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
169+ 
170+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
171+ Pan *profile = Pan::GetProfile();
172+ int32_t errorCode = profile->SetConnectStrategy(remoteDevice, connStrategy);
173+ HILOGI("errorCode: %{public}d", errorCode);
174+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
175+ }
176+ 
177+ void OnConnectionStateChange(::taihe::callback_view<void(
178+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)> callback)
179+ {
180+ if (observer_) {
181+ observer_->connectionStateChange_.RegisterEvent(callback);
182+ }
183+ }
184+ 
185+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
186+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>> callback)
187+ {
188+ if (observer_) {
189+ observer_->connectionStateChange_.DeregisterEvent(callback);
190+ }
191+ }
192+ 
193+private:
194+ std::shared_ptr<TaiheBluetoothPanObserver> observer_ = nullptr;
195+};
196+ 
197+::ohos::bluetooth::pan::PanProfile CreatePanProfile()
198+{
199+ return taihe::make_holder<PanProfileImpl, ::ohos::bluetooth::pan::PanProfile>();
200+}
201+ 
202+} // namespace Bluetooth
203+} // namespace OHOS
204+ 
205+// Since these macros are auto-generate, lint will cause false positive.
206+// NOLINTBEGIN
207+TH_EXPORT_CPP_API_CreatePanProfile(OHOS::Bluetooth::CreatePanProfile);
208+// NOLINTEND
Aframeworks/ets/taihe/bluetooth_pan/src/taihe_bluetooth_pan_observer.cpp+56-0
@@ -0,0 +1,56 @@
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_pan_observer"
18+#endif
19+ 
20+#include "ohos.bluetooth.pan.proj.hpp"
21+#include "ohos.bluetooth.pan.impl.hpp"
22+#include "bluetooth_utils.h"
23+#include "bluetooth_log.h"
24+#include "taihe_bluetooth_pan_observer.h"
25+#include "taihe/runtime.hpp"
26+#include "taihe_bluetooth_utils.h"
27+#include "stdexcept"
28+ 
29+namespace OHOS {
30+namespace Bluetooth {
31+ 
32+TaiheBluetoothPanObserver::TaiheBluetoothPanObserver()
33+{}
34+ 
35+void TaiheBluetoothPanObserver::OnConnectionStateChanged(
36+ const BluetoothRemoteDevice &device, int state, int cause, int role)
37+{
38+ std::shared_lock<std::shared_mutex> guard(connectionStateChange_.lock_);
39+ HILOGD("enter, remote device: %{public}s, state: %{public}d, cause: %{public}d, role: %{public}d",
40+ GET_ENCRYPT_ADDR(device), state, cause, role);
41+ ::taihe::string deviceId_(device.GetDeviceAddr());
42+ int32_t profileConnectionState = TaiheUtils::GetProfileConnectionState(state);
43+ auto taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam {
44+ .deviceId = deviceId_,
45+ .state = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState),
46+ .cause = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(cause),
47+ };
48+ for (auto callback : connectionStateChange_.callbackVec_) {
49+ if (callback) {
50+ (*callback)(taiheResult);
51+ }
52+ }
53+}
54+ 
55+} // namespace Bluetooth
56+} // namespace OHOS
Aframeworks/ets/taihe/bluetooth_pbap/BUILD.gn+120-0
@@ -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_pbap_taihe") {
21+ sources = [
22+ "idl/ohos.bluetooth.pbap.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_pbap = "$taihe_file_path/out/$subsystem_name/$part_name/pbap"
32+ 
33+ohos_taihe("run_taihe") {
34+ taihe_generated_file_path = "${taihe_generated_file_path_pbap}"
35+ deps = [ ":bluetooth_pbap_taihe" ]
36+ outputs = [
37+ "$taihe_generated_file_path/src/ohos.bluetooth.pbap.ani.cpp",
38+ "$taihe_generated_file_path/src/ohos.bluetooth.pbap.abi.c",
39+ ]
40+}
41+ 
42+taihe_shared_library("bluetoothPbap_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_pbap}"
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.pbap.impl.cpp",
72+ "src/taihe_bluetooth_pbap_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("bluetoothPbap_abc") {
99+ base_url = "${taihe_generated_file_path_pbap}"
100+ files = [ "${taihe_generated_file_path_pbap}/@ohos.bluetooth.pbap.ets" ]
101+ is_boot_abc = "True"
102+ device_dst_file = "/system/framework/bluetoothPbap_abc.abc"
103+ dependencies = [ ":run_taihe" ]
104+}
105+ 
106+ohos_prebuilt_etc("bluetoothPbap_etc") {
107+ source = "$target_out_dir/bluetoothPbap_abc.abc"
108+ module_install_dir = "framework"
109+ part_name = "$part_name"
110+ subsystem_name = "$subsystem_name"
111+ deps = [ ":bluetoothPbap_abc" ]
112+}
113+ 
114+group("bluetoothPbap_taihe") {
115+ deps = [
116+ ":bluetoothPbap_etc",
117+ ":bluetoothPbap_taihe_native"
118+ ]
119+ # deps = [":run_taihe"]
120+}
Aframeworks/ets/taihe/bluetooth_pbap/idl/ohos.bluetooth.pbap.taihe+63-0
@@ -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+@!namespace("@ohos.bluetooth.pbap", "pbap")
17+@!sts_inject("""
18+static { loadLibraryWithPermissionCheck("bluetoothPbap_taihe_native.z", "@ohos.bluetooth.pbap") }
19+""")
20+from ohos.bluetooth.baseProfile use BaseProfile;
21+from ohos.bluetooth.constant use AccessAuthorization;
22+@!sts_inject_into_module("import {baseProfile} from './@ohos.bluetooth.baseProfile';")
23+ 
24+function CreatePbapServerProfile(): PbapServerProfile;
25+interface PbapServerProfile : BaseProfile {
26+ @!sts_inject_into_class("""on(type: String, callback: object): void {
27+ if (type === "connectionStateChange") {
28+ this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void);
29+ }
30+ }
31+ """)
32+ 
33+ @!sts_inject_into_class("""off(type: String, callback?: object): void {
34+ if (type === "connectionStateChange") {
35+ this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined);
36+ }
37+ }
38+ """)
39+ 
40+ @gen_async("getPhoneBookAccessAuthorization")
41+ @gen_promise("getPhoneBookAccessAuthorization")
42+ GetPhoneBookAccessAuthorizationSync(deviceId: String): AccessAuthorization;
43+ 
44+ @gen_async("getShareType")
45+ @gen_promise("getShareType")
46+ GetShareTypeSync(deviceId: String): ShareType;
47+ 
48+ @gen_async("setShareType")
49+ @gen_promise("setShareType")
50+ SetShareTypeSync(deviceId: String, type: ShareType): void;
51+ 
52+ @gen_async("setPhoneBookAccessAuthorization")
53+ @gen_promise("setPhoneBookAccessAuthorization")
54+ SetPhoneBookAccessAuthorizationSync(deviceId: String, authorization: AccessAuthorization): void;
55+ 
56+ Disconnect(deviceId: String): void;
57+}
58+ 
59+enum ShareType: i32 {
60+ SHARE_NAME_AND_PHONE_NUMBER = 0,
61+ SHARE_ALL = 1,
62+ SHARE_NOTHING = 2
63+}
Aframeworks/ets/taihe/bluetooth_pbap/include/taihe_bluetooth_pbap_observer.h+43-0
@@ -0,0 +1,43 @@
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_PBAP_OBSERVER_H_
17+#define TAIHE_BLUETOOTH_PBAP_OBSERVER_H_
18+ 
19+#include <shared_mutex>
20+#include "bluetooth_pbap_pse.h"
21+#include "ohos.bluetooth.pbap.proj.hpp"
22+#include "ohos.bluetooth.pbap.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 TaiheBluetoothPbapObserver : public PbapPseObserver {
31+public:
32+ void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int32_t state, int32_t cause) override;
33+ 
34+ TaiheBluetoothPbapObserver();
35+ ~TaiheBluetoothPbapObserver() override = default;
36+ 
37+private:
38+ friend class PbapServerProfileImpl;
39+ EventModule<void(::ohos::bluetooth::baseProfile::StateChangeParam const& data)> connectionStateChange_;
40+};
41+} // namespace Bluetooth
42+} // namespace OHOS
43+#endif // TAIHE_BLUETOOTH_PBAP_OBSERVER_H_
Aframeworks/ets/taihe/bluetooth_pbap/src/ohos.bluetooth.pbap.impl.cpp+226-0
@@ -0,0 +1,226 @@
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_pbap_impl_bluetooth"
18+#endif
19+ 
20+#include "ohos.bluetooth.pbap.proj.hpp"
21+#include "ohos.bluetooth.pbap.impl.hpp"
22+#include "taihe/runtime.hpp"
23+#include "stdexcept"
24+#include "bluetooth_errorcode.h"
25+#include "bluetooth_pbap_pse.h"
26+#include "bluetooth_log.h"
27+#include "bluetooth_utils.h"
28+#include "taihe_bluetooth_pbap_observer.h"
29+#include "taihe_bluetooth_utils.h"
30+#include "taihe_event_module.h"
31+ 
32+namespace OHOS {
33+namespace Bluetooth {
34+ 
35+class PbapServerProfileImpl {
36+public:
37+ PbapServerProfileImpl()
38+ {
39+ observer_ = std::make_shared<TaiheBluetoothPbapObserver>();
40+ PbapPse *profile = PbapPse::GetProfile();
41+ profile->RegisterObserver(observer_);
42+ }
43+ 
44+ ::ohos::bluetooth::constant::AccessAuthorization GetPhoneBookAccessAuthorizationSync(
45+ ::taihe::string_view deviceId)
46+ {
47+ HILOGD("enter");
48+ std::string remoteAddr = std::string(deviceId);
49+ bool checkRet = CheckDeviceIdParam(remoteAddr);
50+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
51+ ::ohos::bluetooth::constant::AccessAuthorization::from_value(0));
52+ 
53+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
54+ PbapPse *profile = PbapPse::GetProfile();
55+ int32_t accessAuthorization = 0;
56+ int32_t errorCode = profile->GetPhoneBookAccessAuthorization(remoteDevice, accessAuthorization);
57+ HILOGI("errorCode: %{public}d, accessAuthorization: %{public}d", errorCode, accessAuthorization);
58+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
59+ ::ohos::bluetooth::constant::AccessAuthorization::from_value(accessAuthorization));
60+ return ::ohos::bluetooth::constant::AccessAuthorization::from_value(accessAuthorization);
61+ }
62+ 
63+ ::ohos::bluetooth::pbap::ShareType GetShareTypeSync(::taihe::string_view deviceId)
64+ {
65+ HILOGD("enter");
66+ std::string remoteAddr = std::string(deviceId);
67+ bool checkRet = CheckDeviceIdParam(remoteAddr);
68+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
69+ ::ohos::bluetooth::pbap::ShareType::from_value(0));
70+ 
71+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
72+ PbapPse *profile = PbapPse::GetProfile();
73+ int32_t shareType = 0;
74+ int32_t errorCode = profile->GetShareType(remoteDevice, shareType);
75+ HILOGI("errorCode: %{public}d, shareType: %{public}d", errorCode, shareType);
76+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
77+ ::ohos::bluetooth::pbap::ShareType::from_value(shareType));
78+ return ::ohos::bluetooth::pbap::ShareType::from_value(shareType);
79+ }
80+ 
81+ void SetShareTypeSync(::taihe::string_view deviceId, ::ohos::bluetooth::pbap::ShareType type)
82+ {
83+ HILOGD("enter");
84+ std::string remoteAddr = std::string(deviceId);
85+ bool checkRet = CheckDeviceIdParam(remoteAddr);
86+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
87+ 
88+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
89+ PbapPse *profile = PbapPse::GetProfile();
90+ int32_t errorCode = profile->SetShareType(remoteDevice, type.get_value());
91+ HILOGI("errorCode: %{public}d", errorCode);
92+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
93+ }
94+ 
95+ void SetPhoneBookAccessAuthorizationSync(::taihe::string_view deviceId,
96+ ::ohos::bluetooth::constant::AccessAuthorization authorization)
97+ {
98+ HILOGD("enter");
99+ std::string remoteAddr = std::string(deviceId);
100+ bool checkRet = CheckDeviceIdParam(remoteAddr);
101+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
102+ 
103+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
104+ PbapPse *profile = PbapPse::GetProfile();
105+ int32_t errorCode = profile->SetPhoneBookAccessAuthorization(remoteDevice, authorization.get_value());
106+ HILOGI("errorCode: %{public}d", errorCode);
107+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
108+ }
109+ 
110+ void Disconnect(::taihe::string_view deviceId)
111+ {
112+ HILOGD("enter");
113+ std::string remoteAddr = std::string(deviceId);
114+ bool checkRet = CheckDeviceIdParam(remoteAddr);
115+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
116+ 
117+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
118+ PbapPse *profile = PbapPse::GetProfile();
119+ int32_t errorCode = profile->Disconnect(remoteDevice);
120+ HILOGI("errorCode: %{public}d", errorCode);
121+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
122+ }
123+ 
124+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(::taihe::string_view deviceId)
125+ {
126+ HILOGD("enter");
127+ std::string remoteAddr = std::string(deviceId);
128+ bool checkRet = CheckDeviceIdParam(remoteAddr);
129+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
130+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
131+ 
132+ PbapPse *profile = PbapPse::GetProfile();
133+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
134+ int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
135+ int32_t errorCode = profile->GetDeviceState(device, state);
136+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
137+ HILOGI("errorCode: %{public}d, profileState: %{public}d", errorCode, profileState);
138+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
139+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
140+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
141+ }
142+ 
143+ ::taihe::array<::taihe::string> GetConnectedDevices()
144+ {
145+ HILOGI("enter");
146+ PbapPse *profile = PbapPse::GetProfile();
147+ std::vector<int32_t> states = {static_cast<int32_t>(BTConnectState::CONNECTED)};
148+ std::vector<BluetoothRemoteDevice> devices;
149+ int32_t errorCode = profile->GetDevicesByStates(states, devices);
150+ HILOGI("errorCode: %{public}d, devices size: %{public}zu", errorCode, devices.size());
151+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, taihe::array<::taihe::string>{});
152+ 
153+ std::vector<std::string> deviceVector;
154+ for (auto &device : devices) {
155+ deviceVector.push_back(device.GetDeviceAddr());
156+ }
157+ return deviceVector.empty() ? taihe::array<::taihe::string>{}
158+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
159+ }
160+ 
161+ ::ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(::taihe::string_view deviceId)
162+ {
163+ HILOGD("enter");
164+ std::string remoteAddr = std::string(deviceId);
165+ bool checkRet = CheckDeviceIdParam(remoteAddr);
166+ TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,
167+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
168+ 
169+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
170+ PbapPse *profile = PbapPse::GetProfile();
171+ int32_t strategy = 0;
172+ int32_t errorCode = profile->GetConnectionStrategy(remoteDevice, strategy);
173+ HILOGI("errorCode: %{public}d, strategy: %{public}d", errorCode, strategy);
174+ TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,
175+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
176+ return ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
177+ }
178+ 
179+ void SetConnectionStrategySync(::taihe::string_view deviceId,
180+ ::ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
181+ {
182+ HILOGD("enter");
183+ std::string remoteAddr = std::string(deviceId);
184+ int32_t connStrategy = strategy.get_value();
185+ bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
186+ TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);
187+ 
188+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
189+ PbapPse *profile = PbapPse::GetProfile();
190+ int32_t errorCode = profile->SetConnectionStrategy(remoteDevice, connStrategy);
191+ HILOGI("errorCode: %{public}d", errorCode);
192+ TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);
193+ }
194+ 
195+ void OnConnectionStateChange(::taihe::callback_view<void(
196+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)> callback)
197+ {
198+ if (observer_) {
199+ observer_->connectionStateChange_.RegisterEvent(callback);
200+ }
201+ }
202+ 
203+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
204+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>> callback)
205+ {
206+ if (observer_) {
207+ observer_->connectionStateChange_.DeregisterEvent(callback);
208+ }
209+ }
210+ 
211+private:
212+ std::shared_ptr<TaiheBluetoothPbapObserver> observer_ = nullptr;
213+};
214+ 
215+::ohos::bluetooth::pbap::PbapServerProfile CreatePbapServerProfile()
216+{
217+ return taihe::make_holder<PbapServerProfileImpl, ::ohos::bluetooth::pbap::PbapServerProfile>();
218+}
219+ 
220+} // namespace Bluetooth
221+} // namespace OHOS
222+ 
223+// Since these macros are auto-generate, lint will cause false positive.
224+// NOLINTBEGIN
225+TH_EXPORT_CPP_API_CreatePbapServerProfile(OHOS::Bluetooth::CreatePbapServerProfile);
226+// NOLINTEND
Aframeworks/ets/taihe/bluetooth_pbap/src/taihe_bluetooth_pbap_observer.cpp+56-0
@@ -0,0 +1,56 @@
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_pbap_observer"
18+#endif
19+ 
20+#include "ohos.bluetooth.pbap.proj.hpp"
21+#include "ohos.bluetooth.pbap.impl.hpp"
22+#include "bluetooth_utils.h"
23+#include "bluetooth_log.h"
24+#include "taihe_bluetooth_pbap_observer.h"
25+#include "taihe/runtime.hpp"
26+#include "taihe_bluetooth_utils.h"
27+#include "stdexcept"
28+ 
29+namespace OHOS {
30+namespace Bluetooth {
31+ 
32+TaiheBluetoothPbapObserver::TaiheBluetoothPbapObserver()
33+{}
34+ 
35+void TaiheBluetoothPbapObserver::OnConnectionStateChanged(
36+ const BluetoothRemoteDevice &device, int32_t state, int32_t cause)
37+{
38+ std::shared_lock<std::shared_mutex> guard(connectionStateChange_.lock_);
39+ HILOGD("enter, remote device: %{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 taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam {
44+ .deviceId = deviceId_,
45+ .state = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState),
46+ .cause = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(cause),
47+ };
48+ for (auto callback : connectionStateChange_.callbackVec_) {
49+ if (callback) {
50+ (*callback)(taiheResult);
51+ }
52+ }
53+}
54+ 
55+} // namespace Bluetooth
56+} // namespace OHOS
Aframeworks/ets/taihe/bluetooth_socket/BUILD.gn+115-0
@@ -0,0 +1,115 @@
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_socket_taihe") {
21+ sources = [
22+ "idl/ohos.bluetooth.socket.taihe"
23+ ]
24+}
25+ 
26+subsystem_name = "communication"
27+part_name = "bluetooth"
28+taihe_generated_file_path_socket = "$taihe_file_path/out/$subsystem_name/$part_name/socket"
29+ 
30+ohos_taihe("run_taihe") {
31+ taihe_generated_file_path = "${taihe_generated_file_path_socket}"
32+ deps = [ ":bluetooth_socket_taihe" ]
33+ outputs = [
34+ "$taihe_generated_file_path/src/ohos.bluetooth.socket.ani.cpp",
35+ "$taihe_generated_file_path/src/ohos.bluetooth.socket.abi.c",
36+ ]
37+}
38+ 
39+taihe_shared_library("bluetoothSocket_taihe_native") {
40+ cflags_cc = [
41+ "-Os",
42+ "-fno-rtti",
43+ "-fno-exceptions",
44+ "-fdata-sections",
45+ "-ffunction-sections",
46+ "-fno-unwind-tables",
47+ "-fno-asynchronous-unwind-tables",
48+ "-fno-merge-all-constants",
49+ "-flto",
50+ ]
51+ ldflags = [
52+ "-Wl,--as-needed",
53+ "-Wl,--gc-sections",
54+ ]
55+ shlib_type = "ani"
56+ taihe_generated_file_path = "${taihe_generated_file_path_socket}"
57+ part_name = "$part_name"
58+ subsystem_name = "$subsystem_name"
59+ sources = get_target_outputs(":run_taihe")
60+ include_dirs = [
61+ "include",
62+ "src",
63+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include",
64+ "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include",
65+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common"
66+ ]
67+ sources += [
68+ "src/ohos.bluetooth.socket.impl.cpp",
69+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp",
70+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp",
71+ "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp"
72+ ]
73+ deps = [
74+ ":run_taihe",
75+ "$SUBSYSTEM_DIR/bluetooth/frameworks/inner:btframework",
76+ ]
77+ external_deps = [
78+ "c_utils:utils",
79+ "hilog:libhilog",
80+ "ipc:ipc_single",
81+ ]
82+ sanitize = {
83+ cfi = true # Enable/disable control flow integrity detection
84+ boundary_sanitize = true # Enable boundary san detection
85+ cfi_cross_dso = true # Cross-SO CFI Checks
86+ cfi_vcall_icall_only = true # CFI optimization, restrict CFI detection scope
87+ integer_overflow = true # Enable integer overflow detection
88+ ubsan = true # Enable some Ubsan options
89+ debug = false
90+ }
91+}
92+ 
93+generate_static_abc("bluetoothSocket_abc") {
94+ base_url = "${taihe_generated_file_path_socket}"
95+ files = [ "${taihe_generated_file_path_socket}/@ohos.bluetooth.socket.ets" ]
96+ is_boot_abc = "True"
97+ device_dst_file = "/system/framework/bluetoothSocket_abc.abc"
98+ dependencies = [ ":run_taihe" ]
99+}
100+ 
101+ohos_prebuilt_etc("bluetoothSocket_etc") {
102+ source = "$target_out_dir/bluetoothSocket_abc.abc"
103+ module_install_dir = "framework"
104+ part_name = "$part_name"
105+ subsystem_name = "$subsystem_name"
106+ deps = [ ":bluetoothSocket_abc" ]
107+}
108+ 
109+group("bluetoothSocket_taihe") {
110+ deps = [
111+ ":bluetoothSocket_etc",
112+ ":bluetoothSocket_taihe_native"
113+ ]
114+ # deps = [":run_taihe"]
115+}
Aframeworks/ets/taihe/bluetooth_socket/idl/ohos.bluetooth.socket.taihe+62-0
@@ -0,0 +1,62 @@
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+@!namespace("@ohos.bluetooth.socket", "socket")
17+@!sts_inject("""
18+static { loadLibraryWithPermissionCheck("bluetoothSocket_taihe_native.z", "@ohos.bluetooth.socket") }
19+""")
20+ 
21+@gen_async("sppAccept")
22+function SppAcceptSync(serverSocket: i32): i32;
23+ 
24+@gen_async("sppListen")
25+function SppListenSync(name: String, options: SppOptions): i32;
26+ 
27+function SppCloseServerSocket(socket: i32): void;
28+ 
29+@gen_async("sppConnect")
30+function SppConnectSync(deviceId: String, options: SppOptions): i32;
31+ 
32+function SppWrite(clientSocket: i32, data: @arraybuffer Array<u8>): void;
33+function SppCloseClientSocket(socket: i32): void;
34+ 
35+function GetMaxReceiveDataSize(clientSocket: i32): i32;
36+ 
37+function OnSppRead(clientSocket: i32, callback:(data: @arraybuffer Array<u8>) => void): void;
38+function OffSppRead(clientSocket: i32, callback: Optional<(data: @arraybuffer Array<u8>) => void>): void;
39+ 
40+function IsConnected(clientSocket: i32): bool;
41+function GetL2capPsm(serverSocket: i32): i32;
42+function GetDeviceId(clientSocket: i32): String;
43+function GetMaxTransmitDataSize(clientSocket: i32): i32;
44+ 
45+@gen_promise("sppWriteAsync")
46+function SppWriteAsyncSync(clientSocket: i32, data: @arraybuffer Array<u8>): void;
47+ 
48+@gen_promise("sppReadAsync")
49+function SppReadAsyncSync(clientSocket: i32): @arraybuffer Array<u8>;
50+ 
51+struct SppOptions {
52+ uuid: String;
53+ secure: bool;
54+ type: SppType;
55+ psm: Optional<i32>;
56+}
57+ 
58+enum SppType: i32 {
59+ SPP_RFCOMM = 0,
60+ SPP_L2CAP = 1,
61+ SPP_L2CAP_BLE = 2
62+}
Aframeworks/ets/taihe/bluetooth_socket/include/taihe_bluetooth_socket_manager.h+180-0
@@ -0,0 +1,180 @@
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_SOCKET_MANAGER_H_
17+#define TAIHE_BLUETOOTH_SOCKET_MANAGER_H_
18+ 
19+#include <atomic>
20+#include <map>
21+#include <memory>
22+#include <mutex>
23+#include <thread>
24+#include <vector>
25+ 
26+#include "bluetooth_socket.h"
27+#include "bluetooth_socket_inputstream.h"
28+#include "bluetooth_socket_outputstream.h"
29+#include "bluetooth_log.h"
30+#include "taihe/array.hpp"
31+#include "taihe/callback.hpp"
32+#include "taihe/optional.hpp"
33+ 
34+namespace OHOS {
35+namespace Bluetooth {
36+ 
37+constexpr int RFCOMM_SOCKET_BUFFER_SIZE = 1024;
38+constexpr int L2CAP_SOCKET_BUFFER_SIZE = 65535;
39+constexpr int SPP_ACCEPT_TIMEOUT = 20;
40+ 
41+using SppReadCallback = ::taihe::callback<void(::taihe::array_view<uint8_t> data)>;
42+using OptionalSppReadCallback = ::taihe::optional<SppReadCallback>;
43+ 
44+struct TaiheSppClient : public std::enable_shared_from_this<TaiheSppClient> {
45+ std::shared_ptr<ClientSocket> client_;
46+ OptionalSppReadCallback readCallback_;
47+ std::atomic<bool> readFlag_{false};
48+ std::shared_ptr<std::thread> readThread_;
49+ std::mutex callbackMutex_;
50+ 
51+ void SetReadCallback(::taihe::callback_view<void(::taihe::array_view<uint8_t> data)> callback)
52+ {
53+ std::lock_guard<std::mutex> lock(callbackMutex_);
54+ readCallback_ = OptionalSppReadCallback{std::in_place_t{}, callback};
55+ }
56+ 
57+ void ClearReadCallback()
58+ {
59+ std::lock_guard<std::mutex> lock(callbackMutex_);
60+ readCallback_.reset();
61+ }
62+ 
63+ void StartReadThread()
64+ {
65+ readFlag_ = true;
66+ auto self = shared_from_this();
67+ auto inputStream = client_->GetInputStream();
68+ BtSocketType type = client_->GetType();
69+ auto client = client_;
70+ readThread_ = std::make_shared<std::thread>([self, inputStream, type, client]() {
71+ std::vector<uint8_t> buf;
72+ if (type == TYPE_RFCOMM) {
73+ buf.resize(RFCOMM_SOCKET_BUFFER_SIZE);
74+ } else {
75+ buf.resize(client->GetMaxReceivePacketSize());
76+ }
77+ while (self->readFlag_) {
78+ std::fill(buf.begin(), buf.end(), 0);
79+ ssize_t ret = inputStream->Read(buf.data(), buf.size());
80+ if (ret <= 0) {
81+ HILOGE("inputStream.Read failed, ret = %{public}zd", ret);
82+ return;
83+ }
84+ OptionalSppReadCallback cbCopy;
85+ {
86+ std::lock_guard<std::mutex> lock(self->callbackMutex_);
87+ cbCopy = self->readCallback_;
88+ }
89+ if (cbCopy.has_value() && self->readFlag_) {
90+ cbCopy.value()(::taihe::array_view<uint8_t>(buf.data(), static_cast<size_t>(ret)));
91+ }
92+ }
93+ });
94+ readThread_->detach();
95+ }
96+ 
97+ void StopReadThread()
98+ {
99+ readFlag_ = false;
100+ ClearReadCallback();
101+ }
102+};
103+ 
104+class TaiheSocketManager {
105+public:
106+ static TaiheSocketManager& GetInstance()
107+ {
108+ static TaiheSocketManager instance;
109+ return instance;
110+ }
111+ 
112+ int32_t AddServer(std::shared_ptr<ServerSocket> server)
113+ {
114+ std::lock_guard<std::mutex> lock(mutex_);
115+ int32_t id = serverCount_++;
116+ serverMap_[id] = server;
117+ return id;
118+ }
119+ 
120+ std::shared_ptr<ServerSocket> GetServer(int32_t id)
121+ {
122+ std::lock_guard<std::mutex> lock(mutex_);
123+ auto it = serverMap_.find(id);
124+ if (it != serverMap_.end()) {
125+ return it->second;
126+ }
127+ return nullptr;
128+ }
129+ 
130+ void RemoveServer(int32_t id)
131+ {
132+ std::lock_guard<std::mutex> lock(mutex_);
133+ serverMap_.erase(id);
134+ }
135+ 
136+ int32_t AddClient(std::shared_ptr<ClientSocket> client)
137+ {
138+ std::lock_guard<std::mutex> lock(mutex_);
139+ int32_t id = clientCount_++;
140+ auto sppClient = std::make_shared<TaiheSppClient>();
141+ sppClient->client_ = client;
142+ clientMap_[id] = sppClient;
143+ return id;
144+ }
145+ 
146+ std::shared_ptr<TaiheSppClient> GetClient(int32_t id)
147+ {
148+ std::lock_guard<std::mutex> lock(mutex_);
149+ auto it = clientMap_.find(id);
150+ if (it != clientMap_.end()) {
151+ return it->second;
152+ }
153+ return nullptr;
154+ }
155+ 
156+ void RemoveClient(int32_t id)
157+ {
158+ std::lock_guard<std::mutex> lock(mutex_);
159+ auto it = clientMap_.find(id);
160+ if (it != clientMap_.end()) {
161+ it->second->StopReadThread();
162+ clientMap_.erase(it);
163+ }
164+ }
165+ 
166+private:
167+ TaiheSocketManager() = default;
168+ ~TaiheSocketManager() = default;
169+ TaiheSocketManager(const TaiheSocketManager&) = delete;
170+ TaiheSocketManager& operator=(const TaiheSocketManager&) = delete;
171+ 
172+ std::mutex mutex_;
173+ std::map<int32_t, std::shared_ptr<ServerSocket>> serverMap_;
174+ std::map<int32_t, std::shared_ptr<TaiheSppClient>> clientMap_;
175+ int32_t serverCount_ = 0;
176+ int32_t clientCount_ = 0;
177+};
178+} // namespace Bluetooth
179+} // namespace OHOS
180+#endif // TAIHE_BLUETOOTH_SOCKET_MANAGER_H_
Aframeworks/ets/taihe/bluetooth_socket/src/ohos.bluetooth.socket.impl.cpp+332-0
@@ -0,0 +1,332 @@
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_socket_impl"
18+#endif
19+ 
20+#include "ohos.bluetooth.socket.impl.hpp"
21+#include "ohos.bluetooth.socket.proj.hpp"
22+#include "taihe/runtime.hpp"
23+#include "stdexcept"
24+ 
25+#include "bluetooth_errorcode.h"
26+#include "bluetooth_log.h"
27+#include "bluetooth_remote_device.h"
28+#include "bluetooth_socket.h"
29+#include "bluetooth_socket_inputstream.h"
30+#include "bluetooth_socket_outputstream.h"
31+#include "uuid.h"
32+#include "taihe_bluetooth_socket_manager.h"
33+ 
34+using namespace OHOS::Bluetooth;
35+ 
36+namespace {
37+struct SppOptionValues {
38+ std::string uuid;
39+ bool secure;
40+ BtSocketType type;
41+ int psm;
42+ bool valid;
43+};
44+ 
45+SppOptionValues ConvertSppOptions(const ::ohos::bluetooth::socket::SppOptions& options)
46+{
47+ SppOptionValues v;
48+ v.uuid = std::string(options.uuid);
49+ v.secure = options.secure;
50+ v.type = static_cast<BtSocketType>(options.type.get_value());
51+ v.psm = options.psm.has_value() ? options.psm.value() : -1;
52+ v.valid = true;
53+ if ((v.type == TYPE_L2CAP || v.type == TYPE_L2CAP_LE) && v.psm <= 0) {
54+ HILOGE("L2CAP/L2CAP_LE type but psm <= 0");
55+ v.valid = false;
56+ }
57+ if (v.type == TYPE_RFCOMM && v.uuid.empty()) {
58+ HILOGE("RFCOMM type but uuid is empty");
59+ v.valid = false;
60+ }
61+ return v;
62+}
63+ 
64+int32_t SppAcceptSync(int32_t serverSocket)
65+{
66+ HILOGI("enter, serverSocket: %{public}d", serverSocket);
67+ auto server = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetServer(serverSocket);
68+ if (!server) {
69+ HILOGE("server is null");
70+ return -1;
71+ }
72+ auto client = server->Accept(OHOS::Bluetooth::SPP_ACCEPT_TIMEOUT);
73+ if (!client) {
74+ HILOGE("Accept failed");
75+ return -1;
76+ }
77+ return OHOS::Bluetooth::TaiheSocketManager::GetInstance().AddClient(client);
78+}
79+ 
80+int32_t SppListenSync(::taihe::string_view name, ::ohos::bluetooth::socket::SppOptions const& options)
81+{
82+ HILOGI("enter");
83+ auto opt = ConvertSppOptions(options);
84+ if (!opt.valid) {
85+ HILOGE("invalid spp options");
86+ return -1;
87+ }
88+ std::string nameStr = std::string(name);
89+ auto server = std::make_shared<OHOS::Bluetooth::ServerSocket>(nameStr,
90+ UUID::FromString(opt.uuid), opt.type, opt.secure, opt.psm);
91+ int errorCode = server->Listen();
92+ HILOGI("Listen errorCode: %{public}d", errorCode);
93+ if (server->GetStringTag() != "") {
94+ HILOGI("SppListen success");
95+ return OHOS::Bluetooth::TaiheSocketManager::GetInstance().AddServer(server);
96+ }
97+ HILOGE("SppListen failed");
98+ return -1;
99+}
100+ 
101+void SppCloseServerSocket(int32_t socket)
102+{
103+ HILOGI("enter, socket: %{public}d", socket);
104+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(socket);
105+ if (client && client->client_) {
106+ client->client_->Close();
107+ OHOS::Bluetooth::TaiheSocketManager::GetInstance().RemoveClient(socket);
108+ } else {
109+ HILOGE("no such key in clientMap.");
110+ }
111+ auto server = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetServer(socket);
112+ if (server) {
113+ server->Close();
114+ OHOS::Bluetooth::TaiheSocketManager::GetInstance().RemoveServer(socket);
115+ } else {
116+ HILOGE("no such key in serverMap.");
117+ }
118+}
119+ 
120+int32_t SppConnectSync(::taihe::string_view deviceId, ::ohos::bluetooth::socket::SppOptions const& options)
121+{
122+ HILOGI("enter");
123+ auto opt = ConvertSppOptions(options);
124+ if (!opt.valid) {
125+ HILOGE("invalid spp options");
126+ return -1;
127+ }
128+ std::string addr = std::string(deviceId);
129+ BluetoothRemoteDevice device(addr, BT_TRANSPORT_BREDR);
130+ auto client = std::make_shared<OHOS::Bluetooth::ClientSocket>(device,
131+ UUID::FromString(opt.uuid), opt.type, opt.secure);
132+ int errorCode = client->Connect(opt.psm);
133+ HILOGI("Connect errorCode: %{public}d", errorCode);
134+ if (errorCode == BT_NO_ERROR) {
135+ HILOGI("SppConnect successfully");
136+ return OHOS::Bluetooth::TaiheSocketManager::GetInstance().AddClient(client);
137+ }
138+ HILOGE("SppConnect failed");
139+ return -1;
140+}
141+ 
142+void SppWrite(int32_t clientSocket, ::taihe::array_view<uint8_t> data)
143+{
144+ HILOGD("enter, clientSocket: %{public}d", clientSocket);
145+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
146+ if (!client || !client->client_) {
147+ HILOGE("client is null");
148+ return;
149+ }
150+ auto outputStream = client->client_->GetOutputStream();
151+ uint8_t* buf = data.data();
152+ size_t totalSize = data.size();
153+ while (totalSize) {
154+ int result = outputStream->Write(buf, totalSize);
155+ if (result <= 0) {
156+ HILOGE("Write failed, result: %{public}d", result);
157+ return;
158+ }
159+ totalSize -= static_cast<size_t>(result);
160+ buf += static_cast<size_t>(result);
161+ }
162+}
163+ 
164+void SppCloseClientSocket(int32_t socket)
165+{
166+ HILOGI("enter, socket: %{public}d", socket);
167+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(socket);
168+ if (client && client->client_) {
169+ client->StopReadThread();
170+ client->client_->Close();
171+ } else {
172+ HILOGE("no such key in clientMap.");
173+ }
174+ OHOS::Bluetooth::TaiheSocketManager::GetInstance().RemoveClient(socket);
175+}
176+ 
177+int32_t GetMaxReceiveDataSize(int32_t clientSocket)
178+{
179+ HILOGD("enter, clientSocket: %{public}d", clientSocket);
180+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
181+ if (!client || !client->client_) {
182+ HILOGE("client is null");
183+ return -1;
184+ }
185+ return static_cast<int32_t>(client->client_->GetMaxReceivePacketSize());
186+}
187+ 
188+void OnSppRead(int32_t clientSocket, ::taihe::callback_view<void(::taihe::array_view<uint8_t> data)> callback)
189+{
190+ HILOGI("enter, clientSocket: %{public}d", clientSocket);
191+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
192+ if (!client || !client->client_) {
193+ HILOGE("client is null");
194+ return;
195+ }
196+ if (client->readFlag_) {
197+ HILOGE("client is reading, please off first");
198+ return;
199+ }
200+ client->SetReadCallback(callback);
201+ client->StartReadThread();
202+}
203+ 
204+void OffSppRead(int32_t clientSocket,
205+ ::taihe::optional_view<::taihe::callback<void(::taihe::array_view<uint8_t> data)>> callback)
206+{
207+ HILOGI("enter, clientSocket: %{public}d", clientSocket);
208+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
209+ if (!client || !client->client_) {
210+ HILOGE("client is null");
211+ return;
212+ }
213+ client->StopReadThread();
214+}
215+ 
216+bool IsConnected(int32_t clientSocket)
217+{
218+ HILOGD("enter, clientSocket: %{public}d", clientSocket);
219+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
220+ if (!client || !client->client_) {
221+ HILOGE("client is null");
222+ return false;
223+ }
224+ return client->client_->IsConnected();
225+}
226+ 
227+int32_t GetL2capPsm(int32_t serverSocket)
228+{
229+ HILOGD("enter, serverSocket: %{public}d", serverSocket);
230+ auto server = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetServer(serverSocket);
231+ if (!server) {
232+ HILOGE("server is null");
233+ return -1;
234+ }
235+ return server->GetL2capPsm();
236+}
237+ 
238+::taihe::string GetDeviceId(int32_t clientSocket)
239+{
240+ HILOGD("enter, clientSocket: %{public}d", clientSocket);
241+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
242+ if (!client || !client->client_) {
243+ HILOGE("client is null");
244+ return ::taihe::string{};
245+ }
246+ BluetoothRemoteDevice remoteDevice = client->client_->GetRemoteDevice();
247+ return ::taihe::string(remoteDevice.GetDeviceAddr());
248+}
249+ 
250+int32_t GetMaxTransmitDataSize(int32_t clientSocket)
251+{
252+ HILOGD("enter, clientSocket: %{public}d", clientSocket);
253+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
254+ if (!client || !client->client_) {
255+ HILOGE("client is null");
256+ return -1;
257+ }
258+ return static_cast<int32_t>(client->client_->GetMaxTransmitPacketSize());
259+}
260+ 
261+void SppWriteAsyncSync(int32_t clientSocket, ::taihe::array_view<uint8_t> data)
262+{
263+ HILOGD("enter, clientSocket: %{public}d", clientSocket);
264+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
265+ if (!client || !client->client_) {
266+ HILOGE("client is null");
267+ return;
268+ }
269+ auto outputStream = client->client_->GetOutputStream();
270+ uint8_t* buf = data.data();
271+ size_t totalSize = data.size();
272+ while (totalSize) {
273+ int result = outputStream->Write(buf, totalSize);
274+ if (result <= 0) {
275+ HILOGE("Write failed, result: %{public}d", result);
276+ return;
277+ }
278+ totalSize -= static_cast<size_t>(result);
279+ buf += static_cast<size_t>(result);
280+ }
281+}
282+ 
283+::taihe::array<uint8_t> SppReadAsyncSync(int32_t clientSocket)
284+{
285+ HILOGD("enter, clientSocket: %{public}d", clientSocket);
286+ auto client = OHOS::Bluetooth::TaiheSocketManager::GetInstance().GetClient(clientSocket);
287+ if (!client || !client->client_) {
288+ HILOGE("client is null");
289+ return ::taihe::array<uint8_t>{};
290+ }
291+ if (client->readFlag_) {
292+ HILOGE("client is reading, please off first");
293+ return ::taihe::array<uint8_t>{};
294+ }
295+ client->readFlag_ = true;
296+ auto inputStream = client->client_->GetInputStream();
297+ BtSocketType type = client->client_->GetType();
298+ std::vector<uint8_t> buf;
299+ if (type == TYPE_RFCOMM) {
300+ buf.resize(RFCOMM_SOCKET_BUFFER_SIZE);
301+ } else {
302+ buf.resize(client->client_->GetMaxReceivePacketSize());
303+ }
304+ std::fill(buf.begin(), buf.end(), 0);
305+ ssize_t ret = inputStream->Read(buf.data(), buf.size());
306+ client->readFlag_ = false;
307+ if (ret <= 0) {
308+ HILOGE("Read failed, ret: %{public}zd", ret);
309+ return ::taihe::array<uint8_t>{};
310+ }
311+ return ::taihe::array<uint8_t>(::taihe::copy_data, buf.data(), static_cast<size_t>(ret));
312+}
313+} // namespace
314+ 
315+// Since these macros are auto-generate, lint will cause false positive.
316+// NOLINTBEGIN
317+TH_EXPORT_CPP_API_SppAcceptSync(SppAcceptSync);
318+TH_EXPORT_CPP_API_SppListenSync(SppListenSync);
319+TH_EXPORT_CPP_API_SppCloseServerSocket(SppCloseServerSocket);
320+TH_EXPORT_CPP_API_SppConnectSync(SppConnectSync);
321+TH_EXPORT_CPP_API_SppWrite(SppWrite);
322+TH_EXPORT_CPP_API_SppCloseClientSocket(SppCloseClientSocket);
323+TH_EXPORT_CPP_API_GetMaxReceiveDataSize(GetMaxReceiveDataSize);
324+TH_EXPORT_CPP_API_OnSppRead(OnSppRead);
325+TH_EXPORT_CPP_API_OffSppRead(OffSppRead);
326+TH_EXPORT_CPP_API_IsConnected(IsConnected);
327+TH_EXPORT_CPP_API_GetL2capPsm(GetL2capPsm);
328+TH_EXPORT_CPP_API_GetDeviceId(GetDeviceId);
329+TH_EXPORT_CPP_API_GetMaxTransmitDataSize(GetMaxTransmitDataSize);
330+TH_EXPORT_CPP_API_SppWriteAsyncSync(SppWriteAsyncSync);
331+TH_EXPORT_CPP_API_SppReadAsyncSync(SppReadAsyncSync);
332+// NOLINTEND
Mframeworks/ets/taihe/common/taihe_async_work.h+9-1
@@ -41,7 +41,15 @@ enum TaiheAsyncType : int {
41 BLE_START_SCAN,41 BLE_START_SCAN,
42 BLE_STOP_SCAN,42 BLE_STOP_SCAN,
43 BLE_ENABLE_ADVERTISING,43 BLE_ENABLE_ADVERTISING,
44- BLE_DISABLE_ADVERTISING44+ BLE_DISABLE_ADVERTISING,
45+ BAS_GET_BATTERY_LEVEL,
46+ GATT_CLIENT_READ_PHY,
47+ GATT_CLIENT_SET_PHY,
48+ GATT_CLIENT_WRITE_CHARACTER_WITH_CONTEXT,
49+ GATT_CLIENT_MTU_CHANGED,
50+ GATT_CLIENT_UPDATE_CONNECTION_PRIORITY,
51+ GATT_SERVER_SET_PHY,
52+ GATT_SERVER_READ_PHY
45};53};
46 54 
47struct TaiheAsyncWorkRet {55struct TaiheAsyncWorkRet {
Mframeworks/ets/taihe/common/taihe_event_module.h+14-0
@@ -31,6 +31,8 @@ class EventModule {
31public:31public:
32 void RegisterEvent(::taihe::callback_view<T> callback);32 void RegisterEvent(::taihe::callback_view<T> callback);
33 void DeregisterEvent(::taihe::optional_view<::taihe::callback<T>> callback);33 void DeregisterEvent(::taihe::optional_view<::taihe::callback<T>> callback);
34+ template<typename... Args>
35+ void PublishEvent(Args&&... args);
34 36 
35 std::vector<::taihe::optional<::taihe::callback<T>>> callbackVec_;37 std::vector<::taihe::optional<::taihe::callback<T>>> callbackVec_;
36 std::shared_mutex lock_;38 std::shared_mutex lock_;
@@ -67,6 +69,18 @@ void EventModule<T>::DeregisterEvent(::taihe::optional_view<::taihe::callback<T>
67 callbackVec_.clear();69 callbackVec_.clear();
68 }70 }
69}71}
72+ 
73+template<typename T>
74+template<typename... Args>
75+void EventModule<T>::PublishEvent(Args&&... args)
76+{
77+ std::shared_lock<std::shared_mutex> guard(lock_);
78+ for (auto& cb : callbackVec_) {
79+ if (cb.has_value()) {
80+ cb.value()(std::forward<Args>(args)...);
81+ }
82+ }
83+}
70} // namespace Bluetooth84} // namespace Bluetooth
71} // namespace OHOS85} // namespace OHOS
72#endif // TAIHE_EVENT_MODULE_H86#endif // TAIHE_EVENT_MODULE_H
Mframeworks/ets/taihe/common/taihe_native_object.cpp+22-0
@@ -76,5 +76,27 @@ ani_ref TaiheNativeBleDescriptor::ToTaiheValue(ani_env *env) const
76 ani_object object = ConvertBLEDescriptorToJS(env, const_cast<GattDescriptor &>(descriptor_));76 ani_object object = ConvertBLEDescriptorToJS(env, const_cast<GattDescriptor &>(descriptor_));
77 return reinterpret_cast<ani_ref>(object);77 return reinterpret_cast<ani_ref>(object);
78}78}
79+ 
80+ani_ref TaiheNativePhyValue::ToTaiheValue(ani_env *env) const
81+{
82+ ani_class cls;
83+ ani_status status = ANI_ERROR;
84+ if ((status = env->FindClass("ohos.bluetooth.ble.PhyValue", &cls)) != ANI_OK) {
85+ HILOGE("FindClass status : %{public}d", status);
86+ return nullptr;
87+ }
88+ ani_method ctor;
89+ if ((status = env->Class_FindMethod(cls, "<ctor>", "ii?", &ctor)) != ANI_OK) {
90+ HILOGE("Class_FindMethod status : %{public}d", status);
91+ return nullptr;
92+ }
93+ ani_ref phyModeRef = TaiheGetNull(env);
94+ ani_object object;
95+ if ((status = env->Object_New(cls, ctor, &object, txPhy_, rxPhy_, phyModeRef)) != ANI_OK) {
96+ HILOGE("Object_New status : %{public}d", status);
97+ return nullptr;
98+ }
99+ return reinterpret_cast<ani_ref>(object);
100+}
79} // namespace Bluetooth101} // namespace Bluetooth
80} // namespace OHOS102} // namespace OHOS
Mframeworks/ets/taihe/common/taihe_native_object.h+11-0
@@ -87,6 +87,17 @@ public:
87private:87private:
88 GattDescriptor descriptor_;88 GattDescriptor descriptor_;
89};89};
90+ 
91+class TaiheNativePhyValue : public TaiheNativeObject {
92+public:
93+ TaiheNativePhyValue(int32_t txPhy, int32_t rxPhy) : txPhy_(txPhy), rxPhy_(rxPhy) {}
94+ ~TaiheNativePhyValue() override = default;
95+ 
96+ ani_ref ToTaiheValue(ani_env *env) const override;
97+private:
98+ int32_t txPhy_;
99+ int32_t rxPhy_;
100+};
90} // namespace Bluetooth101} // namespace Bluetooth
91} // namespace OHOS102} // namespace OHOS
92#endif // TAIHE_NATIVE_OBJECT_H103#endif // TAIHE_NATIVE_OBJECT_H