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 #include <sys/types.h>
25 #include <syscall.h>
26 #include <unistd.h>
27
28 #include "bluetooth_address.h"
29 #include "bt_hal_constant.h"
30 #include "h4_protocol.h"
31 #include "mct_protocol.h"
32
33 #ifdef LOG_DOMAIN
34 #undef LOG_DOMAIN
35 #endif
36 #define LOG_DOMAIN 0xD000105
37
38 namespace OHOS {
39 namespace HDI {
40 namespace Bluetooth {
41 namespace Hci {
42 namespace V1_0 {
43 constexpr size_t BT_VENDOR_INVALID_DATA_LEN = 0;
44 constexpr int32_t RT_PRIORITY = 1;
45 BtVendorCallbacksT VendorInterface::vendorCallbacks_ = {
46 .size = sizeof(BtVendorCallbacksT),
47 .initCb = VendorInterface::OnInitCallback,
48 .alloc = VendorInterface::OnMallocCallback,
49 .dealloc = VendorInterface::OnFreeCallback,
50 .xmitCb = VendorInterface::OnCmdXmitCallback,
51 };
52
VendorInterface()53 VendorInterface::VendorInterface()
54 {}
55
~VendorInterface()56 VendorInterface::~VendorInterface()
57 {
58 CleanUp();
59 }
60
WatchHciChannel(const ReceiveCallback & receiveCallback)61 bool VendorInterface::WatchHciChannel(const ReceiveCallback &receiveCallback)
62 {
63 pid_t tid = gettid();
64 struct sched_param setParams = {.sched_priority = RT_PRIORITY};
65 int rc = sched_setscheduler(tid, SCHED_FIFO, &setParams);
66 if (rc != 0) {
67 HDF_LOGI("vendorInterface setscheduler failed rc:%{public}d.", rc);
68 }
69 HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN begin");
70 int channel[HCI_MAX_CHANNEL] = {0};
71 int channelCount = vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_OPEN, channel);
72 if (channelCount < 1 || channelCount > HCI_MAX_CHANNEL) {
73 HDF_LOGE("vendorInterface_->op BT_OP_HCI_CHANNEL_OPEN failed ret:%{public}d.", channelCount);
74 return false;
75 }
76 HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN end");
77
78 if (channelCount == 1) {
79 auto h4 = std::make_shared<Hci::H4Protocol>(channel[0],
80 receiveCallback.onAclReceive,
81 receiveCallback.onScoReceive,
82 std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1),
83 receiveCallback.onIsoReceive);
84 watcher_->AddFdToWatcher(channel[0], std::bind(&Hci::H4Protocol::ReadData, h4, std::placeholders::_1));
85 hci_ = h4;
86 } else {
87 auto mct = std::make_shared<Hci::MctProtocol>(channel,
88 receiveCallback.onAclReceive,
89 receiveCallback.onScoReceive,
90 std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1));
91 watcher_->AddFdToWatcher(
92 channel[hci_channels_t::HCI_ACL_IN], std::bind(&Hci::MctProtocol::ReadAclData, mct, std::placeholders::_1));
93 watcher_->AddFdToWatcher(
94 channel[hci_channels_t::HCI_EVT], std::bind(&Hci::MctProtocol::ReadEventData, mct, std::placeholders::_1));
95 hci_ = mct;
96 }
97
98 return true;
99 }
100
Initialize(InitializeCompleteCallback initializeCompleteCallback,const ReceiveCallback & receiveCallback)101 bool VendorInterface::Initialize(
102 InitializeCompleteCallback initializeCompleteCallback, const ReceiveCallback &receiveCallback)
103 {
104 HDF_LOGI("VendorInterface %{public}s, ", __func__);
105 std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
106 initializeCompleteCallback_ = initializeCompleteCallback;
107 eventDataCallback_ = receiveCallback.onEventReceive;
108
109 HDF_LOGI("VendorInterface dlopen");
110 vendorHandle_ = dlopen(BT_VENDOR_NAME, RTLD_NOW);
111 if (vendorHandle_ == nullptr) {
112 HDF_LOGE("VendorInterface dlopen %{public}s failed, error code: %{public}s", BT_VENDOR_NAME, dlerror());
113 return false;
114 }
115
116 vendorInterface_ =
117 reinterpret_cast<BtVendorInterfaceT *>(dlsym(vendorHandle_, BT_VENDOR_INTERFACE_SYMBOL_NAME));
118
119 auto bluetoothAddress = BluetoothAddress::GetDeviceAddress();
120 std::vector<uint8_t> address = { 0, 0, 0, 0, 0, 0 };
121 if (bluetoothAddress != nullptr) {
122 bluetoothAddress->ReadAddress(address);
123 }
124
125 if (vendorInterface_ == nullptr) {
126 HDF_LOGE("VendorInterface dlsym %{public}s failed.", BT_VENDOR_INTERFACE_SYMBOL_NAME);
127 return false;
128 }
129
130 HDF_LOGI("VendorInterface init");
131 int result = vendorInterface_->init(&vendorCallbacks_, address.data());
132 if (result != 0) {
133 HDF_LOGE("vendorInterface_->init failed.");
134 return false;
135 }
136
137 result = vendorInterface_->op(BtOpcodeT::BT_OP_POWER_ON, nullptr);
138 if (result != 0) {
139 HDF_LOGE("vendorInterface_->op BT_OP_POWER_ON failed.");
140 return false;
141 }
142
143 watcher_ = std::make_shared<HciWatcher>();
144
145 if (!WatchHciChannel(receiveCallback)) {
146 return false;
147 }
148
149 if (!watcher_->Start()) {
150 HDF_LOGE("watcher start failed.");
151 return false;
152 }
153
154 if (vendorInterface_ == nullptr) {
155 HDF_LOGE("vendorInterface_ is nullptr");
156 return false;
157 }
158
159 HDF_LOGI("VendorInterface BT_OP_INIT");
160 vendorInterface_->op(BtOpcodeT::BT_OP_INIT, nullptr);
161
162 HDF_LOGI("VendorInterface Initialize end");
163 return true;
164 }
165
CleanUp()166 void VendorInterface::CleanUp()
167 {
168 std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
169 HDF_LOGE("vendorInterface clean up.");
170 if (vendorInterface_ == nullptr) {
171 HDF_LOGE("VendorInterface::CleanUp, vendorInterface_ is nullptr.");
172 return;
173 }
174 if (watcher_ != nullptr) {
175 watcher_->Stop();
176 }
177 vendorInterface_->op(BtOpcodeT::BT_OP_LPM_DISABLE, nullptr);
178 vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_CLOSE, nullptr);
179 vendorInterface_->op(BtOpcodeT::BT_OP_POWER_OFF, nullptr);
180 vendorInterface_->close();
181
182 hci_ = nullptr;
183 vendorInterface_ = nullptr;
184 initializeCompleteCallback_ = nullptr;
185 eventDataCallback_ = nullptr;
186 dlclose(vendorHandle_);
187 vendorHandle_ = nullptr;
188 watcher_ = nullptr;
189 vendorSentOpcode_ = 0;
190 lpmTimer_ = 0;
191 wakeupLock_ = false;
192 activity_ = false;
193 }
194
SendPacket(Hci::HciPacketType type,const std::vector<uint8_t> & packet)195 size_t VendorInterface::SendPacket(Hci::HciPacketType type, const std::vector<uint8_t> &packet)
196 {
197 if (vendorInterface_ == nullptr) {
198 HDF_LOGE("VendorInterface::SendPacket, vendorInterface_ is nullptr.");
199 return BT_VENDOR_INVALID_DATA_LEN;
200 }
201
202 {
203 std::lock_guard<std::mutex> lock(wakeupMutex_);
204 activity_ = true;
205 if (watcher_ != nullptr) {
206 watcher_->SetTimeout(
207 std::chrono::milliseconds(lpmTimer_), std::bind(&VendorInterface::WatcherTimeout, this));
208 }
209 if (!wakeupLock_) {
210 vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_LOCK, nullptr);
211 wakeupLock_ = true;
212 }
213 }
214
215 if (hci_ == nullptr) {
216 HDF_LOGE("VendorInterface::SendPacket, hci_ is nullptr.");
217 return BT_VENDOR_INVALID_DATA_LEN;
218 }
219 return hci_->SendPacket(type, packet);
220 }
221
OnInitCallback(BtOpResultT result)222 void VendorInterface::OnInitCallback(BtOpResultT result)
223 {
224 HDF_LOGI("%{public}s, ", __func__);
225 if (VendorInterface::GetInstance()->initializeCompleteCallback_) {
226 VendorInterface::GetInstance()->initializeCompleteCallback_(result == BTC_OP_RESULT_SUCCESS);
227 VendorInterface::GetInstance()->initializeCompleteCallback_ = nullptr;
228 }
229
230 uint32_t lpmTimer = 0;
231 if (VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_GET_LPM_TIMER, &lpmTimer) != 0) {
232 HDF_LOGE("Vector interface BT_OP_GET_LPM_TIMER failed");
233 }
234 VendorInterface::GetInstance()->lpmTimer_ = lpmTimer;
235
236 VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_LPM_ENABLE, nullptr);
237 if (VendorInterface::GetInstance()->watcher_ != nullptr) {
238 VendorInterface::GetInstance()->watcher_->SetTimeout(std::chrono::milliseconds(lpmTimer),
239 std::bind(&VendorInterface::WatcherTimeout, VendorInterface::GetInstance()));
240 }
241 }
242
OnMallocCallback(int size)243 void *VendorInterface::OnMallocCallback(int size)
244 {
245 static int MAX_BUFFER_SIZE = 1024;
246 if (size <= 0 || size > MAX_BUFFER_SIZE) {
247 HDF_LOGE("%{public}s, size is invalid", __func__);
248 return nullptr;
249 }
250 return malloc(size);
251 }
252
OnFreeCallback(void * buf)253 void VendorInterface::OnFreeCallback(void *buf)
254 {
255 if (buf != nullptr) {
256 free(buf);
257 }
258 }
259
OnCmdXmitCallback(uint16_t opcode,void * buf)260 size_t VendorInterface::OnCmdXmitCallback(uint16_t opcode, void *buf)
261 {
262 HC_BT_HDR *hdr = reinterpret_cast<HC_BT_HDR *>(buf);
263
264 VendorInterface::GetInstance()->vendorSentOpcode_ = opcode;
265
266 return VendorInterface::GetInstance()->SendPacket(
267 Hci::HCI_PACKET_TYPE_COMMAND, std::vector<uint8_t>(hdr->data, hdr->data + hdr->len));
268 }
269
OnEventReceived(const std::vector<uint8_t> & data)270 void VendorInterface::OnEventReceived(const std::vector<uint8_t> &data)
271 {
272 if (data[0] == Hci::HCI_EVENT_CODE_VENDOR_SPECIFIC) {
273 size_t buffSize = sizeof(HC_BT_HDR) + data.size();
274 HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
275 buff->event = data[0];
276 buff->len = data.size();
277 buff->offset = 0;
278 buff->layer_specific = 0;
279 (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
280 if (vendorInterface_ && vendorInterface_->op) {
281 vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
282 }
283 delete[] buff;
284 } else if (vendorSentOpcode_ != 0 && data[0] == Hci::HCI_EVENT_CODE_COMMAND_COMPLETE) {
285 uint8_t opcodeOffset = hci_->GetPacketHeaderInfo(Hci::HCI_PACKET_TYPE_EVENT).headerSize + 1;
286 uint16_t opcode = data[opcodeOffset] + (data[opcodeOffset + 1] << 0x08);
287 if (opcode == vendorSentOpcode_) {
288 size_t buffSize = sizeof(HC_BT_HDR) + data.size();
289 HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
290 buff->event = data[0];
291 buff->len = data.size();
292 buff->offset = 0;
293 buff->layer_specific = 0;
294 (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
295 vendorSentOpcode_ = 0;
296 if (vendorInterface_ && vendorInterface_->op) {
297 vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
298 }
299 delete[] buff;
300 }
301 }
302
303 eventDataCallback_(data);
304 }
305
WatcherTimeout()306 void VendorInterface::WatcherTimeout()
307 {
308 std::lock_guard<std::mutex> lock(wakeupMutex_);
309 if (!activity_ && wakeupLock_ && vendorInterface_ && vendorInterface_->op) {
310 vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_UNLOCK, nullptr);
311 wakeupLock_ = false;
312 }
313 activity_ = false;
314 }
315 } // namespace V1_0
316 } // namespace Hci
317 } // namespace Bluetooth
318 } // namespace HDI
319 } // namespace OHOS