d32022a6创建于 5月19日历史提交
/*
 * Copyright (C) 2021-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 <list>
#include <mutex>
#include <thread>

#include "bluetooth_gatt_client_server.h"
#include "bluetooth_hitrace.h"
#include "bluetooth_errorcode.h"
#include "bluetooth_log.h"
#include "hisysevent.h"
#include "interface_adapter_ble.h"
#include "interface_adapter_classic.h"
#include "interface_adapter_manager.h"
#include "interface_profile_gatt_client.h"
#include "interface_profile_manager.h"
#include "bluetooth_utils_server.h"
#include "string_ex.h"
#include "system_ability_definition.h"
#include "ipc_skeleton.h"
#include "permission_manager.h"

using namespace OHOS::bluetooth;
namespace OHOS {
namespace Bluetooth {

constexpr int32_t CONN_UNKNOWN = 4;
inline const std::string GATT_DIS_MSG_CONN_UNKNOWN = "CONN_UNKNOWN";
struct BluetoothGattClientServer::impl {
    class GattClientCallbackImpl;
    class SystemStateObserver;

    IProfileGattClient *clientService_;
    std::unique_ptr<SystemStateObserver> systemStateObserver_;
    std::list<std::unique_ptr<GattClientCallbackImpl>> callbacks_;
    std::mutex registerMutex_;

    impl();
    ~impl();

    IProfileGattClient *GetServicePtr()
    {
        if (IProfileManager::GetInstance() == nullptr) {
            return nullptr;
        }
        return static_cast<IProfileGattClient *>(
            IProfileManager::GetInstance()->GetProfileService(PROFILE_NAME_GATT_CLIENT));
    }
};

class BluetoothGattClientServer::impl::SystemStateObserver : public ISystemStateObserver {
public:
    SystemStateObserver(BluetoothGattClientServer::impl *impl) : impl_(impl){};
    ~SystemStateObserver() override = default;

    void OnSystemStateChange(const BTSystemState state) override
    {
        std::lock_guard<std::mutex> lck(impl_->registerMutex_);
        switch (state) {
            case BTSystemState::ON:
                impl_->clientService_ = impl_->GetServicePtr();
                break;
            case BTSystemState::OFF:
                impl_->clientService_ = nullptr;
                break;
            default:
                break;
        }
    }

private:
    BluetoothGattClientServer::impl *impl_;
};

namespace {

bool CheckGattClientPermission(uint64_t tokenId, int sdkVersion)
{
    if (PermissionManager::IsNativeCaller(tokenId) || sdkVersion >= API_VERSION_10) {
        if (!PermissionManager::VerifyPermission(ACCESS_BLUETOOTH, tokenId)) {
                HILOGI("check ACCESS_BLUETOOTH permission failed");
                return false;
        }
    } else {
        if (!PermissionManager::VerifyPermission(USE_BLUETOOTH, tokenId)) {
                HILOGI("check USE_BLUETOOTH permission failed");
                return false;
        }
    }
    return true;
}
}  // namespace {}

class BluetoothGattClientServer::impl::GattClientCallbackImpl : public IGattClientCallback {
public:
    void OnConnectionStateChanged(int state, int newState) override
    {
        HILOGI("curState(%{public}d) -> newState(%{public}d)", state, newState);
        if (!CheckGattClientPermission(tokenId_, PermissionManager::GetApiVersion(tokenId_))) {
            return;
        }
        int32_t pid = IPCSkeleton::GetCallingPid();
        int32_t uid = IPCSkeleton::GetCallingUid();
        if (state == static_cast<int>(BTConnectState::CONNECTED) ||
            state == static_cast<int>(BTConnectState::DISCONNECTED)) {
            HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BT_SERVICE, "GATT_CLIENT_CONN_STATE",
                OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "PID", pid, "UID", uid, "STATE", state);
        }
        callback_->OnConnectionStateChanged(state, newState, CONN_UNKNOWN, GATT_DIS_MSG_CONN_UNKNOWN);
    }

    void OnCharacteristicChanged(const Characteristic &characteristic) override
    {
        HILOGI("enter");
        if (!CheckGattClientPermission(tokenId_, PermissionManager::GetApiVersion(tokenId_))) {
            return;
        }
        callback_->OnCharacteristicChanged((BluetoothGattCharacteristic)characteristic);
    }

    void OnCharacteristicRead(int ret, const Characteristic &characteristic) override
    {
        HILOGI("ret: %{public}d", ret);
        callback_->OnCharacteristicRead(ret, (BluetoothGattCharacteristic)characteristic);
    }

    void OnCharacteristicWrite(int ret, const Characteristic &characteristic) override
    {
        HILOGI("ret: %{public}d", ret);
        BluetoothGattRspContext rspContext; // To adapt to WriteCharacteristicValueWithContext, useless.
        callback_->OnCharacteristicWrite(ret, (BluetoothGattCharacteristic)characteristic, rspContext);
    }

    void OnDescriptorRead(int ret, const Descriptor &descriptor) override
    {
        HILOGI("ret: %{public}d", ret);
        callback_->OnDescriptorRead(ret, (BluetoothGattDescriptor)descriptor);
    }

    void OnDescriptorWrite(int ret, const Descriptor &descriptor) override
    {
        HILOGI("ret: %{public}d", ret);
        callback_->OnDescriptorWrite(ret, (BluetoothGattDescriptor)descriptor);
    }

    void OnMtuChanged(int state, int mtu) override
    {
        HILOGI("state: %{public}d, mtu: %{public}d", state, mtu);
        if (PermissionManager::IsNativeCaller(tokenId_) ||
            PermissionManager::GetApiVersion(tokenId_) >= API_VERSION_10) {
            if (PermissionManager::VerifyPermission(ACCESS_BLUETOOTH, tokenId_) == false) {
                HILOGE("check access permission failed.");
                return;
            }
        }
        callback_->OnMtuChanged(state, mtu);
    }

    void OnReadRemoteRssiValue(const RawAddress &addr, int rssi, int status) override
    {
        return;
    }

    void OnServicesDiscovered(int status) override
    {
        HILOGI("status: %{public}d", status);
        callback_->OnServicesDiscovered(status);
    }

    void OnConnectionParameterChanged(int interval, int latency, int timeout, int status) override
    {
        HILOGI("interval: %{public}d, latency: %{public}d, timeout: %{public}d, status: %{public}d",
            interval, latency, timeout, status);
        callback_->OnConnectionParameterChanged(interval, latency, timeout, status);
    }

    void OnServicesChanged() override
    {
        HILOGI("enter");
        callback_->OnServicesChanged();
    }

    sptr<IBluetoothGattClientCallback> GetCallback()
    {
        return callback_;
    }

    void SetAppId(int appId)
    {
        applicationId_ = appId;
    }

    int GetAppId()
    {
        return applicationId_;
    }

    GattClientCallbackImpl(const sptr<IBluetoothGattClientCallback> &callback, BluetoothGattClientServer &owner);
    ~GattClientCallbackImpl()
    {
        if (!callback_->AsObject()->RemoveDeathRecipient(deathRecipient_)) {
            HILOGE("Failed to unlink death recipient to callback");
        }
        callback_ = nullptr;
        deathRecipient_ = nullptr;
    };

private:
    class CallbackDeathRecipient : public IRemoteObject::DeathRecipient {
    public:
        CallbackDeathRecipient(const sptr<IBluetoothGattClientCallback> &callback, BluetoothGattClientServer &owner);

        sptr<IBluetoothGattClientCallback> GetCallback() const
        {
            return callback_;
        };

        void OnRemoteDied(const wptr<IRemoteObject> &remote) override;

    private:
        sptr<IBluetoothGattClientCallback> callback_;
        BluetoothGattClientServer &owner_;
    };

    sptr<IBluetoothGattClientCallback> callback_;
    sptr<CallbackDeathRecipient> deathRecipient_;
    int applicationId_;
    uint32_t tokenId_;
};

BluetoothGattClientServer::impl::GattClientCallbackImpl::GattClientCallbackImpl(
    const sptr<IBluetoothGattClientCallback> &callback, BluetoothGattClientServer &owner)
    : callback_(callback), deathRecipient_(new CallbackDeathRecipient(callback, owner))
{
    if (!callback_->AsObject()->AddDeathRecipient(deathRecipient_)) {
        HILOGE("Failed to link death recipient to callback");
    }
    tokenId_ = IPCSkeleton::GetCallingTokenID();
}

BluetoothGattClientServer::impl::GattClientCallbackImpl::CallbackDeathRecipient::CallbackDeathRecipient(
    const sptr<IBluetoothGattClientCallback> &callback, BluetoothGattClientServer &owner)
    : callback_(callback), owner_(owner)
{}

void BluetoothGattClientServer::impl::GattClientCallbackImpl::CallbackDeathRecipient::OnRemoteDied(
    const wptr<IRemoteObject> &remote)
{
    HILOGI("enter");
    if (owner_.pimpl == nullptr || owner_.pimpl->clientService_ == nullptr) {
        HILOGE("gattClientServerImpl clientService_ is not support.");
        return;
    }
    std::lock_guard<std::mutex> lck(owner_.pimpl->registerMutex_);
    for (auto it = owner_.pimpl->callbacks_.begin(); it != owner_.pimpl->callbacks_.end(); ++it) {
        if ((*it)->GetCallback()->AsObject() == remote) {
            HILOGI("callback is found from callbacks");
            sptr<CallbackDeathRecipient> dr = (*it)->deathRecipient_;
            if (!dr->GetCallback()->AsObject()->RemoveDeathRecipient(dr)) {
                HILOGE("Failed to unlink death recipient from callback");
            }
            HILOGI("App id is %{public}d", (*it)->GetAppId());
            owner_.pimpl->clientService_->Disconnect((*it)->GetAppId());
            owner_.pimpl->clientService_->DeregisterApplication((*it)->GetAppId());
            owner_.pimpl->callbacks_.erase(it);
            return;
        }
    }
    HILOGE("No callback erased from callbacks");
}

BluetoothGattClientServer::impl::impl() : clientService_(nullptr), systemStateObserver_(new SystemStateObserver(this))
{
    IAdapterManager::GetInstance()->RegisterSystemStateObserver(*systemStateObserver_);
}

BluetoothGattClientServer::impl::~impl()
{
    IAdapterManager::GetInstance()->DeregisterSystemStateObserver(*systemStateObserver_);
}

BluetoothGattClientServer::BluetoothGattClientServer() : pimpl(new impl())
{
    HILOGI("enter");
}

BluetoothGattClientServer::~BluetoothGattClientServer()
{}

int BluetoothGattClientServer::RegisterApplication(
    const sptr<IBluetoothGattClientCallback> &callback, const BluetoothRawAddress &addr, int32_t transport)
{
    int appId = 0;
    int ret = RegisterApplication(callback, addr, transport, appId);
    return (ret == NO_ERROR) ? appId : ret;
}

int BluetoothGattClientServer::RegisterApplication(
    const sptr<IBluetoothGattClientCallback> &callback, const BluetoothRawAddress &addr, int32_t transport, int &appId)
{
    HILOGI("address: %{public}s, transport: %{public}d", GetEncryptAddr(addr.GetAddress()).c_str(), transport);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    pimpl->clientService_ = pimpl->GetServicePtr();
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    auto it = pimpl->callbacks_.emplace(
        pimpl->callbacks_.begin(), std::make_unique<impl::GattClientCallbackImpl>(callback, *this));
    appId = pimpl->clientService_->RegisterSharedApplication(*it->get(), (RawAddress)addr, transport);
    if (appId >= 0) {
        HILOGI("appId: %{public}d", appId);
        (*it)->SetAppId(appId);
        HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BT_SERVICE, "GATT_APP_REGISTER",
            OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,  "ACTION", "register",
            "SIDE", "client", "ADDRESS", GetEncryptAddr(addr.GetAddress()), "PID", OHOS::IPCSkeleton::GetCallingPid(),
            "UID", OHOS::IPCSkeleton::GetCallingUid(), "APPID", appId);
    } else {
        HILOGE("RegisterSharedApplication failed, appId: %{public}d", appId);
        pimpl->callbacks_.erase(it);
    }
    return NO_ERROR;
}

int BluetoothGattClientServer::DeregisterApplication(int32_t appId)
{
    HILOGI("appId: %{public}d", appId);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return bluetooth::GattStatus::REQUEST_NOT_SUPPORT;
    }
    HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::BT_SERVICE, "GATT_APP_REGISTER",
        OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,  "ACTION", "deregister",
        "SIDE", "client", "ADDRESS", "empty", "PID", OHOS::IPCSkeleton::GetCallingPid(),
        "UID", OHOS::IPCSkeleton::GetCallingUid(), "APPID", appId);

    auto it = std::find_if(pimpl->callbacks_.begin(), pimpl->callbacks_.end(),
        [appId](const std::unique_ptr<impl::GattClientCallbackImpl> &p) { return p->GetAppId() == appId; });
    if (it == pimpl->callbacks_.end()) {
        HILOGE("Unknown appId: %{public}d", appId);
        return INVALID_PARAMETER;
    }

    int ret = pimpl->clientService_->DeregisterApplication(appId);
    pimpl->callbacks_.erase(it);
    return ret;
}

int BluetoothGattClientServer::Connect(int32_t appId, bool autoConnect)
{
    HILOGI("appId: %{public}d, autoConnect: %{public}d", appId, autoConnect);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    OHOS::Bluetooth::BluetoothHiTrace::BluetoothStartAsyncTrace("GATT_CLIENT_CONNECT", 1);
    int result = pimpl->clientService_->Connect(appId, autoConnect);
    OHOS::Bluetooth::BluetoothHiTrace::BluetoothFinishAsyncTrace("GATT_CLIENT_CONNECT", 1);
    return result;
}

int BluetoothGattClientServer::Disconnect(int32_t appId)
{
    HILOGI("appId: %{public}d", appId);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    return pimpl->clientService_->Disconnect(appId);
}

int BluetoothGattClientServer::DiscoveryServices(int32_t appId)
{
    HILOGI("appId: %{public}d", appId);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    return pimpl->clientService_->DiscoveryServices(appId);
}

int BluetoothGattClientServer::ReadCharacteristic(int32_t appId, const BluetoothGattCharacteristic &characteristic)
{
    HILOGI("appId: %{public}d", appId);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    return pimpl->clientService_->ReadCharacteristic(appId, (Characteristic)characteristic);
}

int BluetoothGattClientServer::WriteCharacteristic(
    int32_t appId, BluetoothGattCharacteristic *characteristic, bool withoutRespond, bool isWithContext)
{
    if (isWithContext) {
        HILOGE("API WriteCharacteristicValueWithContext is not supported.");
        return BT_ERR_API_NOT_SUPPORT;
    }
    HILOGI("appId: %{public}d, withoutRespond: %{public}d", appId, withoutRespond);
    Characteristic character(characteristic->handle_);
    character.length_ = characteristic->length_;
    character.value_ = std::move(characteristic->value_);
    characteristic->length_ = 0;
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    return pimpl->clientService_->WriteCharacteristic(appId, character, withoutRespond);
}
int BluetoothGattClientServer::SignedWriteCharacteristic(int32_t appId, BluetoothGattCharacteristic *characteristic)
{
    HILOGI("appId: %{public}d", appId);
    Characteristic character(characteristic->handle_);
    character.length_ = characteristic->length_;
    character.value_ = std::move(characteristic->value_);
    characteristic->length_ = 0;
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return bluetooth::GattStatus::REQUEST_NOT_SUPPORT;
    }
    return pimpl->clientService_->SignedWriteCharacteristic(appId, character);
}

int BluetoothGattClientServer::ReadDescriptor(int32_t appId, const BluetoothGattDescriptor &descriptor)
{
    HILOGI("appId: %{public}d", appId);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    return pimpl->clientService_->ReadDescriptor(appId, (Descriptor)descriptor);
}

int BluetoothGattClientServer::WriteDescriptor(int32_t appId, BluetoothGattDescriptor *descriptor)
{
    HILOGI("appId: %{public}d", appId);
    Descriptor desc(descriptor->handle_);
    desc.length_ = descriptor->length_;
    desc.value_ = std::move(descriptor->value_);
    descriptor->length_ = 0;
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    return pimpl->clientService_->WriteDescriptor(appId, desc);
}

int BluetoothGattClientServer::RequestExchangeMtu(int32_t appId, int32_t mtu)
{
    HILOGI("appId: %{public}d, mtu: %{public}d", appId, mtu);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    return pimpl->clientService_->RequestExchangeMtu(appId, mtu);
}

void BluetoothGattClientServer::GetAllDevice(::std::vector<BluetoothGattDevice> &device)
{
    HILOGI("enter");
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return;
    }
    for (auto &dev : pimpl->clientService_->GetAllDevice()) {
        device.push_back(dev);
    }
}

int BluetoothGattClientServer::RequestConnectionPriority(int32_t appId, int32_t connPriority)
{
    HILOGI("appId: %{public}d, connPriority: %{public}d", appId, connPriority);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return 0;
    }
    return pimpl->clientService_->RequestConnectionPriority(appId, connPriority);
}

int BluetoothGattClientServer::GetServices(int32_t appId, ::std::vector<BluetoothGattService> &service)
{
    HILOGI("appId: %{public}d", appId);
    std::lock_guard<std::mutex> lck(pimpl->registerMutex_);
    if (pimpl->clientService_ == nullptr) {
        HILOGE("request not support.");
        return BT_ERR_INTERNAL_ERROR;
    }
    for (auto &svc : pimpl->clientService_->GetServices(appId)) {
        service.push_back(svc);
    }
    return NO_ERROR;
}

int BluetoothGattClientServer::RequestFastestConn(const BluetoothRawAddress &addr)
{
    HILOGI("NOT SUPPORT NOW");
    return NO_ERROR;
}

int BluetoothGattClientServer::ReadRemoteRssiValue(int32_t appId)
{
    HILOGI("NOT SUPPORT NOW");
    return NO_ERROR;
}

int BluetoothGattClientServer::RequestNotification(int32_t appId, uint16_t characterHandle, bool enable)
{
    HILOGI("NOT SUPPORT NOW");
    return NO_ERROR;
}
int BluetoothGattClientServer::GetConnectedState(const std::string &deviceId, int &state)
{
    HILOGI("NOT SUPPORT NOW");
    return NO_ERROR;
}
int BluetoothGattClientServer::SetPhy(int32_t appId, int32_t txPhy, int32_t rxPhy, int32_t phyOptions)
{
    HILOGI("NOT SUPPORT NOW");
    return NO_ERROR;
}
int BluetoothGattClientServer::ReadPhy(int32_t appId)
{
    HILOGI("NOT SUPPORT NOW");
    return NO_ERROR;
}
int BluetoothGattClientServer::ReadCharacteristicByUuid(int32_t appId, const std::string &uuid,
    int32_t startHandle, int32_t endHandle)
{
    HILOGI("NOT SUPPORT NOW");
    return NO_ERROR;
}
}  // namespace Bluetooth
}  // namespace OHOS