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 
35 namespace OHOS {
36 namespace HDI {
37 namespace Bluetooth {
38 namespace Hci {
39 namespace V1_0 {
40 constexpr size_t BT_VENDOR_INVALID_DATA_LEN = 0;
41 BtVendorCallbacksT VendorInterface::vendorCallbacks_ = {
42     .size = sizeof(BtVendorCallbacksT),
43     .initCb = VendorInterface::OnInitCallback,
44     .alloc = VendorInterface::OnMallocCallback,
45     .dealloc = VendorInterface::OnFreeCallback,
46     .xmitCb = VendorInterface::OnCmdXmitCallback,
47 };
48 
VendorInterface()49 VendorInterface::VendorInterface()
50 {}
51 
~VendorInterface()52 VendorInterface::~VendorInterface()
53 {
54     CleanUp();
55 }
56 
WatchHciChannel(const ReceiveCallback &receiveCallback)57 bool 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 
Initialize( InitializeCompleteCallback initializeCompleteCallback, const ReceiveCallback &receiveCallback)90 bool 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 
CleanUp()153 void 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 
SendPacket(Hci::HciPacketType type, const std::vector<uint8_t> &packet)176 size_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 
OnInitCallback(BtOpResultT result)200 void 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 
OnMallocCallback(int size)220 void *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 
OnFreeCallback(void *buf)230 void VendorInterface::OnFreeCallback(void *buf)
231 {
232     if (buf != nullptr) {
233         free(buf);
234     }
235 }
236 
OnCmdXmitCallback(uint16_t opcode, void *buf)237 size_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 
OnEventReceived(const std::vector<uint8_t> &data)247 void 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 
WatcherTimeout()283 void 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