* Copyright (C) 2022 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.
*/
#include "bluetooth_errorcode.h"
#include "bluetooth_pan_server.h"
#include "bluetooth_log.h"
#include "bluetooth_utils_server.h"
#include "interface_profile.h"
#include "interface_profile_pan.h"
#include "i_bluetooth_host_observer.h"
#include "remote_observer_list.h"
#include "hilog/log.h"
namespace OHOS {
namespace Bluetooth {
class BluetoothPanCallback : public bluetooth::IPanObserver {
public:
BluetoothPanCallback() = default;
~BluetoothPanCallback() override = default;
void OnConnectionStateChanged(const RawAddress &device, int state) override
{
HILOGI("addr:%{public}s, state:%{public}d", GET_ENCRYPT_ADDR(device), state);
observers_->ForEach([device, state](sptr<IBluetoothPanObserver> observer) {
observer->OnConnectionStateChanged(device, state,
static_cast<uint32_t>(ConnChangeCause::CONNECT_CHANGE_COMMON_CAUSE));
});
}
void SetObserver(RemoteObserverList<IBluetoothPanObserver> *observers)
{
observers_ = observers;
}
private:
RemoteObserverList<IBluetoothPanObserver> *observers_;
};
struct BluetoothPanServer::impl {
impl();
~impl();
class SystemStateObserver;
std::unique_ptr<SystemStateObserver> systemStateObserver_ = nullptr;
RemoteObserverList<IBluetoothPanObserver> observers_;
std::unique_ptr<BluetoothPanCallback> observerImp_ = std::make_unique<BluetoothPanCallback>();
IProfilePan *panService_ = nullptr;
std::vector<sptr<IBluetoothPanObserver>> advCallBack_;
std::mutex advCallBackMutex;
IProfilePan *GetServicePtr()
{
if (IProfileManager::GetInstance() == nullptr) {
return nullptr;
}
return static_cast<IProfilePan *>(
IProfileManager::GetInstance()->GetProfileService(PROFILE_NAME_PAN));
}
};
class BluetoothPanServer::impl::SystemStateObserver : public ISystemStateObserver {
public:
explicit SystemStateObserver(BluetoothPanServer::impl *pimpl) : pimpl_(pimpl) {}
void OnSystemStateChange(const BTSystemState state) override
{
switch (state) {
case BTSystemState::ON:
pimpl_->panService_ = pimpl_->GetServicePtr();
if (pimpl_->panService_ != nullptr) {
pimpl_->panService_->RegisterObserver(*pimpl_->observerImp_.get());
}
break;
case BTSystemState::OFF:
pimpl_->panService_ = nullptr;
break;
default:
break;
}
};
private:
BluetoothPanServer::impl *pimpl_ = nullptr;
};
BluetoothPanServer::impl::impl()
{
HILOGI("starts");
}
BluetoothPanServer::impl::~impl()
{
HILOGI("starts");
}
BluetoothPanServer::BluetoothPanServer()
{
pimpl = std::make_unique<impl>();
pimpl->observerImp_->SetObserver(&(pimpl->observers_));
pimpl->systemStateObserver_ = std::make_unique<impl::SystemStateObserver>(pimpl.get());
IAdapterManager::GetInstance()->RegisterSystemStateObserver(*(pimpl->systemStateObserver_));
pimpl->panService_ = pimpl->GetServicePtr();
if (pimpl->panService_ != nullptr) {
pimpl->panService_->RegisterObserver(*pimpl->observerImp_.get());
}
}
BluetoothPanServer::~BluetoothPanServer()
{
IAdapterManager::GetInstance()->DeregisterSystemStateObserver(*(pimpl->systemStateObserver_));
if (pimpl->panService_ != nullptr) {
pimpl->panService_->DeregisterObserver(*pimpl->observerImp_.get());
}
}
ErrCode BluetoothPanServer::RegisterObserver(const sptr<IBluetoothPanObserver> observer)
{
HILOGI("enter");
if (observer == nullptr) {
HILOGE("observer is null");
return ERR_INVALID_VALUE;
}
if (pimpl == nullptr) {
HILOGE("pimpl is null");
return ERR_NO_INIT;
}
auto func = std::bind(&BluetoothPanServer::DeregisterObserver, this, std::placeholders::_1);
pimpl->observers_.Register(observer, func);
std::lock_guard<std::mutex> lock(pimpl->advCallBackMutex);
pimpl->advCallBack_.push_back(observer);
return ERR_OK;
}
ErrCode BluetoothPanServer::DeregisterObserver(const sptr<IBluetoothPanObserver> observer)
{
HILOGI("enter");
if (observer == nullptr) {
HILOGE("observer is null");
return ERR_INVALID_VALUE;
}
if (pimpl == nullptr) {
HILOGE("pimpl is null");
return ERR_NO_INIT;
}
{
std::lock_guard<std::mutex> lock(pimpl->advCallBackMutex);
for (auto iter = pimpl->advCallBack_.begin(); iter != pimpl->advCallBack_.end(); ++iter) {
if ((*iter)->AsObject() == observer->AsObject()) {
if (pimpl != nullptr) {
pimpl->observers_.Deregister(*iter);
pimpl->advCallBack_.erase(iter);
break;
}
}
}
}
pimpl->panService_->DeregisterObserver(*pimpl->observerImp_.get());
return ERR_OK;
}
int32_t BluetoothPanServer::GetDevicesByStates(const std::vector<int32_t> &states,
std::vector<BluetoothRawAddress>& result)
{
HILOGI("enter");
if (pimpl == nullptr || pimpl->panService_ == nullptr) {
HILOGI("not init.");
return BT_ERR_INTERNAL_ERROR;
}
std::vector<bluetooth::RawAddress> serviceDeviceList = pimpl->panService_->GetDevicesByStates(states);
for (auto &device : serviceDeviceList) {
BluetoothRawAddress bluetoothDevice(device.GetAddress());
result.push_back(bluetoothDevice);
}
return NO_ERROR;
}
int32_t BluetoothPanServer::GetDeviceState(const BluetoothRawAddress &device, int32_t &state)
{
if (pimpl == nullptr || pimpl->panService_ == nullptr) {
HILOGI("not init.");
return BT_ERR_INTERNAL_ERROR;
}
state = pimpl->panService_->GetDeviceState(device);
HILOGI("addr:%{public}s, res:%{public}d", GET_ENCRYPT_ADDR(device), state);
return NO_ERROR;
}
int32_t BluetoothPanServer::Disconnect(const BluetoothRawAddress &device)
{
HILOGI("addr:%{public}s", GET_ENCRYPT_ADDR(device));
if (pimpl == nullptr || pimpl->panService_ == nullptr) {
HILOGI("not init.");
return BT_ERR_INTERNAL_ERROR;
}
return pimpl->panService_->Disconnect(device);
}
int32_t BluetoothPanServer::Connect(const BluetoothRawAddress &device)
{
HILOGI("NOT SUPPORT NOW");
return BT_NO_ERROR;
}
int32_t BluetoothPanServer::SetTethering(const bool enable)
{
HILOGI("enable:%{public}d", enable);
if (pimpl == nullptr || pimpl->panService_ == nullptr) {
HILOGI("not init.");
return BT_ERR_INTERNAL_ERROR;
}
return pimpl->panService_->SetTethering(enable);
}
int32_t BluetoothPanServer::IsTetheringOn(bool& result)
{
if (pimpl == nullptr || pimpl->panService_ == nullptr) {
HILOGI("not init.");
return BT_ERR_INTERNAL_ERROR;
}
result = pimpl->panService_->IsTetheringOn();
HILOGI("IsTetheringOn:%{public}d", result);
return NO_ERROR;
}
int32_t BluetoothPanServer::SetConnectStrategy(const BluetoothRawAddress &device, int strategy)
{
HILOGI("NOT SUPPORT NOW");
return BT_NO_ERROR;
}
int32_t BluetoothPanServer::GetConnectStrategy(const BluetoothRawAddress &device, int &strategy)
{
HILOGI("NOT SUPPORT NOW");
return BT_NO_ERROR;
}
}
}