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