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