已开启
ble_bluetooth_change_test #1992
王乾宇创建于 7月24日
ble_bluetooth_change_test #1992
已开启
共 73 个文件变更+6046-15
| @@ -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", |
| @@ -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_PLAYING | 107 | STATE_PLAYING |
| 106 | } | 108 | } |
| 107 | 109 | ||
| 110 | +enum CodecFrameLength: i32 { | ||
| 111 | + CODEC_FRAME_LENGTH_5MS = 0, | ||
| 112 | + CODEC_FRAME_LENGTH_10MS = 1 | ||
| 113 | +} | ||
| 114 | + | ||
| 108 | struct CodecInfo { | 115 | struct 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 | + | ||
| 115 | function CreateA2dpSrcProfile(): A2dpSourceProfile; | 130 | function CreateA2dpSrcProfile(): A2dpSourceProfile; |
| @@ -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); |
| @@ -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; | ||
| @@ -32,6 +32,9 @@ | |||
| 32 | namespace OHOS { | 32 | namespace OHOS { |
| 33 | namespace Bluetooth { | 33 | namespace Bluetooth { |
| 34 | std::shared_ptr<TaiheBluetoothAccessObserver> g_accessCallback = TaiheBluetoothAccessObserver::GetInstance(); | 34 | std::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 | ||
| 36 | void RestrictBluetooth() | 39 | void 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 | } // Bluetooth | 243 | } // Bluetooth |
| 212 | } // OHOS | 244 | } // OHOS |
| 213 | 245 | ||
| @@ -228,4 +260,6 @@ TH_EXPORT_CPP_API_DeletePersistentDeviceId(OHOS::Bluetooth::DeletePersistentDevi | |||
| 228 | TH_EXPORT_CPP_API_AddPersistentDeviceId(OHOS::Bluetooth::AddPersistentDeviceId); | 260 | TH_EXPORT_CPP_API_AddPersistentDeviceId(OHOS::Bluetooth::AddPersistentDeviceId); |
| 229 | TH_EXPORT_CPP_API_NotifyDialogResult(OHOS::Bluetooth::NotifyDialogResult); | 261 | TH_EXPORT_CPP_API_NotifyDialogResult(OHOS::Bluetooth::NotifyDialogResult); |
| 230 | TH_EXPORT_CPP_API_FactoryResetSync(OHOS::Bluetooth::FactoryResetSync); | 262 | TH_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 | // NOLINTEND | 265 | // NOLINTEND |
| @@ -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 | +} | ||
| @@ -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 | + | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 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 | + | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | + | ||
| 35 | + | ||
| 36 | + | ||
| 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 | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 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 | ||
| @@ -22,7 +22,8 @@ copy_taihe_idl("bluetooth_ble_taihe") { | |||
| 22 | "idl/ohos.bluetooth.ble.taihe", | 22 | "idl/ohos.bluetooth.ble.taihe", |
| 23 | ] | 23 | ] |
| 24 | deps = [ | 24 | deps = [ |
| 25 | - "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetooth_constant_taihe" | 25 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetooth_constant_taihe", |
| 26 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_connection:bluetooth_connection_taihe" | ||
| 26 | ] | 27 | ] |
| 27 | } | 28 | } |
| 28 | 29 | ||
| @@ -86,6 +87,7 @@ taihe_shared_library("bluetoothBle_taihe_native") { | |||
| 86 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_async_work.cpp", | 87 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_async_work.cpp", |
| 87 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_ha_event_utils.cpp", | 88 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_ha_event_utils.cpp", |
| 88 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_native_object.cpp", | 89 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_native_object.cpp", |
| 90 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp", | ||
| 89 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/parser/taihe_parser_utils.cpp", | 91 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/parser/taihe_parser_utils.cpp", |
| 90 | ] | 92 | ] |
| 91 | deps = [ | 93 | deps = [ |
| @@ -20,6 +20,7 @@ | |||
| 20 | static { loadLibraryWithPermissionCheck("bluetoothBle_taihe_native.z", "@ohos.bluetooth.ble") } | 20 | static { loadLibraryWithPermissionCheck("bluetoothBle_taihe_native.z", "@ohos.bluetooth.ble") } |
| 21 | """) | 21 | """) |
| 22 | from ohos.bluetooth.constant use ProfileConnectionState; | 22 | from ohos.bluetooth.constant use ProfileConnectionState; |
| 23 | +from ohos.bluetooth.connection use BluetoothTransport; | ||
| 23 | 24 | ||
| 24 | struct ScanReport { | 25 | struct ScanReport { |
| 25 | reportType: ScanReportType; | 26 | reportType: ScanReportType; |
| @@ -231,6 +232,21 @@ struct GattPermissions { | |||
| 231 | 232 | ||
| 232 | function StopAdvertising(): void; | 233 | function 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 | + | ||
| 234 | interface GattClientDevice { | 250 | interface 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 | ||
| 264 | function CreateGattClientDevice(deviceId: String): GattClientDevice; | 337 | function 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 | ||
| 279 | function CreateGattServer(): GattServer; | 389 | function 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 | + | ||
| 321 | interface BleScanner { | 453 | interface 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 | ||
| 329 | function CreateBleScanner(): BleScanner; | 464 | function CreateBleScanner(): BleScanner; |
| @@ -22,9 +22,9 @@ | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | - | ||
| 26 | - | ||
| 27 | 25 | ||
| 26 | + | ||
| 27 | + | ||
| 28 | 28 | ||
| 29 | namespace OHOS { | 29 | namespace OHOS { |
| 30 | namespace Bluetooth { | 30 | namespace 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 Bluetooth | 52 | } // namespace Bluetooth |
| @@ -17,8 +17,12 @@ | |||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 20 | 23 | ||
| 21 | 24 | ||
| 25 | + | ||
| 22 | 26 | ||
| 23 | namespace OHOS { | 27 | namespace OHOS { |
| 24 | namespace Bluetooth { | 28 | namespace 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 Bluetooth | 49 | } // namespace Bluetooth |
| 43 | } // namespace OHOS | 50 | } // namespace OHOS |
| @@ -30,6 +30,8 @@ public: | |||
| 30 | uintptr_t StartScanPromise(const ohos::bluetooth::ble::ScanFilterNullValue &filters, | 30 | uintptr_t StartScanPromise(const ohos::bluetooth::ble::ScanFilterNullValue &filters, |
| 31 | taihe::optional_view<ohos::bluetooth::ble::ScanOptions> options); | 31 | taihe::optional_view<ohos::bluetooth::ble::ScanOptions> options); |
| 32 | uintptr_t StopScanPromise(); | 32 | uintptr_t StopScanPromise(); |
| 33 | + void OnBLEDeviceFind(::taihe::callback_view<void(::ohos::bluetooth::ble::ScanReport const& data)> callback); | ||
| 34 | + void OffBleDeviceFind(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::ScanReport const& data)>> callback); | ||
| 33 | 35 | ||
| 34 | const std::shared_ptr<BleCentralManager> &GetBleCentralManager() | 36 | const std::shared_ptr<BleCentralManager> &GetBleCentralManager() |
| 35 | { | 37 | { |
| @@ -47,6 +47,47 @@ public: | |||
| 47 | taihe::string GetDeviceNameSync(); | 47 | taihe::string GetDeviceNameSync(); |
| 48 | static int GattStatusFromService(int status); | 48 | static int GattStatusFromService(int status); |
| 49 | 49 | ||
| 50 | + ::ohos::bluetooth::ble::PhyValue ReadPhySync(); | ||
| 51 | + void SetPhySync(::ohos::bluetooth::ble::PhyValue const& phyValue); | ||
| 52 | + ::ohos::bluetooth::ble::GattRspContext WriteCharacteristicValueWithContextSync( | ||
| 53 | + ::ohos::bluetooth::ble::BLECharacteristic const& characteristic, | ||
| 54 | + ::ohos::bluetooth::ble::GattWriteType writeType); | ||
| 55 | + void WriteDescriptorValueSync(::ohos::bluetooth::ble::BLEDescriptor const& descriptor); | ||
| 56 | + ::taihe::array<::ohos::bluetooth::ble::GattService> GetServicesSync(); | ||
| 57 | + | ||
| 58 | + void OnBlePhyUpdate(::taihe::callback_view<void(::ohos::bluetooth::ble::PhyValue const& data)> callback); | ||
| 59 | + void OffBlePhyUpdate(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::PhyValue const& data)>> callback); | ||
| 60 | + | ||
| 61 | + void SetCharacteristicChangeNotificationSync( | ||
| 62 | + ::ohos::bluetooth::ble::BLECharacteristic const& characteristic, bool enable); | ||
| 63 | + | ||
| 64 | + int32_t GetRssiValueSync(); | ||
| 65 | + int32_t SetBLEMtuSync(int32_t mtu); | ||
| 66 | + | ||
| 67 | + void WriteCharacteristicValueSync( | ||
| 68 | + ::ohos::bluetooth::ble::BLECharacteristic const& characteristic, | ||
| 69 | + ::ohos::bluetooth::ble::GattWriteType writeType); | ||
| 70 | + | ||
| 71 | + void OnBLEMtuChange(::taihe::callback_view<void(int32_t data)> callback); | ||
| 72 | + void OffBLEMtuChange(::taihe::optional_view<::taihe::callback<void(int32_t data)>> callback); | ||
| 73 | + | ||
| 74 | + void OnServiceChange(::taihe::callback_view<void()> callback); | ||
| 75 | + void OffServiceChange(::taihe::optional_view<::taihe::callback<void()>> callback); | ||
| 76 | + | ||
| 77 | + void OnBLECharacteristicChange( | ||
| 78 | + ::taihe::callback_view<void(::ohos::bluetooth::ble::BLECharacteristic const& data)> callback); | ||
| 79 | + void OffBLECharacteristicChange( | ||
| 80 | + ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLECharacteristic const& data)>> callback); | ||
| 81 | + | ||
| 82 | + void UpdateConnectionParamSync(::ohos::bluetooth::ble::ConnectionParam param); | ||
| 83 | + | ||
| 84 | + void OnBLEConnectionStateChange( | ||
| 85 | + ::taihe::callback_view<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)> callback); | ||
| 86 | + void OffBLEConnectionStateChange( | ||
| 87 | + ::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)>> callback); | ||
| 88 | + | ||
| 89 | + ::ohos::bluetooth::constant::ProfileConnectionState GetConnectedState(); | ||
| 90 | + | ||
| 50 | std::shared_ptr<GattClient> &GetClient() | 91 | std::shared_ptr<GattClient> &GetClient() |
| 51 | { | 92 | { |
| 52 | return client_; | 93 | return client_; |
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | 22 | ||
| @@ -24,6 +25,7 @@ | |||
| 24 | 25 | ||
| 25 | 26 | ||
| 26 | 27 | ||
| 28 | + | ||
| 27 | 29 | ||
| 28 | namespace OHOS { | 30 | namespace OHOS { |
| 29 | namespace Bluetooth { | 31 | namespace 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_ {}; | ||
| 58 | private: | 76 | private: |
| 59 | std::string deviceAddr_ = INVALID_MAC_ADDRESS; | 77 | std::string deviceAddr_ = INVALID_MAC_ADDRESS; |
| 60 | }; | 78 | }; |
| @@ -37,6 +37,28 @@ public: | |||
| 37 | const ohos::bluetooth::ble::NotifyCharacteristic ¬ifyCharacteristic); | 37 | const ohos::bluetooth::ble::NotifyCharacteristic ¬ifyCharacteristic); |
| 38 | void NotifyCharacteristicChangedAsync(taihe::string_view deviceId, | 38 | void NotifyCharacteristicChangedAsync(taihe::string_view deviceId, |
| 39 | const ohos::bluetooth::ble::NotifyCharacteristic ¬ifyCharacteristic, uintptr_t callback); | 39 | const ohos::bluetooth::ble::NotifyCharacteristic ¬ifyCharacteristic, uintptr_t callback); |
| 40 | + void OnBlePhyUpdate(::taihe::callback_view<void(::ohos::bluetooth::ble::PhyValue const& data)> callback); | ||
| 41 | + void OffBlePhyUpdate(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::PhyValue const& data)>> callback); | ||
| 42 | + void SetPhySync(::taihe::string_view deviceId, ::ohos::bluetooth::ble::PhyValue const& phyValue); | ||
| 43 | + ::ohos::bluetooth::ble::PhyValue ReadPhySync(::taihe::string_view deviceId); | ||
| 44 | + void OnBLEMtuChange(::taihe::callback_view<void(int32_t data)> callback); | ||
| 45 | + void OffBLEMtuChange(::taihe::optional_view<::taihe::callback<void(int32_t data)>> callback); | ||
| 46 | + void Disconnect(::taihe::string_view deviceId); | ||
| 47 | + void Connect(::taihe::string_view deviceId, ::taihe::optional_view<bool> autoConnect); | ||
| 48 | + void OnCharacteristicRead(::taihe::callback_view<void(::ohos::bluetooth::ble::CharacteristicReadRequest const& data)> callback); | ||
| 49 | + void OffCharacteristicRead(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::CharacteristicReadRequest const& data)>> callback); | ||
| 50 | + void OnCharacteristicWrite(::taihe::callback_view<void(::ohos::bluetooth::ble::CharacteristicWriteRequest const& data)> callback); | ||
| 51 | + void OffCharacteristicWrite(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::CharacteristicWriteRequest const& data)>> callback); | ||
| 52 | + ::ohos::bluetooth::constant::ProfileConnectionState GetConnectedState(::taihe::string_view deviceId); | ||
| 53 | + ::ohos::bluetooth::ble::GattService GetService(::taihe::string_view serviceUuid); | ||
| 54 | + void OnConnectionStateChange(::taihe::callback_view<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)> callback); | ||
| 55 | + void OffConnectionStateChange(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::BLEConnectionChangeState const& data)>> callback); | ||
| 56 | + void OnDescriptorWrite(::taihe::callback_view<void(::ohos::bluetooth::ble::DescriptorWriteRequest const& data)> callback); | ||
| 57 | + void OffDescriptorWrite(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::DescriptorWriteRequest const& data)>> callback); | ||
| 58 | + void OnDescriptorRead(::taihe::callback_view<void(::ohos::bluetooth::ble::DescriptorReadRequest const& data)> callback); | ||
| 59 | + void OffDescriptorRead(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::DescriptorReadRequest const& data)>> callback); | ||
| 60 | + void RemoveAllServices(); | ||
| 61 | + ::taihe::array<::ohos::bluetooth::ble::GattService> GetServices(); | ||
| 40 | 62 | ||
| 41 | std::shared_ptr<GattServer> &GetServer() | 63 | std::shared_ptr<GattServer> &GetServer() |
| 42 | { | 64 | { |
| @@ -17,13 +17,19 @@ | |||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 20 | 23 | ||
| 24 | + | ||
| 21 | 25 | ||
| 22 | namespace OHOS { | 26 | namespace OHOS { |
| 23 | namespace Bluetooth { | 27 | namespace Bluetooth { |
| 24 | class TaiheGattServerCallback : public GattServerCallback { | 28 | class TaiheGattServerCallback : public GattServerCallback { |
| 25 | public: | 29 | public: |
| 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 Bluetooth | 63 | } // namespace Bluetooth |
| 47 | } // namespace OHOS | 64 | } // namespace OHOS |
| @@ -23,14 +23,15 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | - | ||
| 27 | 26 | ||
| 27 | + | ||
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | + | ||
| 34 | 35 | ||
| 35 | 36 | ||
| 36 | 37 | ||
| @@ -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 | } // Bluetooth | 717 | } // Bluetooth |
| 685 | } // OHOS | 718 | } // OHOS |
| 686 | 719 | ||
| @@ -700,4 +733,9 @@ TH_EXPORT_CPP_API_DisableAdvertisingPromise(OHOS::Bluetooth::DisableAdvertisingP | |||
| 700 | TH_EXPORT_CPP_API_DisableAdvertisingAsync(OHOS::Bluetooth::DisableAdvertisingAsync); | 733 | TH_EXPORT_CPP_API_DisableAdvertisingAsync(OHOS::Bluetooth::DisableAdvertisingAsync); |
| 701 | TH_EXPORT_CPP_API_EnableAdvertisingPromise(OHOS::Bluetooth::EnableAdvertisingPromise); | 734 | TH_EXPORT_CPP_API_EnableAdvertisingPromise(OHOS::Bluetooth::EnableAdvertisingPromise); |
| 702 | TH_EXPORT_CPP_API_EnableAdvertisingAsync(OHOS::Bluetooth::EnableAdvertisingAsync); | 735 | TH_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 | // NOLINTEND | 741 | // NOLINTEND |
| @@ -43,6 +43,11 @@ void TaiheBluetoothBleAdvertiseCallback::OnStartResultEvent(int result, int advH | |||
| 43 | auto taiheAdvHandle = std::make_shared<TaiheNativeInt>(advHandle); | 43 | auto taiheAdvHandle = std::make_shared<TaiheNativeInt>(advHandle); |
| 44 | AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GET_ADVERTISING_HANDLE, taiheAdvHandle, result); | 44 | AsyncWorkCallFunction(asyncWorkMap_, TaiheAsyncType::GET_ADVERTISING_HANDLE, taiheAdvHandle, result); |
| 45 | } | 45 | } |
| 46 | + ::ohos::bluetooth::ble::AdvertisingStateChangeInfo info{ | ||
| 47 | + advHandle, | ||
| 48 | + ::ohos::bluetooth::ble::AdvertisingState(::ohos::bluetooth::ble::AdvertisingState::key_t::STARTED) | ||
| 49 | + }; | ||
| 50 | + advertisingStateChangeEvent_.PublishEvent(info); | ||
| 46 | } | 51 | } |
| 47 | 52 | ||
| 48 | void TaiheBluetoothBleAdvertiseCallback::OnEnableResultEvent(int result, int advHandle) | 53 | void 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 | ||
| 59 | void TaiheBluetoothBleAdvertiseCallback::OnDisableResultEvent(int result, int advHandle) | 69 | void 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 | ||
| 70 | void TaiheBluetoothBleAdvertiseCallback::OnStopResultEvent(int result, int advHandle) | 85 | void 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 | ||
| 75 | void TaiheBluetoothBleAdvertiseCallback::OnSetAdvDataEvent(int result) | 95 | void TaiheBluetoothBleAdvertiseCallback::OnSetAdvDataEvent(int result) |
| @@ -33,19 +33,76 @@ TaiheBluetoothBleCentralManagerCallback &TaiheBluetoothBleCentralManagerCallback | |||
| 33 | return instance; | 33 | return instance; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | +static ::ohos::bluetooth::ble::ScanResult ConvertScanResultItem(const BleScanResult &result) | ||
| 37 | +{ | ||
| 38 | + auto payload = result.GetPayload(); | ||
| 39 | + BleScanResult &mutableResult = const_cast<BleScanResult &>(result); | ||
| 40 | + return ::ohos::bluetooth::ble::ScanResult{ | ||
| 41 | + taihe::string(result.GetPeripheralDevice().GetDeviceAddr()), | ||
| 42 | + result.GetRssi(), | ||
| 43 | + taihe::array<uint8_t>(taihe::copy_data, payload.data(), payload.size()), | ||
| 44 | + taihe::string(mutableResult.GetName()), | ||
| 45 | + result.IsConnectable() | ||
| 46 | + }; | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +static ::ohos::bluetooth::ble::ScanReport ConvertScanResult(const BleScanResult &result, | ||
| 50 | + ::ohos::bluetooth::ble::ScanReportType reportType) | ||
| 51 | +{ | ||
| 52 | + std::vector<::ohos::bluetooth::ble::ScanResult> resultVec; | ||
| 53 | + resultVec.push_back(ConvertScanResultItem(result)); | ||
| 54 | + ::ohos::bluetooth::ble::ScanReport scanReport{ | ||
| 55 | + reportType, | ||
| 56 | + taihe::array<::ohos::bluetooth::ble::ScanResult>( | ||
| 57 | + taihe::move_data, resultVec.data(), resultVec.size()) | ||
| 58 | + }; | ||
| 59 | + return scanReport; | ||
| 60 | +} | ||
| 61 | + | ||
| 36 | void TaiheBluetoothBleCentralManagerCallback::OnScanCallback(const BleScanResult &result) | 62 | void 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 | ||
| 41 | void TaiheBluetoothBleCentralManagerCallback::OnFoundOrLostCallback(const BleScanResult &result, uint8_t callbackType) | 78 | void 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 | ||
| 46 | void TaiheBluetoothBleCentralManagerCallback::OnBleBatchScanResultsEvent(const std::vector<BleScanResult> &results) | 90 | void 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 | ||
| 51 | void TaiheBluetoothBleCentralManagerCallback::OnStartOrStopScanEvent(int resultCode, bool isStartScan) | 108 | void TaiheBluetoothBleCentralManagerCallback::OnStartOrStopScanEvent(int resultCode, bool isStartScan) |
| @@ -94,5 +94,17 @@ uintptr_t BleScannerImpl::StopScanPromise() | |||
| 94 | asyncWork->Run(); | 94 | asyncWork->Run(); |
| 95 | return reinterpret_cast<uintptr_t>(asyncWork->GetRet()); | 95 | return reinterpret_cast<uintptr_t>(asyncWork->GetRet()); |
| 96 | } | 96 | } |
| 97 | +void BleScannerImpl::OnBLEDeviceFind(::taihe::callback_view<void(::ohos::bluetooth::ble::ScanReport const& data)> callback) { | ||
| 98 | + HILOGI("enter"); | ||
| 99 | + TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR); | ||
| 100 | + callback_->bleDeviceFindEvent_.RegisterEvent(callback); | ||
| 101 | +} | ||
| 102 | + | ||
| 103 | +void BleScannerImpl::OffBleDeviceFind(::taihe::optional_view<::taihe::callback<void(::ohos::bluetooth::ble::ScanReport const& data)>> callback) { | ||
| 104 | + HILOGI("enter"); | ||
| 105 | + TAIHE_BT_ASSERT_RETURN_VOID(callback_ != nullptr, BT_ERR_INTERNAL_ERROR); | ||
| 106 | + callback_->bleDeviceFindEvent_.DeregisterEvent(callback); | ||
| 107 | +} | ||
| 108 | + | ||
| 97 | } // namespace Bluetooth | 109 | } // namespace Bluetooth |
| 98 | } // namespace OHOS | 110 | } // namespace OHOS |
| @@ -19,6 +19,9 @@ | |||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 22 | 25 | ||
| 23 | 26 | ||
| 24 | 27 | ||
| @@ -28,6 +31,7 @@ | |||
| 28 | 31 | ||
| 29 | namespace OHOS { | 32 | namespace OHOS { |
| 30 | namespace Bluetooth { | 33 | namespace Bluetooth { |
| 34 | +constexpr int32_t BLE_SYNC_TIMEOUT_SECONDS = 10; | ||
| 31 | const std::vector<std::pair<int, int>> GattClientDeviceImpl::g_gattStatusSrvToTaihe = { | 35 | const 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 sdk | 276 | + 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 sdk | 344 | + 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 Bluetooth | 806 | } // namespace Bluetooth |
| 394 | -} // namespace OHOS | 807 | +} // namespace OHOS |
| @@ -28,6 +28,20 @@ TaiheGattClientCallback::TaiheGattClientCallback() | |||
| 28 | void TaiheGattClientCallback::OnCharacteristicChanged(const GattCharacteristic &characteristic) | 28 | void 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 | ||
| 33 | void TaiheGattClientCallback::OnCharacteristicReadResult(const GattCharacteristic &characteristic, int ret) | 47 | void TaiheGattClientCallback::OnCharacteristicReadResult(const GattCharacteristic &characteristic, int ret) |
| @@ -49,6 +63,12 @@ void TaiheGattClientCallback::OnDescriptorReadResult(const GattDescriptor &descr | |||
| 49 | void TaiheGattClientCallback::OnConnectionStateChanged(int connectionState, int ret) | 63 | void 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 | ||
| 54 | void TaiheGattClientCallback::OnServicesDiscovered(int status) | 74 | void TaiheGattClientCallback::OnServicesDiscovered(int status) |
| @@ -59,6 +79,17 @@ void TaiheGattClientCallback::OnServicesDiscovered(int status) | |||
| 59 | void TaiheGattClientCallback::OnReadRemoteRssiValueResult(int rssi, int ret) | 79 | void 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 | ||
| 64 | void TaiheGattClientCallback::OnCharacteristicWriteResult(const GattCharacteristic &characteristic, int ret) | 95 | void TaiheGattClientCallback::OnCharacteristicWriteResult(const GattCharacteristic &characteristic, int ret) |
| @@ -72,6 +103,9 @@ void TaiheGattClientCallback::OnCharacteristicWriteResult(const GattCharacterist | |||
| 72 | void TaiheGattClientCallback::OnDescriptorWriteResult(const GattDescriptor &descriptor, int ret) | 103 | void 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 | ||
| 77 | void TaiheGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status) | 111 | void TaiheGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status) |
| @@ -84,6 +118,45 @@ void TaiheGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic | |||
| 84 | void TaiheGattClientCallback::OnMtuUpdate(int mtu, int ret) | 118 | void 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 Bluetooth | 162 | } // namespace Bluetooth |
| @@ -20,8 +20,10 @@ | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | + | ||
| 23 | 24 | ||
| 24 | 25 | ||
| 26 | + | ||
| 25 | 27 | ||
| 26 | 28 | ||
| 27 | namespace OHOS { | 29 | namespace 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 Bluetooth | 460 | } // namespace Bluetooth |
| 192 | } // namespace OHOS | 461 | } // namespace OHOS |
| @@ -34,6 +34,18 @@ void TaiheGattServerCallback::OnCharacteristicReadRequest( | |||
| 34 | { | 34 | { |
| 35 | HILOGI("enter, remote device address: %{public}s, requestId: %{public}d", | 35 | HILOGI("enter, remote device address: %{public}s, requestId: %{public}d", |
| 36 | GET_ENCRYPT_ADDR(device), requestId); | 36 | GET_ENCRYPT_ADDR(device), requestId); |
| 37 | + std::string serviceUuid; | ||
| 38 | + if (characteristic.GetService() != nullptr) { | ||
| 39 | + serviceUuid = characteristic.GetService()->GetUuid().ToString(); | ||
| 40 | + } | ||
| 41 | + ::ohos::bluetooth::ble::CharacteristicReadRequest request{ | ||
| 42 | + taihe::string(device.GetDeviceAddr()), | ||
| 43 | + requestId, | ||
| 44 | + 0, | ||
| 45 | + taihe::string(characteristic.GetUuid().ToString()), | ||
| 46 | + taihe::string(serviceUuid) | ||
| 47 | + }; | ||
| 48 | + characteristicReadEvent_.PublishEvent(request); | ||
| 37 | } | 49 | } |
| 38 | 50 | ||
| 39 | void TaiheGattServerCallback::OnCharacteristicWriteRequest(const BluetoothRemoteDevice &device, | 51 | void 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 | ||
| 46 | void TaiheGattServerCallback::OnConnectionStateUpdate(const BluetoothRemoteDevice &device, int state) | 75 | void 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 | + | ||
| 77 | void TaiheGattServerCallback::OnDescriptorWriteRequest(const BluetoothRemoteDevice &device, | 119 | void 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 | ||
| 84 | void TaiheGattServerCallback::OnDescriptorReadRequest(const BluetoothRemoteDevice &device, | 148 | void 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 | ||
| 91 | void TaiheGattServerCallback::OnMtuUpdate(const BluetoothRemoteDevice &device, int mtu) | 172 | void 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 | ||
| 97 | void TaiheGattServerCallback::OnNotificationCharacteristicChanged(const BluetoothRemoteDevice &device, int ret) | 179 | void 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 Bluetooth | 205 | } // namespace Bluetooth |
| 104 | } // namespace OHOS | 206 | } // namespace OHOS |
| @@ -0,0 +1,109 @@ | |||
| 1 | +# Copyright (C) 2025 Huawei Device Co., Ltd. | ||
| 2 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 3 | +# you may not use this file except in compliance with the License. | ||
| 4 | +# You may obtain a copy of the License at | ||
| 5 | +# | ||
| 6 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 7 | +# | ||
| 8 | +# Unless required by applicable law or agreed to in writing, software | ||
| 9 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 10 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 11 | +# See the License for the specific language governing permissions and | ||
| 12 | +# limitations under the License. | ||
| 13 | + | ||
| 14 | +import("//build/config/components/ets_frontend/ets2abc_config.gni") | ||
| 15 | +import("//build/ohos.gni") | ||
| 16 | +import("//build/ohos/taihe_idl/taihe.gni") | ||
| 17 | + | ||
| 18 | +SUBSYSTEM_DIR = "//foundation/communication" | ||
| 19 | + | ||
| 20 | +copy_taihe_idl("bluetooth_common_taihe") { | ||
| 21 | + sources = [ "idl/ohos.bluetooth.common.taihe" ] | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +subsystem_name = "communication" | ||
| 25 | +part_name = "bluetooth" | ||
| 26 | +taihe_generated_file_path_common = "$taihe_file_path/out/$subsystem_name/$part_name/common" | ||
| 27 | + | ||
| 28 | +ohos_taihe("run_taihe") { | ||
| 29 | + taihe_generated_file_path = "${taihe_generated_file_path_common}" | ||
| 30 | + deps = [ ":bluetooth_common_taihe" ] | ||
| 31 | + outputs = [ | ||
| 32 | + "$taihe_generated_file_path/src/ohos.bluetooth.common.ani.cpp", | ||
| 33 | + "$taihe_generated_file_path/src/ohos.bluetooth.common.abi.c", | ||
| 34 | + ] | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +taihe_shared_library("bluetoothCommon_taihe_native") { | ||
| 38 | + cflags_cc = [ | ||
| 39 | + "-Os", | ||
| 40 | + "-fno-rtti", | ||
| 41 | + "-fno-exceptions", | ||
| 42 | + "-fdata-sections", | ||
| 43 | + "-ffunction-sections", | ||
| 44 | + "-fno-unwind-tables", | ||
| 45 | + "-fno-asynchronous-unwind-tables", | ||
| 46 | + "-fno-merge-all-constants", | ||
| 47 | + "-flto", | ||
| 48 | + ] | ||
| 49 | + ldflags = [ | ||
| 50 | + "-Wl,--as-needed", | ||
| 51 | + "-Wl,--gc-sections", | ||
| 52 | + ] | ||
| 53 | + shlib_type = "ani" | ||
| 54 | + taihe_generated_file_path = "${taihe_generated_file_path_common}" | ||
| 55 | + part_name = "$part_name" | ||
| 56 | + subsystem_name = "$subsystem_name" | ||
| 57 | + sources = get_target_outputs(":run_taihe") | ||
| 58 | + include_dirs = [ | ||
| 59 | + "include", | ||
| 60 | + "src", | ||
| 61 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include", | ||
| 62 | + "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include" | ||
| 63 | + ] | ||
| 64 | + sources += [ | ||
| 65 | + "src/ani_constructor.cpp", | ||
| 66 | + "src/ohos.bluetooth.common.impl.cpp", | ||
| 67 | + ] | ||
| 68 | + deps = [ | ||
| 69 | + ":run_taihe", | ||
| 70 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/inner:btframework", | ||
| 71 | + ] | ||
| 72 | + external_deps = [ | ||
| 73 | + "c_utils:utils", | ||
| 74 | + "hilog:libhilog", | ||
| 75 | + ] | ||
| 76 | + sanitize = { | ||
| 77 | + cfi = true # Enable/disable control flow integrity detection | ||
| 78 | + boundary_sanitize = true # Enable boundary san detection | ||
| 79 | + cfi_cross_dso = true # Cross-SO CFI Checks | ||
| 80 | + cfi_vcall_icall_only = true # CFI optimization, restrict CFI detection scope | ||
| 81 | + integer_overflow = true # Enable integer overflow detection | ||
| 82 | + ubsan = true # Enable some Ubsan options | ||
| 83 | + debug = false | ||
| 84 | + } | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +generate_static_abc("bluetoothCommon_abc") { | ||
| 88 | + base_url = "${taihe_generated_file_path_common}" | ||
| 89 | + files = [ "${taihe_generated_file_path_common}/@ohos.bluetooth.common.ets" ] | ||
| 90 | + is_boot_abc = "True" | ||
| 91 | + device_dst_file = "/system/framework/bluetoothCommon_abc.abc" | ||
| 92 | + dependencies = [ ":run_taihe" ] | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +ohos_prebuilt_etc("bluetoothCommon_etc") { | ||
| 96 | + source = "$target_out_dir/bluetoothCommon_abc.abc" | ||
| 97 | + module_install_dir = "framework" | ||
| 98 | + part_name = "$part_name" | ||
| 99 | + subsystem_name = "$subsystem_name" | ||
| 100 | + deps = [ ":bluetoothCommon_abc" ] | ||
| 101 | +} | ||
| 102 | + | ||
| 103 | +group("bluetoothCommon_taihe") { | ||
| 104 | + deps = [ | ||
| 105 | + ":bluetoothCommon_etc", | ||
| 106 | + ":bluetoothCommon_taihe_native" | ||
| 107 | + ] | ||
| 108 | + # deps = [":run_taihe"] | ||
| 109 | +} | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | +@!namespace("@ohos.bluetooth.common", "common") | ||
| 2 | +@!sts_inject(""" | ||
| 3 | +static { loadLibraryWithPermissionCheck("bluetoothCommon_taihe_native.z", "@ohos.bluetooth.common") } | ||
| 4 | +""") | ||
| 5 | + | ||
| 6 | +struct BluetoothAddress{ | ||
| 7 | + address: String; | ||
| 8 | + addressType: BluetoothAddressType; | ||
| 9 | + rawAddressType: Optional<BluetoothRawAddressType>; | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +enum BluetoothAddressType: i32 { | ||
| 13 | + VIRTUAL = 1, | ||
| 14 | + REAL = 2, | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +enum BluetoothRawAddressType: i32 { | ||
| 18 | + PUBLIC = 0, | ||
| 19 | + RANDOM = 1, | ||
| 20 | +} | ||
| @@ -0,0 +1,29 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) | ||
| 18 | +{ | ||
| 19 | + ani_env *env; | ||
| 20 | + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { | ||
| 21 | + return ANI_ERROR; | ||
| 22 | + } | ||
| 23 | + if (ANI_OK != ohos::bluetooth::common::ANIRegister(env)) { | ||
| 24 | + std::cerr << "Error from ohos::bluetooth::common::ANIRegister" << std::endl; | ||
| 25 | + return ANI_ERROR; | ||
| 26 | + } | ||
| 27 | + *result = ANI_VERSION_1; | ||
| 28 | + return ANI_OK; | ||
| 29 | +} | ||
| @@ -0,0 +1,30 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +using namespace taihe; | ||
| 22 | +using namespace ohos::bluetooth::common; | ||
| 23 | + | ||
| 24 | +namespace { | ||
| 25 | +// To be implemented. | ||
| 26 | +} // namespace | ||
| 27 | + | ||
| 28 | +// Since these macros are auto-generate, lint will cause false positive. | ||
| 29 | +// NOLINTBEGIN | ||
| 30 | +// NOLINTEND | ||
| @@ -18,6 +18,7 @@ | |||
| 18 | static { loadLibraryWithPermissionCheck("bluetoothConnection_taihe_native.z", "@ohos.bluetooth.connection") } | 18 | static { loadLibraryWithPermissionCheck("bluetoothConnection_taihe_native.z", "@ohos.bluetooth.connection") } |
| 19 | """) | 19 | """) |
| 20 | from ohos.bluetooth.constant use MajorClass, MajorMinorClass, ProfileConnectionState, ProfileId, ProfileUuids; | 20 | from ohos.bluetooth.constant use MajorClass, MajorMinorClass, ProfileConnectionState, ProfileId, ProfileUuids; |
| 21 | +from ohos.bluetooth.common use BluetoothAddress; | ||
| 21 | 22 | ||
| 22 | @!sts_inject(""" | 23 | @!sts_inject(""" |
| 23 | export function on(type: string, cb: (arg_0: Object) => void): void { | 24 | export function on(type: string, cb: (arg_0: Object) => void): void { |
| @@ -269,4 +270,65 @@ function CancelPairedDeviceSync(deviceId: String): void; | |||
| 269 | 270 | ||
| 270 | @gen_async("pairCredibleDevice") | 271 | @gen_async("pairCredibleDevice") |
| 271 | @gen_promise("pairCredibleDevice") | 272 | @gen_promise("pairCredibleDevice") |
| 272 | -function PairCredibleDeviceSync(deviceId: String, transport: BluetoothTransport): void; | 273 | +function PairCredibleDeviceSync(deviceId: String, transport: BluetoothTransport): void; |
| 274 | + | ||
| 275 | +function SetLocalName(name: String): void; | ||
| 276 | + | ||
| 277 | +@gen_promise("startPairOutOfBand") | ||
| 278 | +function StartPairOutOfBandSync(deviceId: String, transport: BluetoothTransport, p192Data: Optional<OobData>, p256Data: Optional<OobData>): void; | ||
| 279 | + | ||
| 280 | +@gen_promise("generateLocalOobData") | ||
| 281 | +function GenerateLocalOobDataSync(transport: BluetoothTransport): OobData; | ||
| 282 | + | ||
| 283 | +function GetVirtualAddressByHash(algorithmType: HashAlgorithmType, hashValue: String): String; | ||
| 284 | + | ||
| 285 | +@gen_promise("pairDeviceOutOfBand") | ||
| 286 | +function PairDeviceOutOfBandSync(transport: BluetoothTransport, p192Data: OobDataNullValue, p256Data: OobDataNullValue): void; | ||
| 287 | + | ||
| 288 | +function GetCarKeyDfxData(): String; | ||
| 289 | +function GetRemoteDeviceTransport(deviceId: String): BluetoothTransport; | ||
| 290 | +function SetCarKeyDfxData(deviceId: String, action: CarKeyActionType): void; | ||
| 291 | + | ||
| 292 | +function OnAclStateChange(callback: (data: AclStateResult) => void): void; | ||
| 293 | +function OffAclStateChange(callback: Optional<(data: AclStateResult) => void>): void; | ||
| 294 | +function OnScanModeChange(callback: (data: ScanMode) => void): void; | ||
| 295 | +function OffScanModeChange(callback: Optional<(data: ScanMode) => void>): void; | ||
| 296 | + | ||
| 297 | +struct OobData { | ||
| 298 | + deviceId: BluetoothAddress; | ||
| 299 | + confirmationHash: @arraybuffer Array<u8>; | ||
| 300 | + randomizerHash: Optional<@arraybuffer Array<u8>>; | ||
| 301 | + deviceName: Optional<String>; | ||
| 302 | + deviceRole: Optional<DeviceRole>; | ||
| 303 | +} | ||
| 304 | + | ||
| 305 | +enum DeviceRole: i32 { | ||
| 306 | + DEVICE_ROLE_PERIPHERAL_ONLY = 0, | ||
| 307 | + DEVICE_ROLE_CENTRAL_ONLY = 1, | ||
| 308 | + DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 2, | ||
| 309 | + DEVICE_ROLE_BOTH_PREFER_CENTRAL = 3 | ||
| 310 | +} | ||
| 311 | + | ||
| 312 | +enum HashAlgorithmType: i32 { | ||
| 313 | + HASH_ALGORITHM_SHA256 = 0 | ||
| 314 | +} | ||
| 315 | + | ||
| 316 | +enum CarKeyActionType: i32 { | ||
| 317 | + CAR_KEY_ACTION_ADD = 0, | ||
| 318 | + CAR_KEY_ACTION_DELETE = 1 | ||
| 319 | +} | ||
| 320 | + | ||
| 321 | +struct AclStateResult { | ||
| 322 | + deviceId: String; | ||
| 323 | + state: AclState; | ||
| 324 | +} | ||
| 325 | + | ||
| 326 | +enum AclState: i32 { | ||
| 327 | + STATE_CONNECTED = 0, | ||
| 328 | + STATE_DISCONNECTED = 1 | ||
| 329 | +} | ||
| 330 | + | ||
| 331 | +union OobDataNullValue { | ||
| 332 | + data: OobData; | ||
| 333 | + @null nValue; | ||
| 334 | +} | ||
| @@ -69,6 +69,10 @@ public: | |||
| 69 | std::vector<::taihe::optional<::taihe::callback<void( | 69 | std::vector<::taihe::optional<::taihe::callback<void( |
| 70 | ::ohos::bluetooth::connection::BatteryInfo const& data)>>> remoteBatteryChangeVec = {}; | 70 | ::ohos::bluetooth::connection::BatteryInfo const& data)>>> remoteBatteryChangeVec = {}; |
| 71 | std::shared_mutex remoteBatteryChangeLock; | 71 | std::shared_mutex remoteBatteryChangeLock; |
| 72 | + | ||
| 73 | + std::vector<::taihe::optional<::taihe::callback<void( | ||
| 74 | + ::ohos::bluetooth::connection::AclStateResult const& data)>>> aclStateChangeVec = {}; | ||
| 75 | + std::shared_mutex aclStateChangeLock; | ||
| 72 | }; | 76 | }; |
| 73 | 77 | ||
| 74 | class TaiheBluetoothConnectionObserver : public BluetoothHostObserver { | 78 | class 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 | + | ||
| 103 | private: | 111 | private: |
| 104 | void OnPairConfirmedCallBack(const std::shared_ptr<PairConfirmedCallBackInfo> &pairConfirmInfo); | 112 | void OnPairConfirmedCallBack(const std::shared_ptr<PairConfirmedCallBackInfo> &pairConfirmInfo); |
| 105 | void OnDiscoveryResultCallBack(const BluetoothRemoteDevice &device); | 113 | void OnDiscoveryResultCallBack(const BluetoothRemoteDevice &device); |
| @@ -21,10 +21,17 @@ | |||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 24 | 30 | ||
| 25 | 31 | ||
| 26 | 32 | ||
| 27 | 33 | ||
| 34 | + | ||
| 28 | 35 | ||
| 29 | 36 | ||
| 30 | 37 | ||
| @@ -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 | + | ||
| 64 | taihe::string GetRemoteProductId(taihe::string_view deviceId) | 218 | taihe::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 | } // Bluetooth | 1055 | } // Bluetooth |
| 738 | } // OHOS | 1056 | } // OHOS |
| 739 | 1057 | ||
| @@ -778,4 +1096,16 @@ TH_EXPORT_CPP_API_SetDevicePinCodeSync(OHOS::Bluetooth::SetDevicePinCodeSync); | |||
| 778 | TH_EXPORT_CPP_API_CancelPairingDeviceSync(OHOS::Bluetooth::CancelPairingDeviceSync); | 1096 | TH_EXPORT_CPP_API_CancelPairingDeviceSync(OHOS::Bluetooth::CancelPairingDeviceSync); |
| 779 | TH_EXPORT_CPP_API_CancelPairedDeviceSync(OHOS::Bluetooth::CancelPairedDeviceSync); | 1097 | TH_EXPORT_CPP_API_CancelPairedDeviceSync(OHOS::Bluetooth::CancelPairedDeviceSync); |
| 780 | TH_EXPORT_CPP_API_PairCredibleDeviceSync(OHOS::Bluetooth::PairCredibleDeviceSync); | 1098 | TH_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 | // NOLINTEND | 1111 | // NOLINTEND |
| @@ -49,7 +49,25 @@ std::shared_ptr<TaiheBluetoothRemoteDeviceObserver> TaiheBluetoothRemoteDeviceOb | |||
| 49 | 49 | ||
| 50 | void TaiheBluetoothRemoteDeviceObserver::OnAclStateChanged( | 50 | void 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 | ||
| 54 | void TaiheBluetoothRemoteDeviceObserver::OnPairStatusChanged(const BluetoothRemoteDevice &device, int status, int cause) | 72 | void TaiheBluetoothRemoteDeviceObserver::OnPairStatusChanged(const BluetoothRemoteDevice &device, int status, int cause) |
| 55 | { | 73 | { |
| @@ -211,7 +229,14 @@ void TaiheBluetoothConnectionObserver::OnPairConfirmed(const BluetoothRemoteDevi | |||
| 211 | 229 | ||
| 212 | void TaiheBluetoothConnectionObserver::OnScanModeChanged(int mode) | 230 | void 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 | ||
| 217 | void TaiheBluetoothConnectionObserver::OnDeviceNameChanged(const std::string &deviceName) | 242 | void TaiheBluetoothConnectionObserver::OnDeviceNameChanged(const std::string &deviceName) |
| @@ -22,7 +22,8 @@ copy_taihe_idl("bluetooth_hfp_taihe") { | |||
| 22 | "idl/ohos.bluetooth.hfp.taihe" | 22 | "idl/ohos.bluetooth.hfp.taihe" |
| 23 | ] | 23 | ] |
| 24 | deps = [ | 24 | deps = [ |
| 25 | - "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_baseProfile:bluetooth_baseProfile_taihe" | 25 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_baseProfile:bluetooth_baseProfile_taihe", |
| 26 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/bluetooth_constant:bluetooth_constant_taihe" | ||
| 26 | ] | 27 | ] |
| 27 | } | 28 | } |
| 28 | 29 | ||
| @@ -71,6 +72,7 @@ taihe_shared_library("bluetoothHfp_taihe_native") { | |||
| 71 | "src/ani_constructor.cpp", | 72 | "src/ani_constructor.cpp", |
| 72 | "src/ohos.bluetooth.hfp.impl.cpp", | 73 | "src/ohos.bluetooth.hfp.impl.cpp", |
| 73 | "src/taihe_bluetooth_hfp_ag_observer.cpp", | 74 | "src/taihe_bluetooth_hfp_ag_observer.cpp", |
| 75 | + "src/taihe_bluetooth_hfp_hf_observer.cpp", | ||
| 74 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp", | 76 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp", |
| 75 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp", | 77 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp", |
| 76 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp" | 78 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp" |
| @@ -38,4 +38,23 @@ interface HandsFreeAudioGatewayProfile : BaseProfile { | |||
| 38 | Disconnect(deviceId: String): void; | 38 | Disconnect(deviceId: String): void; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | -function CreateHfpAgProfile(): HandsFreeAudioGatewayProfile; | 41 | +function CreateHfpAgProfile(): HandsFreeAudioGatewayProfile; |
| 42 | + | ||
| 43 | +interface HandsFreeHfProfile : BaseProfile { | ||
| 44 | + @!sts_inject_into_class("""on(type: string, callback: object): void { | ||
| 45 | + if (type === "connectionStateChange") { | ||
| 46 | + this.onConnectionStateChange(callback as (info: baseProfile.StateChangeParam) => void); | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + """) | ||
| 50 | + | ||
| 51 | + @!sts_inject_into_class("""off(type: string, callback?: object): void { | ||
| 52 | + if (type === "connectionStateChange") { | ||
| 53 | + this.offConnectionStateChange(callback as ((info: baseProfile.StateChangeParam) => void) | undefined); | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + """) | ||
| 57 | + Connect(deviceId: String): void; | ||
| 58 | + Disconnect(deviceId: String): void; | ||
| 59 | +} | ||
| 60 | +function CreateHfpHfProfile(): HandsFreeHfProfile; | ||
| @@ -0,0 +1,44 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 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 | + | ||
| @@ -23,8 +23,10 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | + | ||
| 26 | 27 | ||
| 27 | 28 | ||
| 29 | + | ||
| 28 | 30 | ||
| 29 | 31 | ||
| 30 | namespace OHOS { | 32 | namespace 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 Bluetooth | 302 | } // namespace Bluetooth |
| 169 | } // namespace OHOS | 303 | } // 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 | // NOLINTBEGIN | 306 | // NOLINTBEGIN |
| 173 | TH_EXPORT_CPP_API_CreateHfpAgProfile(OHOS::Bluetooth::CreateHfpAgProfile); | 307 | TH_EXPORT_CPP_API_CreateHfpAgProfile(OHOS::Bluetooth::CreateHfpAgProfile); |
| 308 | +TH_EXPORT_CPP_API_CreateHfpHfProfile(OHOS::Bluetooth::CreateHfpHfProfile); | ||
| 174 | // NOLINTEND | 309 | // NOLINTEND |
| @@ -0,0 +1,63 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | +namespace OHOS { | ||
| 30 | +namespace Bluetooth { | ||
| 31 | + | ||
| 32 | +TaiheHandsFreeUnitObserver::TaiheHandsFreeUnitObserver() | ||
| 33 | +{} | ||
| 34 | + | ||
| 35 | +void TaiheHandsFreeUnitObserver::OnConnectionStateChanged(const BluetoothRemoteDevice &device, | ||
| 36 | + int state, int cause) | ||
| 37 | +{ | ||
| 38 | + std::shared_lock<std::shared_mutex> guard(eventSubscribe_.lock_); | ||
| 39 | + HILOGD("enter, remote device address: %{public}s, state: %{public}d, cause: %{public}d", | ||
| 40 | + GET_ENCRYPT_ADDR(device), state, cause); | ||
| 41 | + ::taihe::string deviceId_(device.GetDeviceAddr()); | ||
| 42 | + int32_t profileConnectionState = TaiheUtils::GetProfileConnectionState(state); | ||
| 43 | + auto state_ = ::ohos::bluetooth::constant::ProfileConnectionState::from_value(profileConnectionState); | ||
| 44 | + auto cause_ = ::ohos::bluetooth::baseProfile::DisconnectCause::from_value(cause); | ||
| 45 | + auto taiheResult = ::ohos::bluetooth::baseProfile::StateChangeParam { | ||
| 46 | + .deviceId = deviceId_, | ||
| 47 | + .state = state_, | ||
| 48 | + .cause = cause_, | ||
| 49 | + }; | ||
| 50 | + for (auto callback : eventSubscribe_.callbackVec_) { | ||
| 51 | + if (callback) { | ||
| 52 | + (*callback)(taiheResult); | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +void TaiheHandsFreeUnitObserver::OnScoStateChanged(const BluetoothRemoteDevice &device, int state) | ||
| 58 | +{ | ||
| 59 | + HILOGD("address: %{public}s, state: %{public}d", GET_ENCRYPT_ADDR(device), state); | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +} // namespace Bluetooth | ||
| 63 | +} // namespace OHOS | ||
| @@ -64,6 +64,8 @@ taihe_shared_library("bluetoothHid_taihe_native") { | |||
| 64 | "include", | 64 | "include", |
| 65 | "src", | 65 | "src", |
| 66 | "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include", | 66 | "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/include", |
| 67 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/parcel", | ||
| 68 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/common", | ||
| 67 | "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include", | 69 | "$SUBSYSTEM_DIR/bluetooth/interfaces/inner_api/include", |
| 68 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common" | 70 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common" |
| 69 | ] | 71 | ] |
| @@ -71,6 +73,10 @@ taihe_shared_library("bluetoothHid_taihe_native") { | |||
| 71 | "src/ani_constructor.cpp", | 73 | "src/ani_constructor.cpp", |
| 72 | "src/ohos.bluetooth.hid.impl.cpp", | 74 | "src/ohos.bluetooth.hid.impl.cpp", |
| 73 | "src/taihe_bluetooth_hid_host_observer.cpp", | 75 | "src/taihe_bluetooth_hid_host_observer.cpp", |
| 76 | + "src/taihe_bluetooth_hid_device_observer.cpp", | ||
| 77 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/parcel/bluetooth_hid_device_sdp_parcel.cpp", | ||
| 78 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/parcel/bluetooth_hid_device_qos_parcel.cpp", | ||
| 79 | + "$SUBSYSTEM_DIR/bluetooth/frameworks/inner/ipc/common/hid_device_utils.cpp", | ||
| 74 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp", | 80 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_error.cpp", |
| 75 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp", | 81 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_bluetooth_utils.cpp", |
| 76 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp" | 82 | "$SUBSYSTEM_DIR/bluetooth/frameworks/ets/taihe/common/taihe_event_module.cpp" |
| @@ -19,6 +19,7 @@ static { loadLibraryWithPermissionCheck("bluetoothHid_taihe_native.z", "@ohos.bl | |||
| 19 | """) | 19 | """) |
| 20 | 20 | ||
| 21 | from ohos.bluetooth.baseProfile use BaseProfile; | 21 | from 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';") |
| 23 | interface HidHostProfile : BaseProfile { | 24 | interface 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 | +} | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 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 | + | ||
| @@ -23,8 +23,11 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | + | ||
| 27 | + | ||
| 26 | 28 | ||
| 27 | 29 | ||
| 30 | + | ||
| 28 | 31 | ||
| 29 | 32 | ||
| 30 | namespace OHOS { | 33 | namespace 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 Bluetooth | 451 | } // namespace Bluetooth |
| 167 | } // namespace OHOS | 452 | } // 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 | // NOLINTBEGIN | 455 | // NOLINTBEGIN |
| 171 | TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile); | 456 | TH_EXPORT_CPP_API_CreateHidHostProfile(OHOS::Bluetooth::CreateHidHostProfile); |
| 457 | +TH_EXPORT_CPP_API_CreateHidDeviceProfile(OHOS::Bluetooth::CreateHidDeviceProfile); | ||
| 172 | // NOLINTEND | 458 | // NOLINTEND |
| @@ -0,0 +1,129 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2025 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 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 | ||
| @@ -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 | +} | ||
| @@ -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 | +} | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 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 | + | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 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 | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 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 | ||
| @@ -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 | +} | ||
| @@ -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 | +} | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 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 | + | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 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 | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 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 | ||
| @@ -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 | +} | ||
| @@ -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 | +} | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 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 | + | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 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 | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 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 | ||
| @@ -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 | +} | ||
| @@ -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 | +} | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 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 | + | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 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 | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 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 | ||
| @@ -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 | +} | ||
| @@ -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 | +} | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 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 | + | ||
| @@ -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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 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 | ||
| @@ -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_ADVERTISING | 44 | + 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 | ||
| 47 | struct TaiheAsyncWorkRet { | 55 | struct TaiheAsyncWorkRet { |
| @@ -31,6 +31,8 @@ class EventModule { | |||
| 31 | public: | 31 | public: |
| 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 Bluetooth | 84 | } // namespace Bluetooth |
| 71 | } // namespace OHOS | 85 | } // namespace OHOS |
| 72 | 86 | ||
| @@ -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 Bluetooth | 101 | } // namespace Bluetooth |
| 80 | } // namespace OHOS | 102 | } // namespace OHOS |
| @@ -87,6 +87,17 @@ public: | |||
| 87 | private: | 87 | private: |
| 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 Bluetooth | 101 | } // namespace Bluetooth |
| 91 | } // namespace OHOS | 102 | } // namespace OHOS |
| 92 | 103 | ||