* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LOG_TAG
#define LOG_TAG "bt_fwk_pbap_pse"
#endif
#include <list>
#include <mutex>
#include <string>
#include "bluetooth_pbap_pse_observer_stub.h"
#include "bluetooth_pbap_pse_proxy.h"
#include "bluetooth_pbap_pse.h"
#include "bluetooth_remote_device.h"
#include "bluetooth_host.h"
#include "bluetooth_utils.h"
#include "bluetooth_observer_list.h"
#include "iservice_registry.h"
#include "raw_address.h"
#include "system_ability_definition.h"
#include "bluetooth_host_proxy.h"
#include "bluetooth_log.h"
#include "bluetooth_profile_manager.h"
namespace OHOS {
namespace Bluetooth {
enum class BTShareType : int32_t {
SHARE_NAME_AND_PHONE_NUMBER = 0,
SHARE_ALL = 1,
SHARE_NOTHING = 2,
};
class BluetoothPbapPseObserverImp : public BluetoothPbapPseObserverStub {
public:
explicit BluetoothPbapPseObserverImp(BluetoothObserverList<PbapPseObserver> &observers)
: observers_(observers)
{}
~BluetoothPbapPseObserverImp() override
{}
void OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t cause) override
{
observers_.ForEach([device, state, cause](std::shared_ptr<PbapPseObserver> observer) {
BluetoothRemoteDevice dev(device.GetAddress(), 0);
observer->OnConnectionStateChanged(dev, state, cause);
});
}
private:
BluetoothObserverList<PbapPseObserver> &observers_;
BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothPbapPseObserverImp);
};
struct PbapPse::impl {
impl();
~impl();
void RegisterObserver(std::shared_ptr<PbapPseObserver> &observer);
void DeregisterObserver(std::shared_ptr<PbapPseObserver> &observer);
std::mutex pbapPseProxyMutex_;
int32_t profileRegisterId = 0;
private:
BluetoothObserverList<PbapPseObserver> observers_;
sptr<BluetoothPbapPseObserverImp> serviceObserverImp_ = nullptr;
};
PbapPse::impl::impl()
{
serviceObserverImp_ = new BluetoothPbapPseObserverImp(observers_);
profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_PBAP_PSE,
[this](sptr<IRemoteObject> remote) {
sptr<IBluetoothPbapPse> proxy = iface_cast<IBluetoothPbapPse>(remote);
CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
proxy->RegisterObserver(serviceObserverImp_);
});
}
PbapPse::impl::~impl()
{
HILOGI("enter");
BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
proxy->DeregisterObserver(serviceObserverImp_);
}
void PbapPse::impl::RegisterObserver(std::shared_ptr<PbapPseObserver> &observer)
{
HILOGI("enter");
if (observer) {
observers_.Register(observer);
}
}
void PbapPse::impl::DeregisterObserver(std::shared_ptr<PbapPseObserver> &observer)
{
HILOGI("enter");
if (observer) {
observers_.Deregister(observer);
}
}
PbapPse *PbapPse::GetProfile()
{
#ifdef DTFUZZ_TEST
static BluetoothNoDestructor<PbapPse> instance;
return instance.get();
#else
static PbapPse instance;
return &instance;
#endif
}
PbapPse::PbapPse()
{
pimpl = std::make_unique<impl>();
}
PbapPse::~PbapPse()
{
HILOGI("enter");
}
void PbapPse::RegisterObserver(std::shared_ptr<PbapPseObserver> observer)
{
HILOGI("enter");
pimpl->RegisterObserver(observer);
}
void PbapPse::DeregisterObserver(std::shared_ptr<PbapPseObserver> observer)
{
HILOGI("enter");
pimpl->DeregisterObserver(observer);
}
int32_t PbapPse::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state) const
{
HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
return proxy->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state);
}
int32_t PbapPse::GetDevicesByStates(const std::vector<int32_t> &states,
std::vector<BluetoothRemoteDevice> &result) const
{
HILOGI("enter");
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
std::vector<BluetoothRawAddress> rawAddress {};
int32_t ret = proxy->GetDevicesByStates(states, rawAddress);
CHECK_AND_RETURN_LOG_RET((ret == BT_NO_ERROR), ret, "inner error");
for (BluetoothRawAddress rawAddr : rawAddress) {
BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
result.push_back(device);
}
return BT_NO_ERROR;
}
int32_t PbapPse::Disconnect(const BluetoothRemoteDevice &device)
{
HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
return proxy->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
}
int32_t PbapPse::SetConnectionStrategy(const BluetoothRemoteDevice &device, int32_t strategy)
{
HILOGI("device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
CHECK_AND_RETURN_LOG_RET(CheckConnectionStrategyInvalid(strategy), BT_ERR_INVALID_PARAM, "strategy param error");
return proxy->SetConnectionStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
}
int32_t PbapPse::GetConnectionStrategy(const BluetoothRemoteDevice &device, int32_t &strategy) const
{
HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
return proxy->GetConnectionStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
}
bool CheckShareTypeInvalid(int32_t shareType)
{
if (shareType == static_cast<int32_t>(BTShareType::SHARE_NAME_AND_PHONE_NUMBER) ||
shareType == static_cast<int32_t>(BTShareType::SHARE_ALL) ||
shareType == static_cast<int32_t>(BTShareType::SHARE_NOTHING)) {
return true;
}
return false;
}
int32_t PbapPse::SetShareType(const BluetoothRemoteDevice &device, int32_t shareType)
{
HILOGI("device: %{public}s, shareType: %{public}d", GET_ENCRYPT_ADDR(device), shareType);
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
CHECK_AND_RETURN_LOG_RET(CheckShareTypeInvalid(shareType), BT_ERR_INVALID_PARAM, "shareType param error");
return proxy->SetShareType(BluetoothRawAddress(device.GetDeviceAddr()), shareType);
}
int32_t PbapPse::GetShareType(const BluetoothRemoteDevice &device, int32_t &shareType) const
{
HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
return proxy->GetShareType(BluetoothRawAddress(device.GetDeviceAddr()), shareType);
}
int32_t PbapPse::SetPhoneBookAccessAuthorization(const BluetoothRemoteDevice &device, int32_t accessAuthorization)
{
HILOGI("device: %{public}s, accessAuthorization: %{public}d",
GET_ENCRYPT_ADDR(device), accessAuthorization);
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
CHECK_AND_RETURN_LOG_RET(CheckAccessAuthorizationInvalid(accessAuthorization),
BT_ERR_INVALID_PARAM, "accessAuthorization param error");
return proxy->SetPhoneBookAccessAuthorization(BluetoothRawAddress(device.GetDeviceAddr()),
accessAuthorization);
}
int32_t PbapPse::GetPhoneBookAccessAuthorization(const BluetoothRemoteDevice &device,
int32_t &accessAuthorization) const
{
HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
sptr<IBluetoothPbapPse> proxy = GetRemoteProxy<IBluetoothPbapPse>(PROFILE_PBAP_PSE);
CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
return proxy->GetPhoneBookAccessAuthorization(BluetoothRawAddress(device.GetDeviceAddr()),
accessAuthorization);
}
}
}