1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "vendor_interface.h"
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_ci#include <thread>
19094332d3Sopenharmony_ci
20094332d3Sopenharmony_ci#include <dlfcn.h>
21094332d3Sopenharmony_ci
22094332d3Sopenharmony_ci#include <hdf_log.h>
23094332d3Sopenharmony_ci#include <securec.h>
24094332d3Sopenharmony_ci
25094332d3Sopenharmony_ci#include "bluetooth_address.h"
26094332d3Sopenharmony_ci#include "bt_hal_constant.h"
27094332d3Sopenharmony_ci#include "h4_protocol.h"
28094332d3Sopenharmony_ci#include "mct_protocol.h"
29094332d3Sopenharmony_ci
30094332d3Sopenharmony_ci#ifdef LOG_DOMAIN
31094332d3Sopenharmony_ci#undef LOG_DOMAIN
32094332d3Sopenharmony_ci#endif
33094332d3Sopenharmony_ci#define LOG_DOMAIN 0xD000105
34094332d3Sopenharmony_ci
35094332d3Sopenharmony_cinamespace OHOS {
36094332d3Sopenharmony_cinamespace HDI {
37094332d3Sopenharmony_cinamespace Bluetooth {
38094332d3Sopenharmony_cinamespace Hci {
39094332d3Sopenharmony_cinamespace V1_0 {
40094332d3Sopenharmony_ciconstexpr size_t BT_VENDOR_INVALID_DATA_LEN = 0;
41094332d3Sopenharmony_ciBtVendorCallbacksT VendorInterface::vendorCallbacks_ = {
42094332d3Sopenharmony_ci    .size = sizeof(BtVendorCallbacksT),
43094332d3Sopenharmony_ci    .initCb = VendorInterface::OnInitCallback,
44094332d3Sopenharmony_ci    .alloc = VendorInterface::OnMallocCallback,
45094332d3Sopenharmony_ci    .dealloc = VendorInterface::OnFreeCallback,
46094332d3Sopenharmony_ci    .xmitCb = VendorInterface::OnCmdXmitCallback,
47094332d3Sopenharmony_ci};
48094332d3Sopenharmony_ci
49094332d3Sopenharmony_ciVendorInterface::VendorInterface()
50094332d3Sopenharmony_ci{}
51094332d3Sopenharmony_ci
52094332d3Sopenharmony_ciVendorInterface::~VendorInterface()
53094332d3Sopenharmony_ci{
54094332d3Sopenharmony_ci    CleanUp();
55094332d3Sopenharmony_ci}
56094332d3Sopenharmony_ci
57094332d3Sopenharmony_cibool VendorInterface::WatchHciChannel(const ReceiveCallback &receiveCallback)
58094332d3Sopenharmony_ci{
59094332d3Sopenharmony_ci    HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN begin");
60094332d3Sopenharmony_ci    int channel[HCI_MAX_CHANNEL] = {0};
61094332d3Sopenharmony_ci    int channelCount = vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_OPEN, channel);
62094332d3Sopenharmony_ci    if (channelCount < 1 || channelCount > HCI_MAX_CHANNEL) {
63094332d3Sopenharmony_ci        HDF_LOGE("vendorInterface_->op BT_OP_HCI_CHANNEL_OPEN failed ret:%d.", channelCount);
64094332d3Sopenharmony_ci        return false;
65094332d3Sopenharmony_ci    }
66094332d3Sopenharmony_ci    HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN end");
67094332d3Sopenharmony_ci
68094332d3Sopenharmony_ci    if (channelCount == 1) {
69094332d3Sopenharmony_ci        auto h4 = std::make_shared<Hci::H4Protocol>(channel[0],
70094332d3Sopenharmony_ci            receiveCallback.onAclReceive,
71094332d3Sopenharmony_ci            receiveCallback.onScoReceive,
72094332d3Sopenharmony_ci            std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1));
73094332d3Sopenharmony_ci        watcher_.AddFdToWatcher(channel[0], std::bind(&Hci::H4Protocol::ReadData, h4, std::placeholders::_1));
74094332d3Sopenharmony_ci        hci_ = h4;
75094332d3Sopenharmony_ci    } else {
76094332d3Sopenharmony_ci        auto mct = std::make_shared<Hci::MctProtocol>(channel,
77094332d3Sopenharmony_ci            receiveCallback.onAclReceive,
78094332d3Sopenharmony_ci            receiveCallback.onScoReceive,
79094332d3Sopenharmony_ci            std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1));
80094332d3Sopenharmony_ci        watcher_.AddFdToWatcher(
81094332d3Sopenharmony_ci            channel[hci_channels_t::HCI_ACL_IN], std::bind(&Hci::MctProtocol::ReadAclData, mct, std::placeholders::_1));
82094332d3Sopenharmony_ci        watcher_.AddFdToWatcher(
83094332d3Sopenharmony_ci            channel[hci_channels_t::HCI_EVT], std::bind(&Hci::MctProtocol::ReadEventData, mct, std::placeholders::_1));
84094332d3Sopenharmony_ci        hci_ = mct;
85094332d3Sopenharmony_ci    }
86094332d3Sopenharmony_ci
87094332d3Sopenharmony_ci    return true;
88094332d3Sopenharmony_ci}
89094332d3Sopenharmony_ci
90094332d3Sopenharmony_cibool VendorInterface::Initialize(
91094332d3Sopenharmony_ci    InitializeCompleteCallback initializeCompleteCallback, const ReceiveCallback &receiveCallback)
92094332d3Sopenharmony_ci{
93094332d3Sopenharmony_ci    HDF_LOGI("VendorInterface %{public}s, ", __func__);
94094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
95094332d3Sopenharmony_ci    initializeCompleteCallback_ = initializeCompleteCallback;
96094332d3Sopenharmony_ci    eventDataCallback_ = receiveCallback.onEventReceive;
97094332d3Sopenharmony_ci
98094332d3Sopenharmony_ci    HDF_LOGI("VendorInterface dlopen");
99094332d3Sopenharmony_ci    vendorHandle_ = dlopen(BT_VENDOR_NAME, RTLD_NOW);
100094332d3Sopenharmony_ci    if (vendorHandle_ == nullptr) {
101094332d3Sopenharmony_ci        HDF_LOGE("VendorInterface dlopen %{public}s failed, error code: %{public}s", BT_VENDOR_NAME, dlerror());
102094332d3Sopenharmony_ci        return false;
103094332d3Sopenharmony_ci    }
104094332d3Sopenharmony_ci
105094332d3Sopenharmony_ci    vendorInterface_ =
106094332d3Sopenharmony_ci        reinterpret_cast<BtVendorInterfaceT *>(dlsym(vendorHandle_, BT_VENDOR_INTERFACE_SYMBOL_NAME));
107094332d3Sopenharmony_ci
108094332d3Sopenharmony_ci    auto bluetoothAddress = BluetoothAddress::GetDeviceAddress();
109094332d3Sopenharmony_ci    std::vector<uint8_t> address = { 0, 0, 0, 0, 0, 0 };
110094332d3Sopenharmony_ci    if (bluetoothAddress != nullptr) {
111094332d3Sopenharmony_ci        bluetoothAddress->ReadAddress(address);
112094332d3Sopenharmony_ci    }
113094332d3Sopenharmony_ci
114094332d3Sopenharmony_ci    if (vendorInterface_ == nullptr) {
115094332d3Sopenharmony_ci        HDF_LOGE("VendorInterface dlsym %{public}s failed.", BT_VENDOR_INTERFACE_SYMBOL_NAME);
116094332d3Sopenharmony_ci        return false;
117094332d3Sopenharmony_ci    }
118094332d3Sopenharmony_ci
119094332d3Sopenharmony_ci    HDF_LOGI("VendorInterface init");
120094332d3Sopenharmony_ci    int result = vendorInterface_->init(&vendorCallbacks_, address.data());
121094332d3Sopenharmony_ci    if (result != 0) {
122094332d3Sopenharmony_ci        HDF_LOGE("vendorInterface_->init failed.");
123094332d3Sopenharmony_ci        return false;
124094332d3Sopenharmony_ci    }
125094332d3Sopenharmony_ci
126094332d3Sopenharmony_ci    result = vendorInterface_->op(BtOpcodeT::BT_OP_POWER_ON, nullptr);
127094332d3Sopenharmony_ci    if (result != 0) {
128094332d3Sopenharmony_ci        HDF_LOGE("vendorInterface_->op BT_OP_POWER_ON failed.");
129094332d3Sopenharmony_ci        return false;
130094332d3Sopenharmony_ci    }
131094332d3Sopenharmony_ci
132094332d3Sopenharmony_ci    if (!WatchHciChannel(receiveCallback)) {
133094332d3Sopenharmony_ci        return false;
134094332d3Sopenharmony_ci    }
135094332d3Sopenharmony_ci
136094332d3Sopenharmony_ci    if (!watcher_.Start()) {
137094332d3Sopenharmony_ci        HDF_LOGE("watcher start failed.");
138094332d3Sopenharmony_ci        return false;
139094332d3Sopenharmony_ci    }
140094332d3Sopenharmony_ci
141094332d3Sopenharmony_ci    if (vendorInterface_ == nullptr) {
142094332d3Sopenharmony_ci        HDF_LOGE("vendorInterface_ is nullptr");
143094332d3Sopenharmony_ci        return false;
144094332d3Sopenharmony_ci    }
145094332d3Sopenharmony_ci
146094332d3Sopenharmony_ci    HDF_LOGI("VendorInterface BT_OP_INIT");
147094332d3Sopenharmony_ci    vendorInterface_->op(BtOpcodeT::BT_OP_INIT, nullptr);
148094332d3Sopenharmony_ci
149094332d3Sopenharmony_ci    HDF_LOGI("VendorInterface Initialize end");
150094332d3Sopenharmony_ci    return true;
151094332d3Sopenharmony_ci}
152094332d3Sopenharmony_ci
153094332d3Sopenharmony_civoid VendorInterface::CleanUp()
154094332d3Sopenharmony_ci{
155094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
156094332d3Sopenharmony_ci    HDF_LOGE("vendorInterface clean up.");
157094332d3Sopenharmony_ci    if (vendorInterface_ == nullptr) {
158094332d3Sopenharmony_ci        HDF_LOGE("VendorInterface::CleanUp, vendorInterface_ is nullptr.");
159094332d3Sopenharmony_ci        return;
160094332d3Sopenharmony_ci    }
161094332d3Sopenharmony_ci
162094332d3Sopenharmony_ci    watcher_.Stop();
163094332d3Sopenharmony_ci
164094332d3Sopenharmony_ci    vendorInterface_->op(BtOpcodeT::BT_OP_LPM_DISABLE, nullptr);
165094332d3Sopenharmony_ci    vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_CLOSE, nullptr);
166094332d3Sopenharmony_ci    vendorInterface_->op(BtOpcodeT::BT_OP_POWER_OFF, nullptr);
167094332d3Sopenharmony_ci    vendorInterface_->close();
168094332d3Sopenharmony_ci
169094332d3Sopenharmony_ci    hci_ = nullptr;
170094332d3Sopenharmony_ci    vendorInterface_ = nullptr;
171094332d3Sopenharmony_ci    initializeCompleteCallback_ = nullptr;
172094332d3Sopenharmony_ci    eventDataCallback_ = nullptr;
173094332d3Sopenharmony_ci    dlclose(vendorHandle_);
174094332d3Sopenharmony_ci}
175094332d3Sopenharmony_ci
176094332d3Sopenharmony_cisize_t VendorInterface::SendPacket(Hci::HciPacketType type, const std::vector<uint8_t> &packet)
177094332d3Sopenharmony_ci{
178094332d3Sopenharmony_ci    if (vendorInterface_ == nullptr) {
179094332d3Sopenharmony_ci        HDF_LOGE("VendorInterface::SendPacket, vendorInterface_ is nullptr.");
180094332d3Sopenharmony_ci        return BT_VENDOR_INVALID_DATA_LEN;
181094332d3Sopenharmony_ci    }
182094332d3Sopenharmony_ci
183094332d3Sopenharmony_ci    {
184094332d3Sopenharmony_ci        std::lock_guard<std::mutex> lock(wakeupMutex_);
185094332d3Sopenharmony_ci        activity_ = true;
186094332d3Sopenharmony_ci        watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer_), std::bind(&VendorInterface::WatcherTimeout, this));
187094332d3Sopenharmony_ci        if (!wakeupLock_) {
188094332d3Sopenharmony_ci            vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_LOCK, nullptr);
189094332d3Sopenharmony_ci            wakeupLock_ = true;
190094332d3Sopenharmony_ci        }
191094332d3Sopenharmony_ci    }
192094332d3Sopenharmony_ci
193094332d3Sopenharmony_ci    if (hci_ == nullptr) {
194094332d3Sopenharmony_ci        HDF_LOGE("VendorInterface::SendPacket, hci_ is nullptr.");
195094332d3Sopenharmony_ci        return BT_VENDOR_INVALID_DATA_LEN;
196094332d3Sopenharmony_ci    }
197094332d3Sopenharmony_ci    return hci_->SendPacket(type, packet);
198094332d3Sopenharmony_ci}
199094332d3Sopenharmony_ci
200094332d3Sopenharmony_civoid VendorInterface::OnInitCallback(BtOpResultT result)
201094332d3Sopenharmony_ci{
202094332d3Sopenharmony_ci    HDF_LOGI("%{public}s, ", __func__);
203094332d3Sopenharmony_ci    if (VendorInterface::GetInstance()->initializeCompleteCallback_) {
204094332d3Sopenharmony_ci        VendorInterface::GetInstance()->initializeCompleteCallback_(result == BTC_OP_RESULT_SUCCESS);
205094332d3Sopenharmony_ci        VendorInterface::GetInstance()->initializeCompleteCallback_ = nullptr;
206094332d3Sopenharmony_ci    }
207094332d3Sopenharmony_ci
208094332d3Sopenharmony_ci    uint32_t lpmTimer = 0;
209094332d3Sopenharmony_ci    if (VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_GET_LPM_TIMER, &lpmTimer) != 0) {
210094332d3Sopenharmony_ci        HDF_LOGE("Vector interface BT_OP_GET_LPM_TIMER failed");
211094332d3Sopenharmony_ci    }
212094332d3Sopenharmony_ci    VendorInterface::GetInstance()->lpmTimer_ = lpmTimer;
213094332d3Sopenharmony_ci
214094332d3Sopenharmony_ci    VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_LPM_ENABLE, nullptr);
215094332d3Sopenharmony_ci
216094332d3Sopenharmony_ci    VendorInterface::GetInstance()->watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer),
217094332d3Sopenharmony_ci        std::bind(&VendorInterface::WatcherTimeout, VendorInterface::GetInstance()));
218094332d3Sopenharmony_ci}
219094332d3Sopenharmony_ci
220094332d3Sopenharmony_civoid *VendorInterface::OnMallocCallback(int size)
221094332d3Sopenharmony_ci{
222094332d3Sopenharmony_ci    static int MAX_BUFFER_SIZE = 1024;
223094332d3Sopenharmony_ci    if (size <= 0 || size > MAX_BUFFER_SIZE) {
224094332d3Sopenharmony_ci        HDF_LOGE("%{public}s, size is invalid", __func__);
225094332d3Sopenharmony_ci        return nullptr;
226094332d3Sopenharmony_ci    }
227094332d3Sopenharmony_ci    return malloc(size);
228094332d3Sopenharmony_ci}
229094332d3Sopenharmony_ci
230094332d3Sopenharmony_civoid VendorInterface::OnFreeCallback(void *buf)
231094332d3Sopenharmony_ci{
232094332d3Sopenharmony_ci    if (buf != nullptr) {
233094332d3Sopenharmony_ci        free(buf);
234094332d3Sopenharmony_ci    }
235094332d3Sopenharmony_ci}
236094332d3Sopenharmony_ci
237094332d3Sopenharmony_cisize_t VendorInterface::OnCmdXmitCallback(uint16_t opcode, void *buf)
238094332d3Sopenharmony_ci{
239094332d3Sopenharmony_ci    HC_BT_HDR *hdr = reinterpret_cast<HC_BT_HDR *>(buf);
240094332d3Sopenharmony_ci
241094332d3Sopenharmony_ci    VendorInterface::GetInstance()->vendorSentOpcode_ = opcode;
242094332d3Sopenharmony_ci
243094332d3Sopenharmony_ci    return VendorInterface::GetInstance()->SendPacket(
244094332d3Sopenharmony_ci        Hci::HCI_PACKET_TYPE_COMMAND, std::vector<uint8_t>(hdr->data, hdr->data + hdr->len));
245094332d3Sopenharmony_ci}
246094332d3Sopenharmony_ci
247094332d3Sopenharmony_civoid VendorInterface::OnEventReceived(const std::vector<uint8_t> &data)
248094332d3Sopenharmony_ci{
249094332d3Sopenharmony_ci    if (data[0] == Hci::HCI_EVENT_CODE_VENDOR_SPECIFIC) {
250094332d3Sopenharmony_ci        size_t buffSize = sizeof(HC_BT_HDR) + data.size();
251094332d3Sopenharmony_ci        HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
252094332d3Sopenharmony_ci        buff->event = data[0];
253094332d3Sopenharmony_ci        buff->len = data.size();
254094332d3Sopenharmony_ci        buff->offset = 0;
255094332d3Sopenharmony_ci        buff->layer_specific = 0;
256094332d3Sopenharmony_ci        (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
257094332d3Sopenharmony_ci        if (vendorInterface_ && vendorInterface_->op) {
258094332d3Sopenharmony_ci            vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
259094332d3Sopenharmony_ci        }
260094332d3Sopenharmony_ci        delete[] buff;
261094332d3Sopenharmony_ci    } else if (vendorSentOpcode_ != 0 && data[0] == Hci::HCI_EVENT_CODE_COMMAND_COMPLETE) {
262094332d3Sopenharmony_ci        uint8_t opcodeOffset = hci_->GetPacketHeaderInfo(Hci::HCI_PACKET_TYPE_EVENT).headerSize + 1;
263094332d3Sopenharmony_ci        uint16_t opcode = data[opcodeOffset] + (data[opcodeOffset + 1] << 0x08);
264094332d3Sopenharmony_ci        if (opcode == vendorSentOpcode_) {
265094332d3Sopenharmony_ci            size_t buffSize = sizeof(HC_BT_HDR) + data.size();
266094332d3Sopenharmony_ci            HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
267094332d3Sopenharmony_ci            buff->event = data[0];
268094332d3Sopenharmony_ci            buff->len = data.size();
269094332d3Sopenharmony_ci            buff->offset = 0;
270094332d3Sopenharmony_ci            buff->layer_specific = 0;
271094332d3Sopenharmony_ci            (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
272094332d3Sopenharmony_ci            vendorSentOpcode_ = 0;
273094332d3Sopenharmony_ci            if (vendorInterface_ && vendorInterface_->op) {
274094332d3Sopenharmony_ci                vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
275094332d3Sopenharmony_ci            }
276094332d3Sopenharmony_ci            delete[] buff;
277094332d3Sopenharmony_ci        }
278094332d3Sopenharmony_ci    }
279094332d3Sopenharmony_ci
280094332d3Sopenharmony_ci    eventDataCallback_(data);
281094332d3Sopenharmony_ci}
282094332d3Sopenharmony_ci
283094332d3Sopenharmony_civoid VendorInterface::WatcherTimeout()
284094332d3Sopenharmony_ci{
285094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lock(wakeupMutex_);
286094332d3Sopenharmony_ci    if (!activity_ && wakeupLock_ && vendorInterface_ && vendorInterface_->op) {
287094332d3Sopenharmony_ci        vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_UNLOCK, nullptr);
288094332d3Sopenharmony_ci        wakeupLock_ = false;
289094332d3Sopenharmony_ci    }
290094332d3Sopenharmony_ci    activity_ = false;
291094332d3Sopenharmony_ci}
292094332d3Sopenharmony_ci}  // namespace V1_0
293094332d3Sopenharmony_ci}  // namespace Hci
294094332d3Sopenharmony_ci}  // namespace Bluetooth
295094332d3Sopenharmony_ci}  // namespace HDI
296094332d3Sopenharmony_ci}  // namespace OHOS