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_pan.h"
17 #include "bluetooth_host.h"
18 #include "bluetooth_profile_manager.h"
19 #include "bluetooth_log.h"
20 #include "bluetooth_observer_list.h"
21 #include "bluetooth_pan_observer_stub.h"
22 #include "i_bluetooth_pan.h"
23 #include "i_bluetooth_host.h"
24 #include "bluetooth_utils.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27 
28 namespace OHOS {
29 namespace Bluetooth {
30 std::mutex g_proxyMutex;
31 class PanInnerObserver : public BluetoothPanObserverStub {
32 public:
PanInnerObserver(BluetoothObserverList<PanObserver> &observers)33     explicit PanInnerObserver(BluetoothObserverList<PanObserver> &observers) : observers_(observers)
34     {
35         HILOGD("enter");
36     }
37     ~PanInnerObserver() override
38     {
39         HILOGD("enter");
40     }
41 
42     ErrCode OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t cause) override
43     {
44         HILOGI("enter, device: %{public}s, state: %{public}d, cause: %{public}d",
45             GET_ENCRYPT_RAW_ADDR(device), state, cause);
46         BluetoothRemoteDevice remoteDevice(device.GetAddress(), 1);
47         observers_.ForEach([remoteDevice, state, cause](std::shared_ptr<PanObserver> observer) {
48             observer->OnConnectionStateChanged(remoteDevice, state, cause);
49         });
50         return NO_ERROR;
51     }
52 
53 private:
54     BluetoothObserverList<PanObserver> &observers_;
55     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(PanInnerObserver);
56 };
57 
58 struct Pan::impl {
59     impl();
60     ~impl();
61 
GetDevicesByStatesOHOS::Bluetooth::Pan::impl62     int32_t GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice>& result)
63     {
64         HILOGI("enter");
65         sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
66         CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "failed: no proxy");
67 
68         std::vector<BluetoothRawAddress> rawDevices;
69         std::vector<int32_t> tmpStates;
70         for (int32_t state : states) {
71             tmpStates.push_back((int32_t)state);
72         }
73 
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 
GetDeviceStateOHOS::Bluetooth::Pan::impl88     int32_t GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
89     {
90         HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
91         sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_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 
DisconnectOHOS::Bluetooth::Pan::impl100     int32_t Disconnect(const BluetoothRemoteDevice &device)
101     {
102         HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
103         sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
104         if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) {
105             HILOGE("invalid param.");
106             return BT_ERR_INVALID_PARAM;
107         }
108 
109         return proxy->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
110     }
111 
RegisterObserverOHOS::Bluetooth::Pan::impl112     void RegisterObserver(std::shared_ptr<PanObserver> observer)
113     {
114         HILOGD("enter");
115         observers_.Register(observer);
116     }
117 
DeregisterObserverOHOS::Bluetooth::Pan::impl118     void DeregisterObserver(std::shared_ptr<PanObserver> observer)
119     {
120         HILOGI("enter");
121         observers_.Deregister(observer);
122     }
123 
SetTetheringOHOS::Bluetooth::Pan::impl124     int32_t SetTethering(bool value)
125     {
126         HILOGI("enter");
127         sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
128         CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "failed: no proxy");
129 
130         int32_t ret = proxy->SetTethering(value);
131         HILOGI("fwk ret:%{public}d", ret);
132         return ret;
133     }
134 
IsTetheringOnOHOS::Bluetooth::Pan::impl135     int32_t IsTetheringOn(bool &value)
136     {
137         HILOGI("enter");
138         sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
139         CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "failed: no proxy");
140 
141         return proxy->IsTetheringOn(value);
142     }
143     int32_t profileRegisterId = 0;
144 private:
145 
146     BluetoothObserverList<PanObserver> observers_;
147     sptr<PanInnerObserver> innerObserver_;
148 };
149 
impl()150 Pan::impl::impl()
151 {
152     innerObserver_ = new PanInnerObserver(observers_);
153     profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_PAN_SERVER,
154         [this](sptr<IRemoteObject> remote) {
155         sptr<IBluetoothPan> proxy = iface_cast<IBluetoothPan>(remote);
156         if (proxy == nullptr) {
157             HILOGD("failed: no proxy");
158             return;
159         }
160         proxy->RegisterObserver(innerObserver_);
161     });
162 }
163 
~impl()164 Pan::impl::~impl()
165 {
166     HILOGD("start");
167     BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
168     sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_PAN_SERVER);
169     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
170     proxy->DeregisterObserver(innerObserver_);
171 }
172 
Pan()173 Pan::Pan()
174 {
175     pimpl = std::make_unique<impl>();
176 }
177 
~Pan()178 Pan::~Pan()
179 {}
180 
GetProfile()181 Pan *Pan::GetProfile()
182 {
183 #ifdef DTFUZZ_TEST
184     static BluetoothNoDestructor<Pan> instance;
185     return instance.get();
186 #else
187     static Pan instance;
188     return &instance;
189 #endif
190 }
191 
GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice> &result)192 int32_t Pan::GetDevicesByStates(std::vector<int> states, std::vector<BluetoothRemoteDevice> &result)
193 {
194     if (!IS_BT_ENABLED()) {
195         HILOGE("bluetooth is off.");
196         return BT_ERR_INVALID_STATE;
197     }
198     sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
199     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
200 
201     return pimpl->GetDevicesByStates(states, result);
202 }
203 
GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)204 int32_t Pan::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
205 {
206     if (!IS_BT_ENABLED()) {
207         HILOGE("bluetooth is off.");
208         return BT_ERR_INVALID_STATE;
209     }
210     sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
211     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
212 
213     return pimpl->GetDeviceState(device, state);
214 }
215 
Disconnect(const BluetoothRemoteDevice &device)216 int32_t Pan::Disconnect(const BluetoothRemoteDevice &device)
217 {
218     if (!IS_BT_ENABLED()) {
219         HILOGE("bluetooth is off.");
220         return BT_ERR_INVALID_STATE;
221     }
222 
223     sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
224     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
225 
226     return pimpl->Disconnect(device);
227 }
228 
RegisterObserver(std::shared_ptr<PanObserver> observer)229 void Pan::RegisterObserver(std::shared_ptr<PanObserver> observer)
230 {
231     HILOGD("enter");
232     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
233     pimpl->RegisterObserver(observer);
234 }
235 
DeregisterObserver(std::shared_ptr<PanObserver> observer)236 void Pan::DeregisterObserver(std::shared_ptr<PanObserver> observer)
237 {
238     HILOGD("enter");
239     CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
240     pimpl->DeregisterObserver(observer);
241 }
242 
SetTethering(bool value)243 int32_t Pan::SetTethering(bool value)
244 {
245     if (!IS_BT_ENABLED()) {
246         HILOGE("bluetooth is off.");
247         return BT_ERR_INVALID_STATE;
248     }
249 
250     sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
251     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
252 
253     return pimpl->SetTethering(value);
254 }
255 
IsTetheringOn(bool &value)256 int32_t Pan::IsTetheringOn(bool &value)
257 {
258     if (!IS_BT_ENABLED()) {
259         HILOGE("bluetooth is off.");
260         return BT_ERR_INVALID_STATE;
261     }
262 
263     sptr<IBluetoothPan> proxy = GetRemoteProxy<IBluetoothPan>(PROFILE_OPP_SERVER);
264     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
265 
266     return pimpl->IsTetheringOn(value);
267 }
268 }  // namespace Bluetooth
269 }  // namespace OHOS