195489c19Sopenharmony_ci/*
295489c19Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
395489c19Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
495489c19Sopenharmony_ci * you may not use this file except in compliance with the License.
595489c19Sopenharmony_ci * You may obtain a copy of the License at
695489c19Sopenharmony_ci *
795489c19Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
895489c19Sopenharmony_ci *
995489c19Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1095489c19Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1195489c19Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1295489c19Sopenharmony_ci * See the License for the specific language governing permissions and
1395489c19Sopenharmony_ci * limitations under the License.
1495489c19Sopenharmony_ci */
1595489c19Sopenharmony_ci
1695489c19Sopenharmony_ci#include <list>
1795489c19Sopenharmony_ci#include <mutex>
1895489c19Sopenharmony_ci#include <string>
1995489c19Sopenharmony_ci#include "bluetooth_map_mse_observer_stub.h"
2095489c19Sopenharmony_ci#include "bluetooth_map_mse_proxy.h"
2195489c19Sopenharmony_ci#include "bluetooth_map_mse.h"
2295489c19Sopenharmony_ci#include "bluetooth_remote_device.h"
2395489c19Sopenharmony_ci#include "bluetooth_host.h"
2495489c19Sopenharmony_ci#include "bluetooth_profile_manager.h"
2595489c19Sopenharmony_ci#include "bluetooth_utils.h"
2695489c19Sopenharmony_ci#include "bluetooth_observer_list.h"
2795489c19Sopenharmony_ci#include "iservice_registry.h"
2895489c19Sopenharmony_ci#include "raw_address.h"
2995489c19Sopenharmony_ci#include "system_ability_definition.h"
3095489c19Sopenharmony_ci#include "bluetooth_host_proxy.h"
3195489c19Sopenharmony_ci#include "bluetooth_log.h"
3295489c19Sopenharmony_ci
3395489c19Sopenharmony_cinamespace OHOS {
3495489c19Sopenharmony_cinamespace Bluetooth {
3595489c19Sopenharmony_ciclass BluetoothMapMseObserverImp : public BluetoothMapMseObserverStub {
3695489c19Sopenharmony_cipublic:
3795489c19Sopenharmony_ci    explicit BluetoothMapMseObserverImp(BluetoothObserverList<MapMseObserver> &observers)
3895489c19Sopenharmony_ci        : observers_(observers)
3995489c19Sopenharmony_ci    {}
4095489c19Sopenharmony_ci    ~BluetoothMapMseObserverImp() override
4195489c19Sopenharmony_ci    {}
4295489c19Sopenharmony_ci
4395489c19Sopenharmony_ci    void OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t cause) override
4495489c19Sopenharmony_ci    {
4595489c19Sopenharmony_ci        HILOGI("enter, device: %{public}s, state: %{public}s, cause: %{public}d",
4695489c19Sopenharmony_ci            GET_ENCRYPT_RAW_ADDR(device), GetProfileConnStateName(state).c_str(), cause);
4795489c19Sopenharmony_ci        observers_.ForEach([device, state, cause](std::shared_ptr<MapMseObserver> observer) {
4895489c19Sopenharmony_ci            BluetoothRemoteDevice dev(device.GetAddress(), 0);
4995489c19Sopenharmony_ci            observer->OnConnectionStateChanged(dev, state, cause);
5095489c19Sopenharmony_ci        });
5195489c19Sopenharmony_ci    }
5295489c19Sopenharmony_ci
5395489c19Sopenharmony_ciprivate:
5495489c19Sopenharmony_ci    BluetoothObserverList<MapMseObserver> &observers_;
5595489c19Sopenharmony_ci    BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothMapMseObserverImp);
5695489c19Sopenharmony_ci};
5795489c19Sopenharmony_ci
5895489c19Sopenharmony_cistruct MapMse::impl {
5995489c19Sopenharmony_ci    impl();
6095489c19Sopenharmony_ci    ~impl();
6195489c19Sopenharmony_ci    void RegisterObserver(std::shared_ptr<MapMseObserver> &observer);
6295489c19Sopenharmony_ci    void DeregisterObserver(std::shared_ptr<MapMseObserver> &observer);
6395489c19Sopenharmony_ci    int32_t profileRegisterId = 0;
6495489c19Sopenharmony_ciprivate:
6595489c19Sopenharmony_ci    BluetoothObserverList<MapMseObserver> observers_;
6695489c19Sopenharmony_ci    sptr<BluetoothMapMseObserverImp> serviceObserverImp_ = nullptr;
6795489c19Sopenharmony_ci};
6895489c19Sopenharmony_ci
6995489c19Sopenharmony_ciMapMse::impl::impl()
7095489c19Sopenharmony_ci{
7195489c19Sopenharmony_ci    serviceObserverImp_ = new (std::nothrow) BluetoothMapMseObserverImp(observers_);
7295489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(serviceObserverImp_ != nullptr, "serviceObserverImp_ is nullptr");
7395489c19Sopenharmony_ci    profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_MAP_MSE,
7495489c19Sopenharmony_ci        [this](sptr<IRemoteObject> remote) {
7595489c19Sopenharmony_ci        sptr<IBluetoothMapMse> proxy = iface_cast<IBluetoothMapMse>(remote);
7695489c19Sopenharmony_ci        CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
7795489c19Sopenharmony_ci        proxy->RegisterObserver(serviceObserverImp_);
7895489c19Sopenharmony_ci    });
7995489c19Sopenharmony_ci};
8095489c19Sopenharmony_ci
8195489c19Sopenharmony_ciMapMse::impl::~impl()
8295489c19Sopenharmony_ci{
8395489c19Sopenharmony_ci    HILOGD("enter");
8495489c19Sopenharmony_ci    BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
8595489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
8695489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
8795489c19Sopenharmony_ci    proxy->DeregisterObserver(serviceObserverImp_);
8895489c19Sopenharmony_ci}
8995489c19Sopenharmony_ci
9095489c19Sopenharmony_civoid MapMse::impl::RegisterObserver(std::shared_ptr<MapMseObserver> &observer)
9195489c19Sopenharmony_ci{
9295489c19Sopenharmony_ci    HILOGI("enter");
9395489c19Sopenharmony_ci    if (observer) {
9495489c19Sopenharmony_ci        observers_.Register(observer);
9595489c19Sopenharmony_ci    }
9695489c19Sopenharmony_ci}
9795489c19Sopenharmony_ci
9895489c19Sopenharmony_civoid MapMse::impl::DeregisterObserver(std::shared_ptr<MapMseObserver> &observer)
9995489c19Sopenharmony_ci{
10095489c19Sopenharmony_ci    HILOGI("enter");
10195489c19Sopenharmony_ci    if (observer) {
10295489c19Sopenharmony_ci        observers_.Deregister(observer);
10395489c19Sopenharmony_ci    }
10495489c19Sopenharmony_ci}
10595489c19Sopenharmony_ci
10695489c19Sopenharmony_ciMapMse *MapMse::GetProfile()
10795489c19Sopenharmony_ci{
10895489c19Sopenharmony_ci#ifdef DTFUZZ_TEST
10995489c19Sopenharmony_ci    static BluetoothNoDestructor<MapMse> instance;
11095489c19Sopenharmony_ci    return instance.get();
11195489c19Sopenharmony_ci#else
11295489c19Sopenharmony_ci    static MapMse instance;
11395489c19Sopenharmony_ci    return &instance;
11495489c19Sopenharmony_ci#endif
11595489c19Sopenharmony_ci}
11695489c19Sopenharmony_ci
11795489c19Sopenharmony_ciMapMse::MapMse()
11895489c19Sopenharmony_ci{
11995489c19Sopenharmony_ci    pimpl = std::make_unique<impl>();
12095489c19Sopenharmony_ci}
12195489c19Sopenharmony_ci
12295489c19Sopenharmony_ciMapMse::~MapMse()
12395489c19Sopenharmony_ci{
12495489c19Sopenharmony_ci    HILOGI("enter");
12595489c19Sopenharmony_ci}
12695489c19Sopenharmony_ci
12795489c19Sopenharmony_civoid MapMse::RegisterObserver(std::shared_ptr<MapMseObserver> observer)
12895489c19Sopenharmony_ci{
12995489c19Sopenharmony_ci    HILOGI("enter");
13095489c19Sopenharmony_ci    pimpl->RegisterObserver(observer);
13195489c19Sopenharmony_ci}
13295489c19Sopenharmony_ci
13395489c19Sopenharmony_civoid MapMse::DeregisterObserver(std::shared_ptr<MapMseObserver> observer)
13495489c19Sopenharmony_ci{
13595489c19Sopenharmony_ci    HILOGI("enter");
13695489c19Sopenharmony_ci    pimpl->DeregisterObserver(observer);
13795489c19Sopenharmony_ci}
13895489c19Sopenharmony_ci
13995489c19Sopenharmony_ciint32_t MapMse::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state) const
14095489c19Sopenharmony_ci{
14195489c19Sopenharmony_ci    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
14295489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
14395489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
14495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
14595489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
14695489c19Sopenharmony_ci
14795489c19Sopenharmony_ci    return proxy->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state);
14895489c19Sopenharmony_ci}
14995489c19Sopenharmony_ci
15095489c19Sopenharmony_ciint32_t MapMse::GetDevicesByStates(const std::vector<int32_t> &states, std::vector<BluetoothRemoteDevice> &result) const
15195489c19Sopenharmony_ci{
15295489c19Sopenharmony_ci    HILOGI("enter");
15395489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
15495489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
15595489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
15695489c19Sopenharmony_ci
15795489c19Sopenharmony_ci    std::vector<BluetoothRawAddress> rawAddress {};
15895489c19Sopenharmony_ci    int32_t ret = proxy->GetDevicesByStates(states, rawAddress);
15995489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET((ret == BT_NO_ERROR), ret, "inner error");
16095489c19Sopenharmony_ci
16195489c19Sopenharmony_ci    for (BluetoothRawAddress rawAddr : rawAddress) {
16295489c19Sopenharmony_ci        BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR);
16395489c19Sopenharmony_ci        result.push_back(device);
16495489c19Sopenharmony_ci    }
16595489c19Sopenharmony_ci    return BT_NO_ERROR;
16695489c19Sopenharmony_ci}
16795489c19Sopenharmony_ci
16895489c19Sopenharmony_ciint32_t MapMse::Disconnect(const BluetoothRemoteDevice &device)
16995489c19Sopenharmony_ci{
17095489c19Sopenharmony_ci    HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
17195489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
17295489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
17395489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
17495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
17595489c19Sopenharmony_ci
17695489c19Sopenharmony_ci    return proxy->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
17795489c19Sopenharmony_ci}
17895489c19Sopenharmony_ci
17995489c19Sopenharmony_ciint32_t MapMse::SetConnectionStrategy(const BluetoothRemoteDevice &device, int32_t strategy)
18095489c19Sopenharmony_ci{
18195489c19Sopenharmony_ci    HILOGI("device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
18295489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
18395489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
18495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
18595489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
18695489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(CheckConnectionStrategyInvalid(strategy), BT_ERR_INVALID_PARAM, "strategy param error");
18795489c19Sopenharmony_ci
18895489c19Sopenharmony_ci    return proxy->SetConnectionStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
18995489c19Sopenharmony_ci}
19095489c19Sopenharmony_ci
19195489c19Sopenharmony_ciint32_t MapMse::GetConnectionStrategy(const BluetoothRemoteDevice &device, int32_t &strategy) const
19295489c19Sopenharmony_ci{
19395489c19Sopenharmony_ci    HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
19495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
19595489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
19695489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
19795489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
19895489c19Sopenharmony_ci
19995489c19Sopenharmony_ci    return proxy->GetConnectionStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
20095489c19Sopenharmony_ci}
20195489c19Sopenharmony_ci
20295489c19Sopenharmony_ciint32_t MapMse::SetMessageAccessAuthorization(const BluetoothRemoteDevice &device, int32_t accessAuthorization)
20395489c19Sopenharmony_ci{
20495489c19Sopenharmony_ci    HILOGI("device: %{public}s, accessAuthorization: %{public}d", GET_ENCRYPT_ADDR(device), accessAuthorization);
20595489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
20695489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
20795489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
20895489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
20995489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(CheckAccessAuthorizationInvalid(accessAuthorization),
21095489c19Sopenharmony_ci        BT_ERR_INVALID_PARAM, "metaData param error");
21195489c19Sopenharmony_ci
21295489c19Sopenharmony_ci    return proxy->SetMessageAccessAuthorization(
21395489c19Sopenharmony_ci        BluetoothRawAddress(device.GetDeviceAddr()), accessAuthorization);
21495489c19Sopenharmony_ci}
21595489c19Sopenharmony_ci
21695489c19Sopenharmony_ciint32_t MapMse::GetMessageAccessAuthorization(const BluetoothRemoteDevice &device, int32_t &accessAuthorization) const
21795489c19Sopenharmony_ci{
21895489c19Sopenharmony_ci    HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
21995489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
22095489c19Sopenharmony_ci    sptr<IBluetoothMapMse> proxy = GetRemoteProxy<IBluetoothMapMse>(PROFILE_MAP_MSE);
22195489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "proxy is nullptr");
22295489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "device param error");
22395489c19Sopenharmony_ci
22495489c19Sopenharmony_ci    return proxy->GetMessageAccessAuthorization(
22595489c19Sopenharmony_ci        BluetoothRawAddress(device.GetDeviceAddr()), accessAuthorization);
22695489c19Sopenharmony_ci}
22795489c19Sopenharmony_ci
22895489c19Sopenharmony_ci} // namespace Bluetooth
22995489c19Sopenharmony_ci} // namespace OHOS