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