1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "bluetooth_hid_host.h" 17#include <unistd.h> 18#include "bluetooth_device.h" 19#include "bluetooth_host.h" 20#include "bluetooth_profile_manager.h" 21#include "bluetooth_log.h" 22#include "bluetooth_observer_list.h" 23#include "bluetooth_hid_host_observer_stub.h" 24#include "bluetooth_utils.h" 25#include "i_bluetooth_hid_host.h" 26#include "i_bluetooth_host.h" 27#include "iservice_registry.h" 28#include "system_ability_definition.h" 29 30namespace OHOS { 31namespace Bluetooth { 32std::mutex g_hidProxyMutex; 33class HidHostInnerObserver : public BluetoothHidHostObserverStub { 34public: 35 explicit HidHostInnerObserver(BluetoothObserverList<HidHostObserver> &observers) : observers_(observers) 36 { 37 HILOGD("Enter!"); 38 } 39 ~HidHostInnerObserver() override 40 { 41 HILOGD("Enter!"); 42 } 43 44 ErrCode OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t cause) override 45 { 46 HILOGD("hid conn state, device: %{public}s, state: %{public}s, cause: %{public}d", 47 GET_ENCRYPT_RAW_ADDR(device), GetProfileConnStateName(state).c_str(), cause); 48 BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0); 49 observers_.ForEach([remoteDevice, state, cause](std::shared_ptr<HidHostObserver> observer) { 50 observer->OnConnectionStateChanged(remoteDevice, state, cause); 51 }); 52 return NO_ERROR; 53 } 54 55private: 56 BluetoothObserverList<HidHostObserver> &observers_; 57 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(HidHostInnerObserver); 58}; 59 60struct HidHost::impl { 61 impl(); 62 ~impl(); 63 64 int32_t GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice>& result) 65 { 66 HILOGI("Enter!"); 67 std::vector<BluetoothRawAddress> rawDevices; 68 std::vector<int32_t> tmpStates; 69 for (int32_t state : states) { 70 tmpStates.push_back((int32_t)state); 71 } 72 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 73 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "failed: no proxy"); 74 int32_t ret = proxy->GetDevicesByStates(tmpStates, rawDevices); 75 if (ret != BT_NO_ERROR) { 76 HILOGE("inner error."); 77 return ret; 78 } 79 80 for (BluetoothRawAddress rawDevice : rawDevices) { 81 BluetoothRemoteDevice remoteDevice(rawDevice.GetAddress(), 1); 82 result.push_back(remoteDevice); 83 } 84 85 return BT_NO_ERROR; 86 } 87 88 int32_t GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state) 89 { 90 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 91 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 92 if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) { 93 HILOGE("invalid param."); 94 return BT_ERR_INVALID_PARAM; 95 } 96 97 return proxy->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state); 98 } 99 100 int32_t Connect(const BluetoothRemoteDevice &device) 101 { 102 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 103 if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) { 104 HILOGE("invalid param."); 105 return BT_ERR_INVALID_PARAM; 106 } 107 HILOGI("hid connect remote device: %{public}s", GET_ENCRYPT_ADDR(device)); 108 return proxy->Connect(BluetoothRawAddress(device.GetDeviceAddr())); 109 } 110 111 int32_t Disconnect(const BluetoothRemoteDevice &device) 112 { 113 HILOGI("hid disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device)); 114 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 115 if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) { 116 HILOGE("invalid param."); 117 return BT_ERR_INVALID_PARAM; 118 } 119 120 return proxy->Disconnect(BluetoothRawAddress(device.GetDeviceAddr())); 121 } 122 123 void RegisterObserver(std::shared_ptr<HidHostObserver> observer) 124 { 125 HILOGD("Enter!"); 126 observers_.Register(observer); 127 } 128 129 void DeregisterObserver(std::shared_ptr<HidHostObserver> observer) 130 { 131 HILOGI("Enter!"); 132 observers_.Deregister(observer); 133 } 134 135 void HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type) 136 { 137 HILOGI("Enter!"); 138 int result; 139 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 140 if (proxy != nullptr) { 141 proxy->HidHostVCUnplug(device, id, size, type, result); 142 } 143 } 144 145 void HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type) 146 { 147 HILOGI("Enter!"); 148 int result; 149 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 150 if (proxy != nullptr) { 151 proxy->HidHostSendData(device, id, size, type, result); 152 } 153 } 154 155 void HidHostSetReport(std::string device, uint8_t type, std::string &report) 156 { 157 HILOGI("Enter!"); 158 int result; 159 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 160 if (proxy != nullptr) { 161 proxy->HidHostSetReport(device, type, report, result); 162 } 163 } 164 165 void HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type) 166 { 167 HILOGI("Enter!"); 168 int result; 169 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 170 if (proxy != nullptr && IS_BT_ENABLED()) { 171 proxy->HidHostGetReport(device, id, size, type, result); 172 } 173 } 174 175 int SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy) 176 { 177 HILOGI("enter"); 178 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 179 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 180 return proxy->SetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy); 181 } 182 183 int GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const 184 { 185 HILOGI("enter"); 186 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 187 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 188 return proxy->GetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy); 189 } 190 191 int32_t profileRegisterId = 0; 192private: 193 BluetoothObserverList<HidHostObserver> observers_; 194 sptr<HidHostInnerObserver> innerObserver_; 195}; 196 197HidHost::impl::impl() 198{ 199 innerObserver_ = new HidHostInnerObserver(observers_); 200 profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_HID_HOST_SERVER, 201 [this](sptr<IRemoteObject> remote) { 202 sptr<IBluetoothHidHost> proxy = iface_cast<IBluetoothHidHost>(remote); 203 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 204 proxy->RegisterObserver(innerObserver_); 205 }); 206} 207 208HidHost::impl::~impl() 209{ 210 HILOGD("start"); 211 BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId); 212 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 213 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 214 proxy->DeregisterObserver(innerObserver_); 215} 216 217HidHost::HidHost() 218{ 219 pimpl = std::make_unique<impl>(); 220} 221 222HidHost::~HidHost() {} 223 224HidHost *HidHost::GetProfile() 225{ 226#ifdef DTFUZZ_TEST 227 static BluetoothNoDestructor<HidHost> instance; 228 return instance.get(); 229#else 230 static HidHost instance; 231 return &instance; 232#endif 233} 234 235int32_t HidHost::GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice> &result) 236{ 237 if (!IS_BT_ENABLED()) { 238 HILOGE("bluetooth is off."); 239 return BT_ERR_INVALID_STATE; 240 } 241 242 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 243 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 244 245 return pimpl->GetDevicesByStates(states, result); 246} 247 248int32_t HidHost::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state) 249{ 250 if (!IS_BT_ENABLED()) { 251 HILOGE("bluetooth is off."); 252 return BT_ERR_INVALID_STATE; 253 } 254 255 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 256 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 257 258 return pimpl->GetDeviceState(device, state); 259} 260 261int32_t HidHost::Connect(const BluetoothRemoteDevice &device) 262{ 263 if (!IS_BT_ENABLED()) { 264 HILOGE("bluetooth is off."); 265 return BT_ERR_INVALID_STATE; 266 } 267 268 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 269 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 270 271 return pimpl->Connect(device); 272} 273 274int32_t HidHost::Disconnect(const BluetoothRemoteDevice &device) 275{ 276 if (!IS_BT_ENABLED()) { 277 HILOGE("bluetooth is off."); 278 return BT_ERR_INVALID_STATE; 279 } 280 281 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 282 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 283 284 return pimpl->Disconnect(device); 285} 286 287int HidHost::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy) 288{ 289 HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy); 290 if (!IS_BT_ENABLED()) { 291 HILOGE("bluetooth is off."); 292 return BT_ERR_INVALID_STATE; 293 } 294 295 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 296 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 297 298 if ((!device.IsValidBluetoothRemoteDevice()) || ( 299 (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) && 300 (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) { 301 HILOGI("input parameter error."); 302 return BT_ERR_INVALID_PARAM; 303 } 304 return pimpl->SetConnectStrategy(device, strategy); 305} 306 307int HidHost::GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const 308{ 309 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 310 if (!IS_BT_ENABLED()) { 311 HILOGE("bluetooth is off."); 312 return BT_ERR_INVALID_STATE; 313 } 314 315 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 316 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy"); 317 318 if (!device.IsValidBluetoothRemoteDevice()) { 319 HILOGI("input parameter error."); 320 return BT_ERR_INVALID_PARAM; 321 } 322 return pimpl->GetConnectStrategy(device, strategy); 323} 324 325void HidHost::RegisterObserver(std::shared_ptr<HidHostObserver> observer) 326{ 327 HILOGD("enter"); 328 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null."); 329 pimpl->RegisterObserver(observer); 330} 331 332void HidHost::DeregisterObserver(std::shared_ptr<HidHostObserver> observer) 333{ 334 HILOGD("enter"); 335 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null."); 336 pimpl->DeregisterObserver(observer); 337} 338 339void HidHost::HidHostVCUnplug(std::string device, uint8_t id, uint16_t size, uint8_t type) 340{ 341 if (!IS_BT_ENABLED()) { 342 HILOGE("bluetooth is off."); 343 return; 344 } 345 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 346 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 347 348 return pimpl->HidHostVCUnplug(device, id, size, type); 349} 350 351void HidHost::HidHostSendData(std::string device, uint8_t id, uint16_t size, uint8_t type) 352{ 353 if (!IS_BT_ENABLED()) { 354 HILOGE("bluetooth is off."); 355 return; 356 } 357 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 358 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 359 360 return pimpl->HidHostSendData(device, id, size, type); 361} 362 363void HidHost::HidHostSetReport(std::string device, uint8_t type, std::string &report) 364{ 365 if (!IS_BT_ENABLED()) { 366 HILOGE("bluetooth is off."); 367 return; 368 } 369 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 370 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 371 372 return pimpl->HidHostSetReport(device, type, report); 373} 374 375void HidHost::HidHostGetReport(std::string device, uint8_t id, uint16_t size, uint8_t type) 376{ 377 if (!IS_BT_ENABLED()) { 378 HILOGE("bluetooth is off."); 379 return; 380 } 381 sptr<IBluetoothHidHost> proxy = GetRemoteProxy<IBluetoothHidHost>(PROFILE_HID_HOST_SERVER); 382 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 383 384 return pimpl->HidHostGetReport(device, id, size, type); 385} 386} // namespace Bluetooth 387} // namespace OHOS