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