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