1/*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "vendor_interface.h"
17
18#include <thread>
19
20#include <dlfcn.h>
21
22#include <hdf_log.h>
23#include <securec.h>
24
25#include "bluetooth_address.h"
26#include "bt_hal_constant.h"
27#include "h4_protocol.h"
28#include "mct_protocol.h"
29
30#ifdef LOG_DOMAIN
31#undef LOG_DOMAIN
32#endif
33#define LOG_DOMAIN 0xD000105
34
35namespace OHOS {
36namespace HDI {
37namespace Bluetooth {
38namespace Hci {
39namespace V1_0 {
40constexpr size_t BT_VENDOR_INVALID_DATA_LEN = 0;
41BtVendorCallbacksT VendorInterface::vendorCallbacks_ = {
42    .size = sizeof(BtVendorCallbacksT),
43    .initCb = VendorInterface::OnInitCallback,
44    .alloc = VendorInterface::OnMallocCallback,
45    .dealloc = VendorInterface::OnFreeCallback,
46    .xmitCb = VendorInterface::OnCmdXmitCallback,
47};
48
49VendorInterface::VendorInterface()
50{}
51
52VendorInterface::~VendorInterface()
53{
54    CleanUp();
55}
56
57bool VendorInterface::WatchHciChannel(const ReceiveCallback &receiveCallback)
58{
59    HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN begin");
60    int channel[HCI_MAX_CHANNEL] = {0};
61    int channelCount = vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_OPEN, channel);
62    if (channelCount < 1 || channelCount > HCI_MAX_CHANNEL) {
63        HDF_LOGE("vendorInterface_->op BT_OP_HCI_CHANNEL_OPEN failed ret:%d.", channelCount);
64        return false;
65    }
66    HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN end");
67
68    if (channelCount == 1) {
69        auto h4 = std::make_shared<Hci::H4Protocol>(channel[0],
70            receiveCallback.onAclReceive,
71            receiveCallback.onScoReceive,
72            std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1));
73        watcher_.AddFdToWatcher(channel[0], std::bind(&Hci::H4Protocol::ReadData, h4, std::placeholders::_1));
74        hci_ = h4;
75    } else {
76        auto mct = std::make_shared<Hci::MctProtocol>(channel,
77            receiveCallback.onAclReceive,
78            receiveCallback.onScoReceive,
79            std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1));
80        watcher_.AddFdToWatcher(
81            channel[hci_channels_t::HCI_ACL_IN], std::bind(&Hci::MctProtocol::ReadAclData, mct, std::placeholders::_1));
82        watcher_.AddFdToWatcher(
83            channel[hci_channels_t::HCI_EVT], std::bind(&Hci::MctProtocol::ReadEventData, mct, std::placeholders::_1));
84        hci_ = mct;
85    }
86
87    return true;
88}
89
90bool VendorInterface::Initialize(
91    InitializeCompleteCallback initializeCompleteCallback, const ReceiveCallback &receiveCallback)
92{
93    HDF_LOGI("VendorInterface %{public}s, ", __func__);
94    std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
95    initializeCompleteCallback_ = initializeCompleteCallback;
96    eventDataCallback_ = receiveCallback.onEventReceive;
97
98    HDF_LOGI("VendorInterface dlopen");
99    vendorHandle_ = dlopen(BT_VENDOR_NAME, RTLD_NOW);
100    if (vendorHandle_ == nullptr) {
101        HDF_LOGE("VendorInterface dlopen %{public}s failed, error code: %{public}s", BT_VENDOR_NAME, dlerror());
102        return false;
103    }
104
105    vendorInterface_ =
106        reinterpret_cast<BtVendorInterfaceT *>(dlsym(vendorHandle_, BT_VENDOR_INTERFACE_SYMBOL_NAME));
107
108    auto bluetoothAddress = BluetoothAddress::GetDeviceAddress();
109    std::vector<uint8_t> address = { 0, 0, 0, 0, 0, 0 };
110    if (bluetoothAddress != nullptr) {
111        bluetoothAddress->ReadAddress(address);
112    }
113
114    if (vendorInterface_ == nullptr) {
115        HDF_LOGE("VendorInterface dlsym %{public}s failed.", BT_VENDOR_INTERFACE_SYMBOL_NAME);
116        return false;
117    }
118
119    HDF_LOGI("VendorInterface init");
120    int result = vendorInterface_->init(&vendorCallbacks_, address.data());
121    if (result != 0) {
122        HDF_LOGE("vendorInterface_->init failed.");
123        return false;
124    }
125
126    result = vendorInterface_->op(BtOpcodeT::BT_OP_POWER_ON, nullptr);
127    if (result != 0) {
128        HDF_LOGE("vendorInterface_->op BT_OP_POWER_ON failed.");
129        return false;
130    }
131
132    if (!WatchHciChannel(receiveCallback)) {
133        return false;
134    }
135
136    if (!watcher_.Start()) {
137        HDF_LOGE("watcher start failed.");
138        return false;
139    }
140
141    if (vendorInterface_ == nullptr) {
142        HDF_LOGE("vendorInterface_ is nullptr");
143        return false;
144    }
145
146    HDF_LOGI("VendorInterface BT_OP_INIT");
147    vendorInterface_->op(BtOpcodeT::BT_OP_INIT, nullptr);
148
149    HDF_LOGI("VendorInterface Initialize end");
150    return true;
151}
152
153void VendorInterface::CleanUp()
154{
155    std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
156    HDF_LOGE("vendorInterface clean up.");
157    if (vendorInterface_ == nullptr) {
158        HDF_LOGE("VendorInterface::CleanUp, vendorInterface_ is nullptr.");
159        return;
160    }
161
162    watcher_.Stop();
163
164    vendorInterface_->op(BtOpcodeT::BT_OP_LPM_DISABLE, nullptr);
165    vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_CLOSE, nullptr);
166    vendorInterface_->op(BtOpcodeT::BT_OP_POWER_OFF, nullptr);
167    vendorInterface_->close();
168
169    hci_ = nullptr;
170    vendorInterface_ = nullptr;
171    initializeCompleteCallback_ = nullptr;
172    eventDataCallback_ = nullptr;
173    dlclose(vendorHandle_);
174}
175
176size_t VendorInterface::SendPacket(Hci::HciPacketType type, const std::vector<uint8_t> &packet)
177{
178    if (vendorInterface_ == nullptr) {
179        HDF_LOGE("VendorInterface::SendPacket, vendorInterface_ is nullptr.");
180        return BT_VENDOR_INVALID_DATA_LEN;
181    }
182
183    {
184        std::lock_guard<std::mutex> lock(wakeupMutex_);
185        activity_ = true;
186        watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer_), std::bind(&VendorInterface::WatcherTimeout, this));
187        if (!wakeupLock_) {
188            vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_LOCK, nullptr);
189            wakeupLock_ = true;
190        }
191    }
192
193    if (hci_ == nullptr) {
194        HDF_LOGE("VendorInterface::SendPacket, hci_ is nullptr.");
195        return BT_VENDOR_INVALID_DATA_LEN;
196    }
197    return hci_->SendPacket(type, packet);
198}
199
200void VendorInterface::OnInitCallback(BtOpResultT result)
201{
202    HDF_LOGI("%{public}s, ", __func__);
203    if (VendorInterface::GetInstance()->initializeCompleteCallback_) {
204        VendorInterface::GetInstance()->initializeCompleteCallback_(result == BTC_OP_RESULT_SUCCESS);
205        VendorInterface::GetInstance()->initializeCompleteCallback_ = nullptr;
206    }
207
208    uint32_t lpmTimer = 0;
209    if (VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_GET_LPM_TIMER, &lpmTimer) != 0) {
210        HDF_LOGE("Vector interface BT_OP_GET_LPM_TIMER failed");
211    }
212    VendorInterface::GetInstance()->lpmTimer_ = lpmTimer;
213
214    VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_LPM_ENABLE, nullptr);
215
216    VendorInterface::GetInstance()->watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer),
217        std::bind(&VendorInterface::WatcherTimeout, VendorInterface::GetInstance()));
218}
219
220void *VendorInterface::OnMallocCallback(int size)
221{
222    static int MAX_BUFFER_SIZE = 1024;
223    if (size <= 0 || size > MAX_BUFFER_SIZE) {
224        HDF_LOGE("%{public}s, size is invalid", __func__);
225        return nullptr;
226    }
227    return malloc(size);
228}
229
230void VendorInterface::OnFreeCallback(void *buf)
231{
232    if (buf != nullptr) {
233        free(buf);
234    }
235}
236
237size_t VendorInterface::OnCmdXmitCallback(uint16_t opcode, void *buf)
238{
239    HC_BT_HDR *hdr = reinterpret_cast<HC_BT_HDR *>(buf);
240
241    VendorInterface::GetInstance()->vendorSentOpcode_ = opcode;
242
243    return VendorInterface::GetInstance()->SendPacket(
244        Hci::HCI_PACKET_TYPE_COMMAND, std::vector<uint8_t>(hdr->data, hdr->data + hdr->len));
245}
246
247void VendorInterface::OnEventReceived(const std::vector<uint8_t> &data)
248{
249    if (data[0] == Hci::HCI_EVENT_CODE_VENDOR_SPECIFIC) {
250        size_t buffSize = sizeof(HC_BT_HDR) + data.size();
251        HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
252        buff->event = data[0];
253        buff->len = data.size();
254        buff->offset = 0;
255        buff->layer_specific = 0;
256        (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
257        if (vendorInterface_ && vendorInterface_->op) {
258            vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
259        }
260        delete[] buff;
261    } else if (vendorSentOpcode_ != 0 && data[0] == Hci::HCI_EVENT_CODE_COMMAND_COMPLETE) {
262        uint8_t opcodeOffset = hci_->GetPacketHeaderInfo(Hci::HCI_PACKET_TYPE_EVENT).headerSize + 1;
263        uint16_t opcode = data[opcodeOffset] + (data[opcodeOffset + 1] << 0x08);
264        if (opcode == vendorSentOpcode_) {
265            size_t buffSize = sizeof(HC_BT_HDR) + data.size();
266            HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
267            buff->event = data[0];
268            buff->len = data.size();
269            buff->offset = 0;
270            buff->layer_specific = 0;
271            (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
272            vendorSentOpcode_ = 0;
273            if (vendorInterface_ && vendorInterface_->op) {
274                vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
275            }
276            delete[] buff;
277        }
278    }
279
280    eventDataCallback_(data);
281}
282
283void VendorInterface::WatcherTimeout()
284{
285    std::lock_guard<std::mutex> lock(wakeupMutex_);
286    if (!activity_ && wakeupLock_ && vendorInterface_ && vendorInterface_->op) {
287        vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_UNLOCK, nullptr);
288        wakeupLock_ = false;
289    }
290    activity_ = false;
291}
292}  // namespace V1_0
293}  // namespace Hci
294}  // namespace Bluetooth
295}  // namespace HDI
296}  // namespace OHOS