已开启
hid ipc问题查看 #2027
hid ipc问题查看 #2027
已开启
panjie创建于 10 天前
11 个文件变更+1046-13
Mbundle.json+2-1
@@ -102,7 +102,8 @@
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"
106 ],107 ],
107 "service_group": [108 "service_group": [
108 "//foundation/communication/bluetooth/tools/ohos-bluetoothTool:ohos-bluetoothTool",109 "//foundation/communication/bluetooth/tools/ohos-bluetoothTool:ohos-bluetoothTool",
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_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+117-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,119 @@ interface HidHostProfile : BaseProfile {
37 Connect(deviceId: String): void;38 Connect(deviceId: String): void;
38 Disconnect(deviceId: String): void;39 Disconnect(deviceId: String): void;
39}40}
40-function CreateHidHostProfile(): HidHostProfile;41+function CreateHidHostProfile(): HidHostProfile;
42+ 
43+union UndefinedType {
44+ @undefined undefined;
45+}
46+ 
47+interface HidDeviceProfile : BaseProfile {
48+ @!sts_inject_into_class("""on(type: string, callback: object): void {
49+ if (type === "connectionStateChange") {
50+ this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void);
51+ }
52+ }
53+ """)
54+ 
55+ @!sts_inject_into_class("""off(type: string, callback?: object): void {
56+ if (type === "connectionStateChange") {
57+ this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined);
58+ }
59+ }
60+ """)
61+ Connect(deviceId: BluetoothAddress): void;
62+ Disconnect(): void;
63+ ReportError(error: ErrorReason): void;
64+ UnregisterHidDevice(): void;
65+ SendReport(id: i32, reportData: @arraybuffer Array<u8>): void;
66+ ReplyReport(type: ReportType, id: i32, reportData: @arraybuffer Array<u8>): void;
67+ OnSetProtocol(callback: (data: ProtocolData) => void): void;
68+ OffSetProtocol(callback: Optional<(data: ProtocolData) => void>): void;
69+ OnInterruptDataReceived(callback: (data: InterruptData) => void): void;
70+ OffInterruptDataReceived(callback: Optional<(data: InterruptData) => void>): void;
71+ RegisterHidDevice(sdp: HidDeviceSdp, inQos: HidDeviceQos, outQos: HidDeviceQos, callback:(data:bool)=>void): void;
72+ OnSetReport(callback: (data: SetReportData) => void): void;
73+ OffSetReport(callback: Optional<(data: SetReportData) => void>): void;
74+ OnGetReport(callback: (data: GetReportData) => void): void;
75+ OffGetReport(callback: Optional<(data: GetReportData) => void>): void;
76+ OnVirtualCableUnplug(callback:(data: UndefinedType) => void): void;
77+ OffVirtualCableUnplug(callback: Optional<(data: UndefinedType) => void>): void;
78+}
79+function CreateHidDeviceProfile(): HidDeviceProfile;
80+ 
81+enum ErrorReason: i32 {
82+ RSP_SUCCESS = 0,
83+ RSP_NOT_READY = 1,
84+ RSP_INVALID_REPORT_ID = 2,
85+ RSP_UNSUPPORTED_REQ = 3,
86+ RSP_INVALID_PARAM = 4,
87+ RSP_UNKNOWN = 14
88+}
89+ 
90+struct ProtocolData {
91+ protocol: ProtocolType;
92+}
93+ 
94+enum ProtocolType: i32 {
95+ PROTOCOL_BOOT_MODE = 0,
96+ PROTOCOL_REPORT_MODE = 1
97+}
98+ 
99+struct InterruptData {
100+ id: i32;
101+ data: @arraybuffer Array<u8>;
102+}
103+ 
104+struct HidDeviceSdp {
105+ name: String;
106+ description: String;
107+ provider: String;
108+ subclass: Subclass;
109+ descriptors: @arraybuffer Array<u8>;
110+}
111+ 
112+enum Subclass: i32 {
113+ SUBCLASS_UNCATEGORIZED = 0,
114+ SUBCLASS_JOYSTICK = 1,
115+ SUBCLASS_GAMEPAD = 2,
116+ SUBCLASS_REMOTE_CONTROL = 3,
117+ SUBCLASS_SENSING_DEVICE = 4,
118+ SUBCLASS_DIGITIZER_TABLET = 5,
119+ SUBCLASS_CARD_READER = 6,
120+ SUBCLASS_KEYBOARD = 64,
121+ SUBCLASS_MOUSE = 128,
122+ SUBCLASS_COMBO = 192
123+}
124+ 
125+struct HidDeviceQos {
126+ serviceType: Optional<ServiceType>;
127+ tokenRate: Optional<i32>;
128+ tokenBucketSize: Optional<i32>;
129+ peakBandwidth: Optional<i32>;
130+ latency: Optional<i32>;
131+ delayVariation: Optional<i32>;
132+}
133+ 
134+enum ServiceType: i32 {
135+ SERVICE_NO_TRAFFIC = 0,
136+ SERVICE_BEST_EFFORT = 1,
137+ SERVICE_GUARANTEED = 2
138+}
139+ 
140+struct SetReportData {
141+ type: ReportType;
142+ id: i32;
143+ data: @arraybuffer Array<u8>;
144+}
145+ 
146+struct GetReportData {
147+ type: ReportType;
148+ id: i32;
149+ bufferSize: i32;
150+}
151+ 
152+enum ReportType: i32 {
153+ REPORT_TYPE_INPUT = 1,
154+ REPORT_TYPE_OUTPUT = 2,
155+ REPORT_TYPE_FEATURE = 3
156+}
Aframeworks/ets/taihe/bluetooth_hid/include/taihe_bluetooth_hid_device_observer.h+73-0
@@ -0,0 +1,73 @@
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 <string>
21+#include <vector>
22+#include "bluetooth_hid_device.h"
23+#include "ohos.bluetooth.hid.proj.hpp"
24+#include "ohos.bluetooth.hid.impl.hpp"
25+#include "taihe/runtime.hpp"
26+#include "stdexcept"
27+ 
28+namespace OHOS {
29+namespace Bluetooth {
30+ 
31+class TaiheBluetoothHidDeviceObserver : public HidDeviceObserver {
32+public:
33+ void OnAppStatusChanged(int state) override;
34+ void OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state) override;
35+ void OnGetReport(int type, int id, uint16_t bufferSize) override;
36+ void OnSetProtocol(int protocol) override;
37+ void OnInterruptDataReceived(int id, const std::vector<uint8_t> &data) override;
38+ void OnSetReport(int type, int id, const std::vector<uint8_t> &data) override;
39+ void OnVirtualCableUnplug() override;
40+ 
41+ TaiheBluetoothHidDeviceObserver();
42+ ~TaiheBluetoothHidDeviceObserver() override = default;
43+ 
44+ std::vector<::taihe::optional<::taihe::callback<void(
45+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>>> connectionStateChangeVec_ = {};
46+ std::shared_mutex connectionStateChangeLock_;
47+ 
48+ std::vector<::taihe::optional<::taihe::callback<void(
49+ ::ohos::bluetooth::hid::ProtocolData const& data)>>> setProtocolVec_ = {};
50+ std::shared_mutex setProtocolLock_;
51+ 
52+ std::vector<::taihe::optional<::taihe::callback<void(
53+ ::ohos::bluetooth::hid::InterruptData const& data)>>> interruptDataReceivedVec_ = {};
54+ std::shared_mutex interruptDataReceivedLock_;
55+ 
56+ std::vector<::taihe::optional<::taihe::callback<void(
57+ ::ohos::bluetooth::hid::SetReportData const& data)>>> setReportVec_ = {};
58+ std::shared_mutex setReportLock_;
59+ 
60+ std::vector<::taihe::optional<::taihe::callback<void(
61+ ::ohos::bluetooth::hid::GetReportData const& data)>>> getReportVec_ = {};
62+ std::shared_mutex getReportLock_;
63+ 
64+ std::vector<::taihe::optional<::taihe::callback<void(
65+ ::ohos::bluetooth::hid::UndefinedType const& data)>>> virtualCableUnplugVec_ = {};
66+ std::shared_mutex virtualCableUnplugLock_;
67+ 
68+ std::vector<::taihe::optional<::taihe::callback<void(bool data)>>> appStatusChangeVec_ = {};
69+ std::shared_mutex appStatusChangeLock_;
70+};
71+} // namespace Bluetooth
72+} // namespace OHOS
73+#endif /* TAIHE_BLUETOOTH_HID_DEVICE_OBSERVER_H_ */
Mframeworks/ets/taihe/bluetooth_hid/src/ani_constructor.cpp+1-0
@@ -14,6 +14,7 @@
14 */14 */
15 15 
16#include "ohos.bluetooth.hid.ani.hpp"16#include "ohos.bluetooth.hid.ani.hpp"
17+ 
17ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)18ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
18{19{
19 ani_env *env;20 ani_env *env;
Mframeworks/ets/taihe/bluetooth_hid/src/ohos.bluetooth.hid.impl.cpp+511-11
@@ -23,9 +23,13 @@
23#include "stdexcept"23#include "stdexcept"
24#include "bluetooth_errorcode.h"24#include "bluetooth_errorcode.h"
25#include "bluetooth_hid_host.h"25#include "bluetooth_hid_host.h"
26+#include "bluetooth_hid_device.h"
27+#include "bluetooth_address_info.h"
26#include "bluetooth_log.h"28#include "bluetooth_log.h"
27#include "taihe_bluetooth_hid_host_observer.h"29#include "taihe_bluetooth_hid_host_observer.h"
30+#include "taihe_bluetooth_hid_device_observer.h"
28#include "taihe_bluetooth_utils.h"31#include "taihe_bluetooth_utils.h"
32+#include "hid_device_utils.h"
29 33 
30namespace OHOS {34namespace OHOS {
31namespace Bluetooth {35namespace Bluetooth {
@@ -57,36 +61,44 @@ public:
57 void Connect(taihe::string_view deviceId)61 void Connect(taihe::string_view deviceId)
58 {62 {
59 HILOGI("enter");63 HILOGI("enter");
64+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_SERVICE_DISCONNECTED,
65+ BT_ERR_INVALID_STATE, BT_ERR_PROFILE_DISABLED, BT_ERR_INTERNAL_ERROR };
66+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
60 std::string remoteAddr = std::string(deviceId);67 std::string remoteAddr = std::string(deviceId);
61 bool checkRet = CheckDeviceIdParam(remoteAddr);68 bool checkRet = CheckDeviceIdParam(remoteAddr);
62- TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);69+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
63 70 
64 HidHost *profile = HidHost::GetProfile();71 HidHost *profile = HidHost::GetProfile();
65 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);72 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
66 int32_t errorCode = profile->Connect(device);73 int32_t errorCode = profile->Connect(device);
67 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());74 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
68- TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);75+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
69 }76 }
70 77 
71 void Disconnect(taihe::string_view deviceId)78 void Disconnect(taihe::string_view deviceId)
72 {79 {
73 HILOGI("Disconnect called");80 HILOGI("Disconnect called");
81+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_SERVICE_DISCONNECTED,
82+ BT_ERR_INVALID_STATE, BT_ERR_PROFILE_DISABLED, BT_ERR_INTERNAL_ERROR };
83+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
74 std::string remoteAddr = std::string(deviceId);84 std::string remoteAddr = std::string(deviceId);
75 bool checkRet = CheckDeviceIdParam(remoteAddr);85 bool checkRet = CheckDeviceIdParam(remoteAddr);
76- TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);86+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
77 87 
78 HidHost *profile = HidHost::GetProfile();88 HidHost *profile = HidHost::GetProfile();
79 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);89 BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
80 int32_t errorCode = profile->Disconnect(device);90 int32_t errorCode = profile->Disconnect(device);
81 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());91 HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
82- TAIHE_BT_ASSERT_RETURN_VOID(errorCode == BT_NO_ERROR, errorCode);92+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
83 }93 }
84 94 
85 ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(taihe::string_view deviceId)95 ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(taihe::string_view deviceId)
86 {96 {
97+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
98+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
87 std::string remoteAddr = std::string(deviceId);99 std::string remoteAddr = std::string(deviceId);
88 bool checkRet = CheckDeviceIdParam(remoteAddr);100 bool checkRet = CheckDeviceIdParam(remoteAddr);
89- TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,101+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
90 ohos::bluetooth::constant::ProfileConnectionState::from_value(0));102 ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
91 103 
92 HidHost *profile = HidHost::GetProfile();104 HidHost *profile = HidHost::GetProfile();
@@ -94,7 +106,7 @@ public:
94 int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);106 int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
95 int32_t errorCode = profile->GetDeviceState(device, state);107 int32_t errorCode = profile->GetDeviceState(device, state);
96 int32_t profileState = TaiheUtils::GetProfileConnectionState(state);108 int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
97- TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode,109+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode,
98 ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));110 ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
99 111 
100 return ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);112 return ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
@@ -103,12 +115,14 @@ public:
103 taihe::array<taihe::string> GetConnectedDevices()115 taihe::array<taihe::string> GetConnectedDevices()
104 {116 {
105 HILOGI("enter");117 HILOGI("enter");
118+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
119+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
106 HidHost *profile = HidHost::GetProfile();120 HidHost *profile = HidHost::GetProfile();
107 std::vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };121 std::vector<int> states = { static_cast<int>(BTConnectState::CONNECTED) };
108 std::vector<BluetoothRemoteDevice> devices;122 std::vector<BluetoothRemoteDevice> devices;
109 int errorCode = profile->GetDevicesByStates(states, devices);123 int errorCode = profile->GetDevicesByStates(states, devices);
110 HILOGI("errorCode:%{public}s, devices size:%{public}zu", GetTaiheErrMsg(errorCode).c_str(), devices.size());124 HILOGI("errorCode:%{public}s, devices size:%{public}zu", GetTaiheErrMsg(errorCode).c_str(), devices.size());
111- TAIHE_BT_ASSERT_RETURN(errorCode == BT_NO_ERROR, errorCode, taihe::array<taihe::string>{});125+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode, taihe::array<taihe::string>{});
112 126 
113 std::vector<std::string> deviceVector;127 std::vector<std::string> deviceVector;
114 for (auto &device: devices) {128 for (auto &device: devices) {
@@ -122,9 +136,11 @@ public:
122 ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(taihe::string_view deviceId)136 ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(taihe::string_view deviceId)
123 {137 {
124 HILOGD("start");138 HILOGD("start");
139+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
140+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
125 std::string remoteAddr = std::string(deviceId);141 std::string remoteAddr = std::string(deviceId);
126 bool checkRet = CheckDeviceIdParam(remoteAddr);142 bool checkRet = CheckDeviceIdParam(remoteAddr);
127- TAIHE_BT_ASSERT_RETURN(checkRet, BT_ERR_INVALID_PARAM,143+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
128 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));144 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
129 145 
130 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);146 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
@@ -132,7 +148,7 @@ public:
132 int strategy = 0;148 int strategy = 0;
133 int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);149 int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);
134 HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);150 HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);
135- TAIHE_BT_ASSERT_RETURN(err == BT_NO_ERROR, err,151+ TAIHE_BT_ASSERT_RETURN_VERIFY(err == BT_NO_ERROR, err,
136 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));152 ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
137 153 
138 return ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);154 return ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
@@ -142,16 +158,18 @@ public:
142 ohos::bluetooth::baseProfile::ConnectionStrategy strategy)158 ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
143 {159 {
144 HILOGD("start");160 HILOGD("start");
161+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
162+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
145 std::string remoteAddr = std::string(deviceId);163 std::string remoteAddr = std::string(deviceId);
146 int32_t connStrategy = strategy.get_value();164 int32_t connStrategy = strategy.get_value();
147 bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);165 bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
148- TAIHE_BT_ASSERT_RETURN_VOID(checkRet, BT_ERR_INVALID_PARAM);166+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
149 167 
150 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);168 BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
151 HidHost *profile = HidHost::GetProfile();169 HidHost *profile = HidHost::GetProfile();
152 int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);170 int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);
153 HILOGI("err: %{public}d", err);171 HILOGI("err: %{public}d", err);
154- TAIHE_BT_ASSERT_RETURN_VOID(err == BT_NO_ERROR, err);172+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(err == BT_NO_ERROR, err);
155 }173 }
156private:174private:
157 std::shared_ptr<TaiheBluetoothHidHostObserver> observer_ = nullptr;175 std::shared_ptr<TaiheBluetoothHidHostObserver> observer_ = nullptr;
@@ -163,10 +181,492 @@ private:
163 // as the parameters in the constructor of the actual implementation class.181 // as the parameters in the constructor of the actual implementation class.
164 return taihe::make_holder<HidHostProfileImpl, ::ohos::bluetooth::hid::HidHostProfile>();182 return taihe::make_holder<HidHostProfileImpl, ::ohos::bluetooth::hid::HidHostProfile>();
165}183}
184+ 
185+std::shared_ptr<TaiheBluetoothHidDeviceObserver> g_hidDeviceObserver =
186+ std::make_shared<TaiheBluetoothHidDeviceObserver>();
187+ 
188+class HidDeviceProfileImpl {
189+public:
190+ HidDeviceProfileImpl()
191+ {
192+ observer_ = g_hidDeviceObserver;
193+ HidDevice *profile = HidDevice::GetProfile();
194+ profile->RegisterObserver(g_hidDeviceObserver);
195+ }
196+ 
197+ void OnConnectionStateChange(::taihe::callback_view<void(
198+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)> callback)
199+ {
200+ if (observer_) {
201+ std::unique_lock<std::shared_mutex> guard(observer_->connectionStateChangeLock_);
202+ auto eventCb = ::taihe::optional<::taihe::callback<void(
203+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>>{std::in_place_t{}, callback};
204+ auto& callbackVec = observer_->connectionStateChangeVec_;
205+ if (std::find(callbackVec.begin(), callbackVec.end(), eventCb) != callbackVec.end()) {
206+ return;
207+ }
208+ callbackVec.emplace_back(eventCb);
209+ }
210+ }
211+ 
212+ void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(
213+ ::ohos::bluetooth::baseProfile::StateChangeParam const& data)>> callback)
214+ {
215+ if (observer_) {
216+ std::unique_lock<std::shared_mutex> guard(observer_->connectionStateChangeLock_);
217+ auto& callbackVec = observer_->connectionStateChangeVec_;
218+ if (callback.has_value()) {
219+ callbackVec.erase(
220+ std::remove_if(callbackVec.begin(), callbackVec.end(),
221+ [callback](const ::taihe::optional<
222+ ::taihe::callback<void(::ohos::bluetooth::baseProfile::StateChangeParam const& data)>>& it) {
223+ return it == callback;
224+ }),
225+ callbackVec.end());
226+ } else {
227+ callbackVec.clear();
228+ }
229+ }
230+ }
231+ 
232+ void OnSetProtocol(::taihe::callback_view<void(
233+ ::ohos::bluetooth::hid::ProtocolData const& data)> callback)
234+ {
235+ if (observer_) {
236+ std::unique_lock<std::shared_mutex> guard(observer_->setProtocolLock_);
237+ auto eventCb = ::taihe::optional<::taihe::callback<void(
238+ ::ohos::bluetooth::hid::ProtocolData const& data)>>{std::in_place_t{}, callback};
239+ auto& callbackVec = observer_->setProtocolVec_;
240+ if (std::find(callbackVec.begin(), callbackVec.end(), eventCb) != callbackVec.end()) {
241+ return;
242+ }
243+ callbackVec.emplace_back(eventCb);
244+ }
245+ }
246+ 
247+ void OffSetProtocol(::taihe::optional_view<::taihe::callback<void(
248+ ::ohos::bluetooth::hid::ProtocolData const& data)>> callback)
249+ {
250+ if (observer_) {
251+ std::unique_lock<std::shared_mutex> guard(observer_->setProtocolLock_);
252+ auto& callbackVec = observer_->setProtocolVec_;
253+ if (callback.has_value()) {
254+ callbackVec.erase(
255+ std::remove_if(callbackVec.begin(), callbackVec.end(),
256+ [callback](const ::taihe::optional<
257+ ::taihe::callback<void(::ohos::bluetooth::hid::ProtocolData const& data)>>& it) {
258+ return it == callback;
259+ }),
260+ callbackVec.end());
261+ } else {
262+ callbackVec.clear();
263+ }
264+ }
265+ }
266+ 
267+ void OnInterruptDataReceived(::taihe::callback_view<void(
268+ ::ohos::bluetooth::hid::InterruptData const& data)> callback)
269+ {
270+ if (observer_) {
271+ std::unique_lock<std::shared_mutex> guard(observer_->interruptDataReceivedLock_);
272+ auto eventCb = ::taihe::optional<::taihe::callback<void(
273+ ::ohos::bluetooth::hid::InterruptData const& data)>>{std::in_place_t{}, callback};
274+ auto& callbackVec = observer_->interruptDataReceivedVec_;
275+ if (std::find(callbackVec.begin(), callbackVec.end(), eventCb) != callbackVec.end()) {
276+ return;
277+ }
278+ callbackVec.emplace_back(eventCb);
279+ }
280+ }
281+ 
282+ void OffInterruptDataReceived(::taihe::optional_view<::taihe::callback<void(
283+ ::ohos::bluetooth::hid::InterruptData const& data)>> callback)
284+ {
285+ if (observer_) {
286+ std::unique_lock<std::shared_mutex> guard(observer_->interruptDataReceivedLock_);
287+ auto& callbackVec = observer_->interruptDataReceivedVec_;
288+ if (callback.has_value()) {
289+ callbackVec.erase(
290+ std::remove_if(callbackVec.begin(), callbackVec.end(),
291+ [callback](const ::taihe::optional<
292+ ::taihe::callback<void(::ohos::bluetooth::hid::InterruptData const& data)>>& it) {
293+ return it == callback;
294+ }),
295+ callbackVec.end());
296+ } else {
297+ callbackVec.clear();
298+ }
299+ }
300+ }
301+ 
302+ void OnSetReport(::taihe::callback_view<void(
303+ ::ohos::bluetooth::hid::SetReportData const& data)> callback)
304+ {
305+ if (observer_) {
306+ std::unique_lock<std::shared_mutex> guard(observer_->setReportLock_);
307+ auto eventCb = ::taihe::optional<::taihe::callback<void(
308+ ::ohos::bluetooth::hid::SetReportData const& data)>>{std::in_place_t{}, callback};
309+ auto& callbackVec = observer_->setReportVec_;
310+ if (std::find(callbackVec.begin(), callbackVec.end(), eventCb) != callbackVec.end()) {
311+ return;
312+ }
313+ callbackVec.emplace_back(eventCb);
314+ }
315+ }
316+ 
317+ void OffSetReport(::taihe::optional_view<::taihe::callback<void(
318+ ::ohos::bluetooth::hid::SetReportData const& data)>> callback)
319+ {
320+ if (observer_) {
321+ std::unique_lock<std::shared_mutex> guard(observer_->setReportLock_);
322+ auto& callbackVec = observer_->setReportVec_;
323+ if (callback.has_value()) {
324+ callbackVec.erase(
325+ std::remove_if(callbackVec.begin(), callbackVec.end(),
326+ [callback](const ::taihe::optional<
327+ ::taihe::callback<void(::ohos::bluetooth::hid::SetReportData const& data)>>& it) {
328+ return it == callback;
329+ }),
330+ callbackVec.end());
331+ } else {
332+ callbackVec.clear();
333+ }
334+ }
335+ }
336+ 
337+ void OnGetReport(::taihe::callback_view<void(
338+ ::ohos::bluetooth::hid::GetReportData const& data)> callback)
339+ {
340+ if (observer_) {
341+ std::unique_lock<std::shared_mutex> guard(observer_->getReportLock_);
342+ auto eventCb = ::taihe::optional<::taihe::callback<void(
343+ ::ohos::bluetooth::hid::GetReportData const& data)>>{std::in_place_t{}, callback};
344+ auto& callbackVec = observer_->getReportVec_;
345+ if (std::find(callbackVec.begin(), callbackVec.end(), eventCb) != callbackVec.end()) {
346+ return;
347+ }
348+ callbackVec.emplace_back(eventCb);
349+ }
350+ }
351+ 
352+ void OffGetReport(::taihe::optional_view<::taihe::callback<void(
353+ ::ohos::bluetooth::hid::GetReportData const& data)>> callback)
354+ {
355+ if (observer_) {
356+ std::unique_lock<std::shared_mutex> guard(observer_->getReportLock_);
357+ auto& callbackVec = observer_->getReportVec_;
358+ if (callback.has_value()) {
359+ callbackVec.erase(
360+ std::remove_if(callbackVec.begin(), callbackVec.end(),
361+ [callback](const ::taihe::optional<
362+ ::taihe::callback<void(::ohos::bluetooth::hid::GetReportData const& data)>>& it) {
363+ return it == callback;
364+ }),
365+ callbackVec.end());
366+ } else {
367+ callbackVec.clear();
368+ }
369+ }
370+ }
371+ 
372+ void OnVirtualCableUnplug(::taihe::callback_view<void(::ohos::bluetooth::hid::UndefinedType const& data)> callback)
373+ {
374+ if (observer_) {
375+ std::unique_lock<std::shared_mutex> guard(observer_->virtualCableUnplugLock_);
376+ auto eventCb = ::taihe::optional<::taihe::callback<void(
377+ ::ohos::bluetooth::hid::UndefinedType const& data)>>{std::in_place_t{}, callback};
378+ auto& callbackVec = observer_->virtualCableUnplugVec_;
379+ if (std::find(callbackVec.begin(), callbackVec.end(), eventCb) != callbackVec.end()) {
380+ return;
381+ }
382+ callbackVec.emplace_back(eventCb);
383+ }
384+ }
385+ 
386+ void OffVirtualCableUnplug(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::hid::UndefinedType const& data)>> callback)
387+ {
388+ if (observer_) {
389+ std::unique_lock<std::shared_mutex> guard(observer_->virtualCableUnplugLock_);
390+ auto& callbackVec = observer_->virtualCableUnplugVec_;
391+ if (callback.has_value()) {
392+ callbackVec.erase(
393+ std::remove_if(callbackVec.begin(), callbackVec.end(),
394+ [callback](const ::taihe::optional<
395+ ::taihe::callback<void(::ohos::bluetooth::hid::UndefinedType const& data)>>& it) {
396+ return it == callback;
397+ }),
398+ callbackVec.end());
399+ } else {
400+ callbackVec.clear();
401+ }
402+ }
403+ }
404+ 
405+ void Connect(::ohos::bluetooth::common::BluetoothAddress const& deviceId)
406+ {
407+ HILOGI("enter");
408+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
409+ BT_ERR_PROFILE_DISABLED, BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER };
410+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
411+ AddressInfo addressInfo;
412+ addressInfo.SetAddress(std::string(deviceId.address));
413+ addressInfo.SetAddressType(static_cast<uint8_t>(deviceId.addressType));
414+ addressInfo.SetRawAddressType(static_cast<uint8_t>(deviceId.rawAddressType.value_or(::ohos::bluetooth::common::BluetoothRawAddressType::key_t::PUBLIC)));
415+ HidDevice *profile = HidDevice::GetProfile();
416+ int32_t errorCode = profile->Connect(addressInfo);
417+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
418+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
419+ }
420+ 
421+ void Disconnect()
422+ {
423+ HILOGI("enter");
424+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
425+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER };
426+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
427+ HidDevice *profile = HidDevice::GetProfile();
428+ int32_t errorCode = profile->Disconnect();
429+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
430+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
431+ }
432+ 
433+ void ReportError(::ohos::bluetooth::hid::ErrorReason error)
434+ {
435+ HILOGI("enter");
436+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
437+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER, BT_ERR_HID_DEVICE_NOT_CONNECTED };
438+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
439+ HidDevice *profile = HidDevice::GetProfile();
440+ int32_t errorCode = profile->ReportError(static_cast<ErrorReason>(error.get_value()));
441+ HILOGI("errorCode:%{public}d", errorCode);
442+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
443+ }
444+ 
445+ void UnregisterHidDevice()
446+ {
447+ HILOGI("enter");
448+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
449+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER };
450+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
451+ HidDevice *profile = HidDevice::GetProfile();
452+ if (observer_) {
453+ std::unique_lock<std::shared_mutex> guard(observer_->appStatusChangeLock_);
454+ observer_->appStatusChangeVec_.clear();
455+ }
456+ int32_t errorCode = profile->UnregisterHidDevice();
457+ HILOGI("errorCode:%{public}d", errorCode);
458+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
459+ }
460+ 
461+ void SendReport(int32_t id, ::taihe::array_view<uint8_t> reportData)
462+ {
463+ HILOGI("enter");
464+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
465+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER, BT_ERR_HID_DEVICE_NOT_CONNECTED };
466+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
467+ std::vector<uint8_t> data;
468+ if (reportData.size() > 0) {
469+ data.assign(reportData.data(), reportData.data() + reportData.size());
470+ }
471+ HidDevice *profile = HidDevice::GetProfile();
472+ int32_t errorCode = profile->SendReport(id, data);
473+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
474+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
475+ }
476+ 
477+ void ReplyReport(::ohos::bluetooth::hid::ReportType type, int32_t id, ::taihe::array_view<uint8_t> reportData)
478+ {
479+ HILOGI("enter");
480+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
481+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APP_NOT_REGISTER, BT_ERR_HID_DEVICE_NOT_CONNECTED };
482+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
483+ std::vector<uint8_t> data;
484+ if (reportData.size() > 0) {
485+ data.assign(reportData.data(), reportData.data() + reportData.size());
486+ }
487+ HidDevice *profile = HidDevice::GetProfile();
488+ int32_t errorCode = profile->ReplyReport(static_cast<ReportType>(type.get_value()), id, data);
489+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
490+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
491+ }
492+ 
493+ void RegisterHidDevice(::ohos::bluetooth::hid::HidDeviceSdp const& sdp,
494+ ::ohos::bluetooth::hid::HidDeviceQos const& inQos,
495+ ::ohos::bluetooth::hid::HidDeviceQos const& outQos,
496+ ::taihe::callback_view<void(bool data)> callback)
497+ {
498+ HILOGI("enter");
499+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INVALID_STATE,
500+ BT_ERR_INTERNAL_ERROR, BT_ERR_HID_APPLICATION_NOT_IN_FOREGROUND,
501+ BT_ERR_HID_APP_HAS_BEEN_REGISTERED, BT_ERR_HID_APP_NOT_REGISTER,
502+ BT_ERR_HID_DEVICE_NOT_CONNECTED };
503+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
504+ 
505+ // Validate SDP fields
506+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSDPSettingParam(std::string(sdp.name), MAX_NAME_SIZE),
507+ BT_ERR_INVALID_PARAM);
508+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSDPSettingParam(std::string(sdp.description), MAX_DESCRIPTION_SIZE),
509+ BT_ERR_INVALID_PARAM);
510+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSDPSettingParam(std::string(sdp.provider), MAX_PROVIDER_SIZE),
511+ BT_ERR_INVALID_PARAM);
512+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidSubclass(sdp.subclass.get_value()),
513+ BT_ERR_INVALID_PARAM);
514+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(sdp.descriptors.size() > 0 && sdp.descriptors.size() <= MAX_DESCRIPTOR_SIZE,
515+ BT_ERR_INVALID_PARAM);
516+ 
517+ // Validate QoS serviceType
518+ if (inQos.serviceType.has_value()) {
519+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidServiceType(inQos.serviceType.value().get_value()),
520+ BT_ERR_INVALID_PARAM);
521+ }
522+ if (outQos.serviceType.has_value()) {
523+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(IsValidServiceType(outQos.serviceType.value().get_value()),
524+ BT_ERR_INVALID_PARAM);
525+ }
526+ 
527+ BluetoothHidDeviceSdp sdpSetting(
528+ bluetooth::SdpSetting(std::string(sdp.name), std::string(sdp.description),
529+ std::string(sdp.provider), sdp.subclass.get_value(),
530+ std::vector<uint8_t>(sdp.descriptors.data(), sdp.descriptors.data() + sdp.descriptors.size())));
531+ auto convertQos = [](::ohos::bluetooth::hid::HidDeviceQos const& qos) {
532+ int32_t serviceType = static_cast<int32_t>(ServiceType::SERVICE_BEST_EFFORT);
533+ if (qos.serviceType.has_value()) {
534+ serviceType = static_cast<int32_t>(qos.serviceType.value().get_key());
535+ }
536+ int32_t tokenRate = qos.tokenRate.value_or(0);
537+ int32_t tokenBucketSize = qos.tokenBucketSize.value_or(0);
538+ int32_t peakBandwidth = qos.peakBandwidth.value_or(0);
539+ int32_t latency = qos.latency.value_or(-1);
540+ int32_t delayVariation = qos.delayVariation.value_or(-1);
541+ return BluetoothHidDeviceQos(
542+ bluetooth::QosSetting(serviceType, tokenRate, tokenBucketSize,
543+ peakBandwidth, latency, delayVariation));
544+ };
545+ BluetoothHidDeviceQos inQosSetting = convertQos(inQos);
546+ BluetoothHidDeviceQos outQosSetting = convertQos(outQos);
547+ 
548+ HILOGI("sdpSetting: name_=%{public}s, description_=%{public}s, provider_=%{public}s, "
549+ "subclass_=%{public}d, sdpSettings_.size=%{public}zu",
550+ sdpSetting.name_.c_str(), sdpSetting.description_.c_str(),
551+ sdpSetting.provider_.c_str(), sdpSetting.subclass_,
552+ sdpSetting.sdpSettings_.size());
553+ HILOGI("inQosSetting: serviceType_=%{public}d, tokenRate_=%{public}d, "
554+ "tokenBucketSize_=%{public}d, peakBandwidth_=%{public}d, latency_=%{public}d, delayVariation_=%{public}d",
555+ inQosSetting.serviceType_, inQosSetting.tokenRate_,
556+ inQosSetting.tokenBucketSize_, inQosSetting.peakBandwidth_,
557+ inQosSetting.latency_, inQosSetting.delayVariation_);
558+ HILOGI("outQosSetting: serviceType_=%{public}d, tokenRate_=%{public}d, "
559+ "tokenBucketSize_=%{public}d, peakBandwidth_=%{public}d, latency_=%{public}d, delayVariation_=%{public}d",
560+ outQosSetting.serviceType_, outQosSetting.tokenRate_,
561+ outQosSetting.tokenBucketSize_, outQosSetting.peakBandwidth_,
562+ outQosSetting.latency_, outQosSetting.delayVariation_);
563+ 
564+ HidDevice *profile = HidDevice::GetProfile();
565+ int32_t errorCode = profile->RegisterHidDevice(sdpSetting, inQosSetting, outQosSetting);
566+ HILOGI("errorCode:%{public}s", GetTaiheErrMsg(errorCode).c_str());
567+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(errorCode == BT_NO_ERROR, errorCode);
568+ if (observer_) {
569+ std::unique_lock<std::shared_mutex> guard(observer_->appStatusChangeLock_);
570+ auto eventCb = ::taihe::optional<::taihe::callback<void(bool)>>{std::in_place_t{}, callback};
571+ auto& callbackVec = observer_->appStatusChangeVec_;
572+ if (std::find(callbackVec.begin(), callbackVec.end(), eventCb) != callbackVec.end()) {
573+ return;
574+ }
575+ callbackVec.emplace_back(eventCb);
576+ }
577+ }
578+ 
579+ ::ohos::bluetooth::constant::ProfileConnectionState GetConnectionState(::taihe::string_view deviceId)
580+ {
581+ HILOGD("enter");
582+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
583+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
584+ std::string remoteAddr = std::string(deviceId);
585+ bool checkRet = CheckDeviceIdParam(remoteAddr);
586+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
587+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(0));
588+ 
589+ HidDevice *profile = HidDevice::GetProfile();
590+ BluetoothRemoteDevice device(remoteAddr, BT_TRANSPORT_BREDR);
591+ int32_t state = static_cast<int32_t>(BTConnectState::DISCONNECTED);
592+ int32_t errorCode = profile->GetConnectionState(device, state);
593+ int32_t profileState = TaiheUtils::GetProfileConnectionState(state);
594+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode,
595+ ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState));
596+ return ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileState);
597+ }
598+ 
599+ ::taihe::array<::taihe::string> GetConnectedDevices()
600+ {
601+ HILOGI("enter");
602+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
603+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
604+ HidDevice *profile = HidDevice::GetProfile();
605+ std::vector<BluetoothRemoteDevice> devices;
606+ int errorCode = profile->GetConnectedDevices(devices);
607+ HILOGI("errorCode:%{public}s, devices size:%{public}zu",
608+ GetTaiheErrMsg(errorCode).c_str(), devices.size());
609+ TAIHE_BT_ASSERT_RETURN_VERIFY(errorCode == BT_NO_ERROR, errorCode, taihe::array<taihe::string>{});
610+ 
611+ std::vector<std::string> deviceVector;
612+ for (auto &device : devices) {
613+ deviceVector.push_back(device.GetDeviceAddr());
614+ }
615+ return deviceVector.empty() ? taihe::array<taihe::string>{}
616+ : taihe::array<::taihe::string>(taihe::copy_data_t{}, deviceVector.data(), deviceVector.size());
617+ }
618+ 
619+ ::ohos::bluetooth::baseProfile::ConnectionStrategy GetConnectionStrategySync(::taihe::string_view deviceId)
620+ {
621+ HILOGD("start");
622+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
623+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
624+ std::string remoteAddr = std::string(deviceId);
625+ bool checkRet = CheckDeviceIdParam(remoteAddr);
626+ TAIHE_BT_ASSERT_RETURN_VERIFY(checkRet, BT_ERR_INVALID_PARAM,
627+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(0));
628+ 
629+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
630+ HidDevice *profile = HidDevice::GetProfile();
631+ int strategy = 0;
632+ int32_t err = profile->GetConnectStrategy(remoteDevice, strategy);
633+ HILOGI("err: %{public}d, strategy: %{public}d", err, strategy);
634+ TAIHE_BT_ASSERT_RETURN_VERIFY(err == BT_NO_ERROR, err,
635+ ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy));
636+ return ::ohos::bluetooth::baseProfile::ConnectionStrategy::from_value(strategy);
637+ }
638+ 
639+ void SetConnectionStrategySync(::taihe::string_view deviceId,
640+ ::ohos::bluetooth::baseProfile::ConnectionStrategy strategy)
641+ {
642+ HILOGD("start");
643+ std::vector<int32_t> validErrCodes = { BT_ERR_INVALID_PARAM, BT_ERR_INTERNAL_ERROR };
644+ TAIHE_BT_CONTEXT_WITHOUT_HA(validErrCodes);
645+ std::string remoteAddr = std::string(deviceId);
646+ int32_t connStrategy = strategy.get_value();
647+ bool checkRet = CheckSetConnectStrategyParam(remoteAddr, connStrategy);
648+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(checkRet, BT_ERR_INVALID_PARAM);
649+ 
650+ BluetoothRemoteDevice remoteDevice(remoteAddr, BT_TRANSPORT_BREDR);
651+ HidDevice *profile = HidDevice::GetProfile();
652+ int32_t err = profile->SetConnectStrategy(remoteDevice, connStrategy);
653+ HILOGI("err: %{public}d", err);
654+ TAIHE_BT_ASSERT_RETURN_VOID_VERIFY(err == BT_NO_ERROR, err);
655+ }
656+ 
657+private:
658+ std::shared_ptr<TaiheBluetoothHidDeviceObserver> observer_ = nullptr;
659+};
660+ 
661+::ohos::bluetooth::hid::HidDeviceProfile CreateHidDeviceProfile()
662+{
663+ return taihe::make_holder<HidDeviceProfileImpl, ::ohos::bluetooth::hid::HidDeviceProfile>();
664+}
166} // namespace Bluetooth665} // namespace Bluetooth
167} // namespace OHOS666} // namespace OHOS
168 667 
169// Since these macros are auto-generate, lint will cause false positive.668// Since these macros are auto-generate, lint will cause false positive.
170// NOLINTBEGIN669// NOLINTBEGIN
171TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile);670TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile);
671+TH_EXPORT_CPP_API_CreateHidDeviceProfile(OHOS::Bluetooth::CreateHidDeviceProfile);
172// NOLINTEND672// NOLINTEND
Aframeworks/ets/taihe/bluetooth_hid/src/taihe_bluetooth_hid_device_observer.cpp+148-0
@@ -0,0 +1,148 @@
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+#include "taihe_event_module.h"
28+ 
29+namespace OHOS {
30+namespace Bluetooth {
31+ 
32+TaiheBluetoothHidDeviceObserver::TaiheBluetoothHidDeviceObserver()
33+{}
34+ 
35+void TaiheBluetoothHidDeviceObserver::OnAppStatusChanged(int state)
36+{
37+ HILOGI("state: %{public}d", state);
38+ bool shouldDeregister = (state == HID_DEVICE_UNREGISTERED);
39+ {
40+ std::shared_lock<std::shared_mutex> guard(appStatusChangeLock_);
41+ for (auto callback : appStatusChangeVec_) {
42+ if (callback) {
43+ (*callback)(state != 0);
44+ }
45+ }
46+ }
47+ if (shouldDeregister) {
48+ std::unique_lock<std::shared_mutex> guard(appStatusChangeLock_);
49+ appStatusChangeVec_.clear();
50+ }
51+}
52+ 
53+void TaiheBluetoothHidDeviceObserver::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state)
54+{
55+ std::shared_lock<std::shared_mutex> guard(connectionStateChangeLock_);
56+ HILOGD("enter, remote device address: %{public}s, state: %{public}d",
57+ GET_ENCRYPT_ADDR(device), state);
58+ ::taihe::string deviceId_(device.GetDeviceAddr());
59+ int32_t profileConnectionState = TaiheUtils::GetProfileConnectionState(state);
60+ auto state_ = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState);
61+ auto taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam {
62+ .deviceId = deviceId_,
63+ .state = state_,
64+ .cause = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(0),
65+ };
66+ for (auto callback : connectionStateChangeVec_) {
67+ if (callback) {
68+ (*callback)(taiheResult);
69+ }
70+ }
71+}
72+ 
73+void TaiheBluetoothHidDeviceObserver::OnGetReport(int type, int id, uint16_t bufferSize)
74+{
75+ std::shared_lock<std::shared_mutex> guard(getReportLock_);
76+ HILOGD("type: %{public}d, id: %{public}d, bufferSize: %{public}d", type, id, bufferSize);
77+ auto taiheResult = ::ohos::bluetooth::hid::GetReportData {
78+ .type = ::ohos::bluetooth::hid::ReportType::from_value(type),
79+ .id = id,
80+ .bufferSize = static_cast<int32_t>(bufferSize),
81+ };
82+ for (auto callback : getReportVec_) {
83+ if (callback) {
84+ (*callback)(taiheResult);
85+ }
86+ }
87+}
88+ 
89+void TaiheBluetoothHidDeviceObserver::OnSetProtocol(int protocol)
90+{
91+ std::shared_lock<std::shared_mutex> guard(setProtocolLock_);
92+ HILOGD("protocol: %{public}d", protocol);
93+ auto taiheResult = ::ohos::bluetooth::hid::ProtocolData {
94+ .protocol = ::ohos::bluetooth::hid::ProtocolType::from_value(protocol),
95+ };
96+ for (auto callback : setProtocolVec_) {
97+ if (callback) {
98+ (*callback)(taiheResult);
99+ }
100+ }
101+}
102+ 
103+void TaiheBluetoothHidDeviceObserver::OnInterruptDataReceived(int id, const std::vector<uint8_t> &data)
104+{
105+ std::shared_lock<std::shared_mutex> guard(interruptDataReceivedLock_);
106+ HILOGD("id: %{public}d, data size: %{public}zu", id, data.size());
107+ auto taiheResult = ::ohos::bluetooth::hid::InterruptData {
108+ .id = id,
109+ .data = data.empty() ? taihe::array<uint8_t>{}
110+ : taihe::array<uint8_t>(taihe::copy_data_t{}, data.data(), data.size()),
111+ };
112+ for (auto callback : interruptDataReceivedVec_) {
113+ if (callback) {
114+ (*callback)(taiheResult);
115+ }
116+ }
117+}
118+ 
119+void TaiheBluetoothHidDeviceObserver::OnSetReport(int type, int id, const std::vector<uint8_t> &data)
120+{
121+ std::shared_lock<std::shared_mutex> guard(setReportLock_);
122+ HILOGD("type: %{public}d, id: %{public}d, data size: %{public}zu", type, id, data.size());
123+ auto taiheResult = ::ohos::bluetooth::hid::SetReportData {
124+ .type = ::ohos::bluetooth::hid::ReportType::from_value(type),
125+ .id = id,
126+ .data = data.empty() ? taihe::array<uint8_t>{}
127+ : taihe::array<uint8_t>(taihe::copy_data_t{}, data.data(), data.size()),
128+ };
129+ for (auto callback : setReportVec_) {
130+ if (callback) {
131+ (*callback)(taiheResult);
132+ }
133+ }
134+}
135+ 
136+void TaiheBluetoothHidDeviceObserver::OnVirtualCableUnplug()
137+{
138+ std::shared_lock<std::shared_mutex> guard(virtualCableUnplugLock_);
139+ HILOGD("enter");
140+ for (auto callback : virtualCableUnplugVec_) {
141+ if (callback) {
142+ (*callback)(::ohos::bluetooth::hid::UndefinedType::make_undefined());
143+ }
144+ }
145+}
146+ 
147+} // namespace Bluetooth
148+} // namespace OHOS