1 /*
2  * Copyright (C) 2023 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_pbap_pse"
17 #endif
18 
19 #include <list>
20 #include <mutex>
21 #include <string>
22 #include "bluetooth_pbap_pse_observer_stub.h"
23 #include "bluetooth_pbap_pse_proxy.h"
24 #include "bluetooth_pbap_pse.h"
25 #include "bluetooth_remote_device.h"
26 #include "bluetooth_host.h"
27 #include "bluetooth_utils.h"
28 #include "bluetooth_observer_list.h"
29 #include "iservice_registry.h"
30 #include "raw_address.h"
31 #include "system_ability_definition.h"
32 #include "bluetooth_host_proxy.h"
33 #include "bluetooth_log.h"
34 #include "bluetooth_profile_manager.h"
35 
36 namespace OHOS {
37 namespace Bluetooth {
38 enum class BTShareType : int32_t {
39     SHARE_NAME_AND_PHONE_NUMBER = 0,
40     SHARE_ALL = 1,
41     SHARE_NOTHING = 2,
42 };
43 
44 class BluetoothPbapPseObserverImp : public BluetoothPbapPseObserverStub {
45 public:
BluetoothPbapPseObserverImp(BluetoothObserverList<PbapPseObserver> & observers)46     explicit BluetoothPbapPseObserverImp(BluetoothObserverList<PbapPseObserver> &observers)
47         : observers_(observers)
48     {}
~BluetoothPbapPseObserverImp()49     ~BluetoothPbapPseObserverImp() override
50     {}
51 
OnConnectionStateChanged(const BluetoothRawAddress & device,int32_t state,int32_t cause)52     void OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t cause) override
53     {
54         observers_.ForEach([device, state, cause](std::shared_ptr<PbapPseObserver> observer) {
55             BluetoothRemoteDevice dev(device.GetAddress(), 0);
56             observer->OnConnectionStateChanged(dev, state, cause);
57         });
58     }
59 
60 private:
61     BluetoothObserverList<PbapPseObserver> &observers_;
62     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothPbapPseObserverImp);
63 };
64 
65 struct PbapPse::impl {
66     impl();
67     ~impl();
68     void RegisterObserver(std::shared_ptr<PbapPseObserver> &observer);
69     void DeregisterObserver(std::shared_ptr<PbapPseObserver> &observer);
70     std::mutex pbapPseProxyMutex_;
71     int32_t profileRegisterId = 0;
72 private:
73     BluetoothObserverList<PbapPseObserver> observers_;
74     sptr<BluetoothPbapPseObserverImp> serviceObserverImp_ = nullptr;
75 };
76 
impl()77 PbapPse::impl::impl()
78 {
79     serviceObserverImp_ = new BluetoothPbapPseObserverImp(observers_);
80     profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_PBAP_PSE,
81         [this](sptr<IRemoteObject> remote) {
82         sptr<IBluetoothPbapPse> proxy = iface_cast<IBluetoothPbapPse>(remote);
83         CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
84         proxy->RegisterObserver(serviceObserverImp_);
85     });
86 }
87 
~impl()88 PbapPse::impl::~impl()
89 {
90     HILOGI("enter");
91     BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
92     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
93     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
94     proxy->DeregisterObserver(serviceObserverImp_);
95 }
96 
RegisterObserver(std::shared_ptr<PbapPseObserver> & observer)97 void PbapPse::impl::RegisterObserver(std::shared_ptr<PbapPseObserver> &observer)
98 {
99     HILOGI("enter");
100     if (observer) {
101         observers_.Register(observer);
102     }
103 }
104 
DeregisterObserver(std::shared_ptr<PbapPseObserver> & observer)105 void PbapPse::impl::DeregisterObserver(std::shared_ptr<PbapPseObserver> &observer)
106 {
107     HILOGI("enter");
108     if (observer) {
109         observers_.Deregister(observer);
110     }
111 }
112 
GetProfile()113 PbapPse *PbapPse::GetProfile()
114 {
115 #ifdef DTFUZZ_TEST
116     static BluetoothNoDestructor<PbapPse> instance;
117     return instance.get();
118 #else
119     static PbapPse instance;
120     return &instance;
121 #endif
122 }
123 
PbapPse()124 PbapPse::PbapPse()
125 {
126     pimpl = std::make_unique<impl>();
127 }
128 
~PbapPse()129 PbapPse::~PbapPse()
130 {
131     HILOGI("enter");
132 }
133 
RegisterObserver(std::shared_ptr<PbapPseObserver> observer)134 void PbapPse::RegisterObserver(std::shared_ptr<PbapPseObserver> observer)
135 {
136     HILOGI("enter");
137     pimpl->RegisterObserver(observer);
138 }
139 
DeregisterObserver(std::shared_ptr<PbapPseObserver> observer)140 void PbapPse::DeregisterObserver(std::shared_ptr<PbapPseObserver> observer)
141 {
142     HILOGI("enter");
143     pimpl->DeregisterObserver(observer);
144 }
145 
GetDeviceState(const BluetoothRemoteDevice & device,int32_t & state) const146 int32_t PbapPse::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state) const
147 {
148     HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
149     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
150     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
151     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
152     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
153 
154     return proxy->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state);
155 }
156 
GetDevicesByStates(const std::vector<int32_t> & states,std::vector<BluetoothRemoteDevice> & result) const157 int32_t PbapPse::GetDevicesByStates(const std::vector<int32_t> &states,
158     std::vector<BluetoothRemoteDevice> &result) const
159 {
160     HILOGI("enter");
161     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
162     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
163     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
164 
165     std::vector<BluetoothRawAddress> rawAddress {};
166     int32_t ret = proxy->GetDevicesByStates(states, rawAddress);
167     CHECK_AND_RETURN_LOG_RET((ret == BT_NO_ERROR), ret, "inner error");
168 
169     for (BluetoothRawAddress rawAddr : rawAddress) {
170         BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
171         result.push_back(device);
172     }
173     return BT_NO_ERROR;
174 }
175 
Disconnect(const BluetoothRemoteDevice & device)176 int32_t PbapPse::Disconnect(const BluetoothRemoteDevice &device)
177 {
178     HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
179     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
180     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
181     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
182     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
183 
184     return proxy->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
185 }
186 
SetConnectionStrategy(const BluetoothRemoteDevice & device,int32_t strategy)187 int32_t PbapPse::SetConnectionStrategy(const BluetoothRemoteDevice &device, int32_t strategy)
188 {
189     HILOGI("device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
190     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
191     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
192     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
193     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
194     CHECK_AND_RETURN_LOG_RET(CheckConnectionStrategyInvalid(strategy), BT_ERR_INVALID_PARAM, "strategy param error");
195 
196     return proxy->SetConnectionStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
197 }
198 
GetConnectionStrategy(const BluetoothRemoteDevice & device,int32_t & strategy) const199 int32_t PbapPse::GetConnectionStrategy(const BluetoothRemoteDevice &device, int32_t &strategy) const
200 {
201     HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
202     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
203     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
204     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
205     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
206 
207     return proxy->GetConnectionStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
208 }
209 
CheckShareTypeInvalid(int32_t shareType)210 bool CheckShareTypeInvalid(int32_t shareType)
211 {
212     if (shareType == static_cast<int32_t>(BTShareType::SHARE_NAME_AND_PHONE_NUMBER) ||
213         shareType == static_cast<int32_t>(BTShareType::SHARE_ALL) ||
214         shareType == static_cast<int32_t>(BTShareType::SHARE_NOTHING)) {
215         return true;
216     }
217     return false;
218 }
219 
SetShareType(const BluetoothRemoteDevice & device,int32_t shareType)220 int32_t PbapPse::SetShareType(const BluetoothRemoteDevice &device, int32_t shareType)
221 {
222     HILOGI("device: %{public}s, shareType: %{public}d", GET_ENCRYPT_ADDR(device), shareType);
223     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
224     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
225     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
226     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
227     CHECK_AND_RETURN_LOG_RET(CheckShareTypeInvalid(shareType), BT_ERR_INVALID_PARAM, "shareType param error");
228 
229     return proxy->SetShareType(BluetoothRawAddress(device.GetDeviceAddr()), shareType);
230 }
231 
GetShareType(const BluetoothRemoteDevice & device,int32_t & shareType) const232 int32_t PbapPse::GetShareType(const BluetoothRemoteDevice &device, int32_t &shareType) const
233 {
234     HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
235     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
236     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
237     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
238     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
239 
240     return proxy->GetShareType(BluetoothRawAddress(device.GetDeviceAddr()), shareType);
241 }
242 
SetPhoneBookAccessAuthorization(const BluetoothRemoteDevice & device,int32_t accessAuthorization)243 int32_t PbapPse::SetPhoneBookAccessAuthorization(const BluetoothRemoteDevice &device, int32_t accessAuthorization)
244 {
245     HILOGI("device: %{public}s, accessAuthorization: %{public}d",
246         GET_ENCRYPT_ADDR(device), accessAuthorization);
247     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
248     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
249     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
250     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
251     CHECK_AND_RETURN_LOG_RET(CheckAccessAuthorizationInvalid(accessAuthorization),
252         BT_ERR_INVALID_PARAM, "accessAuthorization param error");
253 
254     return proxy->SetPhoneBookAccessAuthorization(BluetoothRawAddress(device.GetDeviceAddr()),
255         accessAuthorization);
256 }
257 
GetPhoneBookAccessAuthorization(const BluetoothRemoteDevice & device,int32_t & accessAuthorization) const258 int32_t PbapPse::GetPhoneBookAccessAuthorization(const BluetoothRemoteDevice &device,
259     int32_t &accessAuthorization) const
260 {
261     HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
262     CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
263     sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
264     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
265     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
266 
267     return proxy->GetPhoneBookAccessAuthorization(BluetoothRawAddress(device.GetDeviceAddr()),
268         accessAuthorization);
269 }
270 
271 } // namespace Bluetooth
272 } // namespace OHOS