1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "vendor_interface.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <thread> 19094332d3Sopenharmony_ci 20094332d3Sopenharmony_ci#include <dlfcn.h> 21094332d3Sopenharmony_ci 22094332d3Sopenharmony_ci#include <hdf_log.h> 23094332d3Sopenharmony_ci#include <securec.h> 24094332d3Sopenharmony_ci 25094332d3Sopenharmony_ci#include "bluetooth_address.h" 26094332d3Sopenharmony_ci#include "bt_hal_constant.h" 27094332d3Sopenharmony_ci#include "h4_protocol.h" 28094332d3Sopenharmony_ci#include "mct_protocol.h" 29094332d3Sopenharmony_ci 30094332d3Sopenharmony_ci#ifdef LOG_DOMAIN 31094332d3Sopenharmony_ci#undef LOG_DOMAIN 32094332d3Sopenharmony_ci#endif 33094332d3Sopenharmony_ci#define LOG_DOMAIN 0xD000105 34094332d3Sopenharmony_ci 35094332d3Sopenharmony_cinamespace OHOS { 36094332d3Sopenharmony_cinamespace HDI { 37094332d3Sopenharmony_cinamespace Bluetooth { 38094332d3Sopenharmony_cinamespace Hci { 39094332d3Sopenharmony_cinamespace V1_0 { 40094332d3Sopenharmony_ciconstexpr size_t BT_VENDOR_INVALID_DATA_LEN = 0; 41094332d3Sopenharmony_ciBtVendorCallbacksT VendorInterface::vendorCallbacks_ = { 42094332d3Sopenharmony_ci .size = sizeof(BtVendorCallbacksT), 43094332d3Sopenharmony_ci .initCb = VendorInterface::OnInitCallback, 44094332d3Sopenharmony_ci .alloc = VendorInterface::OnMallocCallback, 45094332d3Sopenharmony_ci .dealloc = VendorInterface::OnFreeCallback, 46094332d3Sopenharmony_ci .xmitCb = VendorInterface::OnCmdXmitCallback, 47094332d3Sopenharmony_ci}; 48094332d3Sopenharmony_ci 49094332d3Sopenharmony_ciVendorInterface::VendorInterface() 50094332d3Sopenharmony_ci{} 51094332d3Sopenharmony_ci 52094332d3Sopenharmony_ciVendorInterface::~VendorInterface() 53094332d3Sopenharmony_ci{ 54094332d3Sopenharmony_ci CleanUp(); 55094332d3Sopenharmony_ci} 56094332d3Sopenharmony_ci 57094332d3Sopenharmony_cibool VendorInterface::WatchHciChannel(const ReceiveCallback &receiveCallback) 58094332d3Sopenharmony_ci{ 59094332d3Sopenharmony_ci HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN begin"); 60094332d3Sopenharmony_ci int channel[HCI_MAX_CHANNEL] = {0}; 61094332d3Sopenharmony_ci int channelCount = vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_OPEN, channel); 62094332d3Sopenharmony_ci if (channelCount < 1 || channelCount > HCI_MAX_CHANNEL) { 63094332d3Sopenharmony_ci HDF_LOGE("vendorInterface_->op BT_OP_HCI_CHANNEL_OPEN failed ret:%d.", channelCount); 64094332d3Sopenharmony_ci return false; 65094332d3Sopenharmony_ci } 66094332d3Sopenharmony_ci HDF_LOGI("VendorInterface BT_OP_HCI_CHANNEL_OPEN end"); 67094332d3Sopenharmony_ci 68094332d3Sopenharmony_ci if (channelCount == 1) { 69094332d3Sopenharmony_ci auto h4 = std::make_shared<Hci::H4Protocol>(channel[0], 70094332d3Sopenharmony_ci receiveCallback.onAclReceive, 71094332d3Sopenharmony_ci receiveCallback.onScoReceive, 72094332d3Sopenharmony_ci std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1)); 73094332d3Sopenharmony_ci watcher_.AddFdToWatcher(channel[0], std::bind(&Hci::H4Protocol::ReadData, h4, std::placeholders::_1)); 74094332d3Sopenharmony_ci hci_ = h4; 75094332d3Sopenharmony_ci } else { 76094332d3Sopenharmony_ci auto mct = std::make_shared<Hci::MctProtocol>(channel, 77094332d3Sopenharmony_ci receiveCallback.onAclReceive, 78094332d3Sopenharmony_ci receiveCallback.onScoReceive, 79094332d3Sopenharmony_ci std::bind(&VendorInterface::OnEventReceived, this, std::placeholders::_1)); 80094332d3Sopenharmony_ci watcher_.AddFdToWatcher( 81094332d3Sopenharmony_ci channel[hci_channels_t::HCI_ACL_IN], std::bind(&Hci::MctProtocol::ReadAclData, mct, std::placeholders::_1)); 82094332d3Sopenharmony_ci watcher_.AddFdToWatcher( 83094332d3Sopenharmony_ci channel[hci_channels_t::HCI_EVT], std::bind(&Hci::MctProtocol::ReadEventData, mct, std::placeholders::_1)); 84094332d3Sopenharmony_ci hci_ = mct; 85094332d3Sopenharmony_ci } 86094332d3Sopenharmony_ci 87094332d3Sopenharmony_ci return true; 88094332d3Sopenharmony_ci} 89094332d3Sopenharmony_ci 90094332d3Sopenharmony_cibool VendorInterface::Initialize( 91094332d3Sopenharmony_ci InitializeCompleteCallback initializeCompleteCallback, const ReceiveCallback &receiveCallback) 92094332d3Sopenharmony_ci{ 93094332d3Sopenharmony_ci HDF_LOGI("VendorInterface %{public}s, ", __func__); 94094332d3Sopenharmony_ci std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_); 95094332d3Sopenharmony_ci initializeCompleteCallback_ = initializeCompleteCallback; 96094332d3Sopenharmony_ci eventDataCallback_ = receiveCallback.onEventReceive; 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_ci HDF_LOGI("VendorInterface dlopen"); 99094332d3Sopenharmony_ci vendorHandle_ = dlopen(BT_VENDOR_NAME, RTLD_NOW); 100094332d3Sopenharmony_ci if (vendorHandle_ == nullptr) { 101094332d3Sopenharmony_ci HDF_LOGE("VendorInterface dlopen %{public}s failed, error code: %{public}s", BT_VENDOR_NAME, dlerror()); 102094332d3Sopenharmony_ci return false; 103094332d3Sopenharmony_ci } 104094332d3Sopenharmony_ci 105094332d3Sopenharmony_ci vendorInterface_ = 106094332d3Sopenharmony_ci reinterpret_cast<BtVendorInterfaceT *>(dlsym(vendorHandle_, BT_VENDOR_INTERFACE_SYMBOL_NAME)); 107094332d3Sopenharmony_ci 108094332d3Sopenharmony_ci auto bluetoothAddress = BluetoothAddress::GetDeviceAddress(); 109094332d3Sopenharmony_ci std::vector<uint8_t> address = { 0, 0, 0, 0, 0, 0 }; 110094332d3Sopenharmony_ci if (bluetoothAddress != nullptr) { 111094332d3Sopenharmony_ci bluetoothAddress->ReadAddress(address); 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci 114094332d3Sopenharmony_ci if (vendorInterface_ == nullptr) { 115094332d3Sopenharmony_ci HDF_LOGE("VendorInterface dlsym %{public}s failed.", BT_VENDOR_INTERFACE_SYMBOL_NAME); 116094332d3Sopenharmony_ci return false; 117094332d3Sopenharmony_ci } 118094332d3Sopenharmony_ci 119094332d3Sopenharmony_ci HDF_LOGI("VendorInterface init"); 120094332d3Sopenharmony_ci int result = vendorInterface_->init(&vendorCallbacks_, address.data()); 121094332d3Sopenharmony_ci if (result != 0) { 122094332d3Sopenharmony_ci HDF_LOGE("vendorInterface_->init failed."); 123094332d3Sopenharmony_ci return false; 124094332d3Sopenharmony_ci } 125094332d3Sopenharmony_ci 126094332d3Sopenharmony_ci result = vendorInterface_->op(BtOpcodeT::BT_OP_POWER_ON, nullptr); 127094332d3Sopenharmony_ci if (result != 0) { 128094332d3Sopenharmony_ci HDF_LOGE("vendorInterface_->op BT_OP_POWER_ON failed."); 129094332d3Sopenharmony_ci return false; 130094332d3Sopenharmony_ci } 131094332d3Sopenharmony_ci 132094332d3Sopenharmony_ci if (!WatchHciChannel(receiveCallback)) { 133094332d3Sopenharmony_ci return false; 134094332d3Sopenharmony_ci } 135094332d3Sopenharmony_ci 136094332d3Sopenharmony_ci if (!watcher_.Start()) { 137094332d3Sopenharmony_ci HDF_LOGE("watcher start failed."); 138094332d3Sopenharmony_ci return false; 139094332d3Sopenharmony_ci } 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_ci if (vendorInterface_ == nullptr) { 142094332d3Sopenharmony_ci HDF_LOGE("vendorInterface_ is nullptr"); 143094332d3Sopenharmony_ci return false; 144094332d3Sopenharmony_ci } 145094332d3Sopenharmony_ci 146094332d3Sopenharmony_ci HDF_LOGI("VendorInterface BT_OP_INIT"); 147094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_INIT, nullptr); 148094332d3Sopenharmony_ci 149094332d3Sopenharmony_ci HDF_LOGI("VendorInterface Initialize end"); 150094332d3Sopenharmony_ci return true; 151094332d3Sopenharmony_ci} 152094332d3Sopenharmony_ci 153094332d3Sopenharmony_civoid VendorInterface::CleanUp() 154094332d3Sopenharmony_ci{ 155094332d3Sopenharmony_ci std::lock_guard<std::mutex> lock(initAndCleanupProcessMutex_); 156094332d3Sopenharmony_ci HDF_LOGE("vendorInterface clean up."); 157094332d3Sopenharmony_ci if (vendorInterface_ == nullptr) { 158094332d3Sopenharmony_ci HDF_LOGE("VendorInterface::CleanUp, vendorInterface_ is nullptr."); 159094332d3Sopenharmony_ci return; 160094332d3Sopenharmony_ci } 161094332d3Sopenharmony_ci 162094332d3Sopenharmony_ci watcher_.Stop(); 163094332d3Sopenharmony_ci 164094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_LPM_DISABLE, nullptr); 165094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_HCI_CHANNEL_CLOSE, nullptr); 166094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_POWER_OFF, nullptr); 167094332d3Sopenharmony_ci vendorInterface_->close(); 168094332d3Sopenharmony_ci 169094332d3Sopenharmony_ci hci_ = nullptr; 170094332d3Sopenharmony_ci vendorInterface_ = nullptr; 171094332d3Sopenharmony_ci initializeCompleteCallback_ = nullptr; 172094332d3Sopenharmony_ci eventDataCallback_ = nullptr; 173094332d3Sopenharmony_ci dlclose(vendorHandle_); 174094332d3Sopenharmony_ci} 175094332d3Sopenharmony_ci 176094332d3Sopenharmony_cisize_t VendorInterface::SendPacket(Hci::HciPacketType type, const std::vector<uint8_t> &packet) 177094332d3Sopenharmony_ci{ 178094332d3Sopenharmony_ci if (vendorInterface_ == nullptr) { 179094332d3Sopenharmony_ci HDF_LOGE("VendorInterface::SendPacket, vendorInterface_ is nullptr."); 180094332d3Sopenharmony_ci return BT_VENDOR_INVALID_DATA_LEN; 181094332d3Sopenharmony_ci } 182094332d3Sopenharmony_ci 183094332d3Sopenharmony_ci { 184094332d3Sopenharmony_ci std::lock_guard<std::mutex> lock(wakeupMutex_); 185094332d3Sopenharmony_ci activity_ = true; 186094332d3Sopenharmony_ci watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer_), std::bind(&VendorInterface::WatcherTimeout, this)); 187094332d3Sopenharmony_ci if (!wakeupLock_) { 188094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_LOCK, nullptr); 189094332d3Sopenharmony_ci wakeupLock_ = true; 190094332d3Sopenharmony_ci } 191094332d3Sopenharmony_ci } 192094332d3Sopenharmony_ci 193094332d3Sopenharmony_ci if (hci_ == nullptr) { 194094332d3Sopenharmony_ci HDF_LOGE("VendorInterface::SendPacket, hci_ is nullptr."); 195094332d3Sopenharmony_ci return BT_VENDOR_INVALID_DATA_LEN; 196094332d3Sopenharmony_ci } 197094332d3Sopenharmony_ci return hci_->SendPacket(type, packet); 198094332d3Sopenharmony_ci} 199094332d3Sopenharmony_ci 200094332d3Sopenharmony_civoid VendorInterface::OnInitCallback(BtOpResultT result) 201094332d3Sopenharmony_ci{ 202094332d3Sopenharmony_ci HDF_LOGI("%{public}s, ", __func__); 203094332d3Sopenharmony_ci if (VendorInterface::GetInstance()->initializeCompleteCallback_) { 204094332d3Sopenharmony_ci VendorInterface::GetInstance()->initializeCompleteCallback_(result == BTC_OP_RESULT_SUCCESS); 205094332d3Sopenharmony_ci VendorInterface::GetInstance()->initializeCompleteCallback_ = nullptr; 206094332d3Sopenharmony_ci } 207094332d3Sopenharmony_ci 208094332d3Sopenharmony_ci uint32_t lpmTimer = 0; 209094332d3Sopenharmony_ci if (VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_GET_LPM_TIMER, &lpmTimer) != 0) { 210094332d3Sopenharmony_ci HDF_LOGE("Vector interface BT_OP_GET_LPM_TIMER failed"); 211094332d3Sopenharmony_ci } 212094332d3Sopenharmony_ci VendorInterface::GetInstance()->lpmTimer_ = lpmTimer; 213094332d3Sopenharmony_ci 214094332d3Sopenharmony_ci VendorInterface::GetInstance()->vendorInterface_->op(BtOpcodeT::BT_OP_LPM_ENABLE, nullptr); 215094332d3Sopenharmony_ci 216094332d3Sopenharmony_ci VendorInterface::GetInstance()->watcher_.SetTimeout(std::chrono::milliseconds(lpmTimer), 217094332d3Sopenharmony_ci std::bind(&VendorInterface::WatcherTimeout, VendorInterface::GetInstance())); 218094332d3Sopenharmony_ci} 219094332d3Sopenharmony_ci 220094332d3Sopenharmony_civoid *VendorInterface::OnMallocCallback(int size) 221094332d3Sopenharmony_ci{ 222094332d3Sopenharmony_ci static int MAX_BUFFER_SIZE = 1024; 223094332d3Sopenharmony_ci if (size <= 0 || size > MAX_BUFFER_SIZE) { 224094332d3Sopenharmony_ci HDF_LOGE("%{public}s, size is invalid", __func__); 225094332d3Sopenharmony_ci return nullptr; 226094332d3Sopenharmony_ci } 227094332d3Sopenharmony_ci return malloc(size); 228094332d3Sopenharmony_ci} 229094332d3Sopenharmony_ci 230094332d3Sopenharmony_civoid VendorInterface::OnFreeCallback(void *buf) 231094332d3Sopenharmony_ci{ 232094332d3Sopenharmony_ci if (buf != nullptr) { 233094332d3Sopenharmony_ci free(buf); 234094332d3Sopenharmony_ci } 235094332d3Sopenharmony_ci} 236094332d3Sopenharmony_ci 237094332d3Sopenharmony_cisize_t VendorInterface::OnCmdXmitCallback(uint16_t opcode, void *buf) 238094332d3Sopenharmony_ci{ 239094332d3Sopenharmony_ci HC_BT_HDR *hdr = reinterpret_cast<HC_BT_HDR *>(buf); 240094332d3Sopenharmony_ci 241094332d3Sopenharmony_ci VendorInterface::GetInstance()->vendorSentOpcode_ = opcode; 242094332d3Sopenharmony_ci 243094332d3Sopenharmony_ci return VendorInterface::GetInstance()->SendPacket( 244094332d3Sopenharmony_ci Hci::HCI_PACKET_TYPE_COMMAND, std::vector<uint8_t>(hdr->data, hdr->data + hdr->len)); 245094332d3Sopenharmony_ci} 246094332d3Sopenharmony_ci 247094332d3Sopenharmony_civoid VendorInterface::OnEventReceived(const std::vector<uint8_t> &data) 248094332d3Sopenharmony_ci{ 249094332d3Sopenharmony_ci if (data[0] == Hci::HCI_EVENT_CODE_VENDOR_SPECIFIC) { 250094332d3Sopenharmony_ci size_t buffSize = sizeof(HC_BT_HDR) + data.size(); 251094332d3Sopenharmony_ci HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]); 252094332d3Sopenharmony_ci buff->event = data[0]; 253094332d3Sopenharmony_ci buff->len = data.size(); 254094332d3Sopenharmony_ci buff->offset = 0; 255094332d3Sopenharmony_ci buff->layer_specific = 0; 256094332d3Sopenharmony_ci (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size()); 257094332d3Sopenharmony_ci if (vendorInterface_ && vendorInterface_->op) { 258094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff); 259094332d3Sopenharmony_ci } 260094332d3Sopenharmony_ci delete[] buff; 261094332d3Sopenharmony_ci } else if (vendorSentOpcode_ != 0 && data[0] == Hci::HCI_EVENT_CODE_COMMAND_COMPLETE) { 262094332d3Sopenharmony_ci uint8_t opcodeOffset = hci_->GetPacketHeaderInfo(Hci::HCI_PACKET_TYPE_EVENT).headerSize + 1; 263094332d3Sopenharmony_ci uint16_t opcode = data[opcodeOffset] + (data[opcodeOffset + 1] << 0x08); 264094332d3Sopenharmony_ci if (opcode == vendorSentOpcode_) { 265094332d3Sopenharmony_ci size_t buffSize = sizeof(HC_BT_HDR) + data.size(); 266094332d3Sopenharmony_ci HC_BT_HDR *buff = reinterpret_cast<HC_BT_HDR *>(new uint8_t[buffSize]); 267094332d3Sopenharmony_ci buff->event = data[0]; 268094332d3Sopenharmony_ci buff->len = data.size(); 269094332d3Sopenharmony_ci buff->offset = 0; 270094332d3Sopenharmony_ci buff->layer_specific = 0; 271094332d3Sopenharmony_ci (void)memcpy_s(buff->data, buffSize - sizeof(HC_BT_HDR), data.data(), data.size()); 272094332d3Sopenharmony_ci vendorSentOpcode_ = 0; 273094332d3Sopenharmony_ci if (vendorInterface_ && vendorInterface_->op) { 274094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_EVENT_CALLBACK, buff); 275094332d3Sopenharmony_ci } 276094332d3Sopenharmony_ci delete[] buff; 277094332d3Sopenharmony_ci } 278094332d3Sopenharmony_ci } 279094332d3Sopenharmony_ci 280094332d3Sopenharmony_ci eventDataCallback_(data); 281094332d3Sopenharmony_ci} 282094332d3Sopenharmony_ci 283094332d3Sopenharmony_civoid VendorInterface::WatcherTimeout() 284094332d3Sopenharmony_ci{ 285094332d3Sopenharmony_ci std::lock_guard<std::mutex> lock(wakeupMutex_); 286094332d3Sopenharmony_ci if (!activity_ && wakeupLock_ && vendorInterface_ && vendorInterface_->op) { 287094332d3Sopenharmony_ci vendorInterface_->op(BtOpcodeT::BT_OP_WAKEUP_UNLOCK, nullptr); 288094332d3Sopenharmony_ci wakeupLock_ = false; 289094332d3Sopenharmony_ci } 290094332d3Sopenharmony_ci activity_ = false; 291094332d3Sopenharmony_ci} 292094332d3Sopenharmony_ci} // namespace V1_0 293094332d3Sopenharmony_ci} // namespace Hci 294094332d3Sopenharmony_ci} // namespace Bluetooth 295094332d3Sopenharmony_ci} // namespace HDI 296094332d3Sopenharmony_ci} // namespace OHOS