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