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 int channel[HCI_MAX_CHANNEL] = {0};
60 int channelCount = vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_OPEN, channel);
61 if (channelCount < 1 || channelCount > HCI_MAX_CHANNEL) {
62 HDF_LOGE("vendorInterface_->op BT_OP_HCI_CHANNEL_OPEN failed ret:%d.", channelCount);
63 return false;
64 }
65
66 if (channelCount == 1) {
67 auto h4 = std::make_shared<Hci::H4Protocol>(channel[0],
68 receiveCallback.onAclReceive,
69 receiveCallback.onScoReceive,
70 std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1));
71 watcher_.AddFdToWatcher(channel[0], std::bind(&Hci::H4Protocol::ReadData, h4, std::placeholders::_1));
72 hci_ = h4;
73 } else {
74 auto mct = std::make_shared<Hci::MctProtocol>(channel,
75 receiveCallback.onAclReceive,
76 receiveCallback.onScoReceive,
77 std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1));
78 watcher_.AddFdToWatcher(
79 channel[hci_channels_t::HCI_ACL_IN], std::bind(&Hci::MctProtocol::ReadAclData, mct, std::placeholders::_1));
80 watcher_.AddFdToWatcher(
81 channel[hci_channels_t::HCI_EVT], std::bind(&Hci::MctProtocol::ReadEventData, mct, std::placeholders::_1));
82 hci_ = mct;
83 }
84
85 return true;
86 }
87
Initialize(InitializeCompleteCallback initializeCompleteCallback,const ReceiveCallback & receiveCallback)88 bool VendorInterface::Initialize(
89 InitializeCompleteCallback initializeCompleteCallback, const ReceiveCallback &receiveCallback)
90 {
91 HDF_LOGI("VendorInterface %{public}s, ", __func__);
92 std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
93 initializeCompleteCallback_ = initializeCompleteCallback;
94 eventDataCallback_ = receiveCallback.onEventReceive;
95
96 vendorHandle_ = dlopen(BT_VENDOR_NAME, RTLD_NOW);
97 if (vendorHandle_ == nullptr) {
98 HDF_LOGE("VendorInterface dlopen %{public}s failed, error code: %{public}s", BT_VENDOR_NAME, dlerror());
99 return false;
100 }
101
102 vendorInterface_ =
103 reinterpret_cast<BtVendorInterfaceT *>(dlsym(vendorHandle_, BT_VENDOR_INTERFACE_SYMBOL_NAME));
104
105 auto bluetoothAddress = BluetoothAddress::GetDeviceAddress();
106 std::vector<uint8_t> address = { 0, 0, 0, 0, 0, 0 };
107 if (bluetoothAddress != nullptr) {
108 bluetoothAddress->ReadAddress(address);
109 }
110
111 if (vendorInterface_ == nullptr) {
112 HDF_LOGE("VendorInterface dlsym %{public}s failed.", BT_VENDOR_INTERFACE_SYMBOL_NAME);
113 return false;
114 }
115 int result = vendorInterface_->init(&vendorCallbacks_, address.data());
116 if (result != 0) {
117 HDF_LOGE("vendorInterface_->init failed.");
118 return false;
119 }
120
121 result = vendorInterface_->op(BtOpcodeT::BT_OP_POWER_ON, nullptr);
122 if (result != 0) {
123 HDF_LOGE("vendorInterface_->op BT_OP_POWER_ON failed.");
124 return false;
125 }
126
127 if (!WatchHciChannel(receiveCallback)) {
128 return false;
129 }
130
131 if (!watcher_.Start()) {
132 HDF_LOGE("watcher start failed.");
133 return false;
134 }
135
136 if (vendorInterface_ == nullptr) {
137 HDF_LOGE("vendorInterface_ is nullptr");
138 return false;
139 }
140 vendorInterface_->op(BtOpcodeT::BT_OP_INIT, nullptr);
141
142 return true;
143 }
144
CleanUp()145 void VendorInterface::CleanUp()
146 {
147 std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_);
148 HDF_LOGE("vendorInterface clean up.");
149 if (vendorInterface_ == nullptr) {
150 HDF_LOGE("VendorInterface::CleanUp, vendorInterface_ is nullptr.");
151 return;
152 }
153
154 watcher_.Stop();
155
156 vendorInterface_->op(BtOpcodeT::BT_OP_LPM_DISABLE, nullptr);
157 vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_CLOSE, nullptr);
158 vendorInterface_->op(BtOpcodeT::BT_OP_POWER_OFF, nullptr);
159 vendorInterface_->close();
160
161 hci_ = nullptr;
162 vendorInterface_ = nullptr;
163 initializeCompleteCallback_ = nullptr;
164 eventDataCallback_ = nullptr;
165 dlclose(vendorHandle_);
166 }
167
SendPacket(Hci::HciPacketType type,const std::vector<uint8_t> & packet)168 size_t VendorInterface::SendPacket(Hci::HciPacketType type, const std::vector<uint8_t> &packet)
169 {
170 if (vendorInterface_ == nullptr) {
171 HDF_LOGE("VendorInterface::SendPacket, vendorInterface_ is nullptr.");
172 return BT_VENDOR_INVALID_DATA_LEN;
173 }
174
175 {
176 std::lock_guard<std::mutex> lock(wakeupMutex_);
177 activity_ = true;
178 watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer_), std::bind(&VendorInterface::WatcherTimeout, this));
179 if (!wakeupLock_) {
180 vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_LOCK, nullptr);
181 wakeupLock_ = true;
182 }
183 }
184
185 if (hci_ == nullptr) {
186 HDF_LOGE("VendorInterface::SendPacket, hci_ is nullptr.");
187 return BT_VENDOR_INVALID_DATA_LEN;
188 }
189 return hci_->SendPacket(type, packet);
190 }
191
OnInitCallback(BtOpResultT result)192 void VendorInterface::OnInitCallback(BtOpResultT result)
193 {
194 HDF_LOGI("%{public}s, ", __func__);
195 if (VendorInterface::GetInstance()->initializeCompleteCallback_) {
196 VendorInterface::GetInstance()->initializeCompleteCallback_(result == BTC_OP_RESULT_SUCCESS);
197 VendorInterface::GetInstance()->initializeCompleteCallback_ = nullptr;
198 }
199
200 uint32_t lpmTimer = 0;
201 if (VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_GET_LPM_TIMER, &lpmTimer) != 0) {
202 HDF_LOGE("Vector interface BT_OP_GET_LPM_TIMER failed");
203 }
204 VendorInterface::GetInstance()->lpmTimer_ = lpmTimer;
205
206 VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_LPM_ENABLE, nullptr);
207
208 VendorInterface::GetInstance()->watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer),
209 std::bind(&VendorInterface::WatcherTimeout, VendorInterface::GetInstance()));
210 }
211
OnMallocCallback(int size)212 void *VendorInterface::OnMallocCallback(int size)
213 {
214 static int MAX_BUFFER_SIZE = 1024;
215 if (size <= 0 || size > MAX_BUFFER_SIZE) {
216 HDF_LOGE("%{public}s, size is invalid", __func__);
217 return nullptr;
218 }
219 return malloc(size);
220 }
221
OnFreeCallback(void * buf)222 void VendorInterface::OnFreeCallback(void *buf)
223 {
224 if (buf != nullptr) {
225 free(buf);
226 }
227 }
228
OnCmdXmitCallback(uint16_t opcode,void * buf)229 size_t VendorInterface::OnCmdXmitCallback(uint16_t opcode, void *buf)
230 {
231 HC_BT_HDR *hdr = reinterpret_cast<HC_BT_HDR *>(buf);
232
233 VendorInterface::GetInstance()->vendorSentOpcode_ = opcode;
234
235 return VendorInterface::GetInstance()->SendPacket(
236 Hci::HCI_PACKET_TYPE_COMMAND, std::vector<uint8_t>(hdr->data, hdr->data + hdr->len));
237 }
238
OnEventReceived(const std::vector<uint8_t> & data)239 void VendorInterface::OnEventReceived(const std::vector<uint8_t> &data)
240 {
241 if (data[0] == Hci::HCI_EVENT_CODE_VENDOR_SPECIFIC) {
242 size_t buffSize = sizeof(HC_BT_HDR) + data.size();
243 HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
244 buff->event = data[0];
245 buff->len = data.size();
246 buff->offset = 0;
247 buff->layer_specific = 0;
248 (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
249 if (vendorInterface_ && vendorInterface_->op) {
250 vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
251 }
252 delete[] buff;
253 } else if (vendorSentOpcode_ != 0 && data[0] == Hci::HCI_EVENT_CODE_COMMAND_COMPLETE) {
254 uint8_t opcodeOffset = hci_->GetPacketHeaderInfo(Hci::HCI_PACKET_TYPE_EVENT).headerSize + 1;
255 uint16_t opcode = data[opcodeOffset] + (data[opcodeOffset + 1] << 0x08);
256 if (opcode == vendorSentOpcode_) {
257 size_t buffSize = sizeof(HC_BT_HDR) + data.size();
258 HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]);
259 buff->event = data[0];
260 buff->len = data.size();
261 buff->offset = 0;
262 buff->layer_specific = 0;
263 (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size());
264 vendorSentOpcode_ = 0;
265 if (vendorInterface_ && vendorInterface_->op) {
266 vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff);
267 }
268 delete[] buff;
269 }
270 }
271
272 eventDataCallback_(data);
273 }
274
WatcherTimeout()275 void VendorInterface::WatcherTimeout()
276 {
277 std::lock_guard<std::mutex> lock(wakeupMutex_);
278 if (!activity_ && wakeupLock_ && vendorInterface_ && vendorInterface_->op) {
279 vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_UNLOCK, nullptr);
280 wakeupLock_ = false;
281 }
282 activity_ = false;
283 }
284 } // namespace V1_0
285 } // namespace Hci
286 } // namespace Bluetooth
287 } // namespace HDI
288 } // namespace OHOS