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 "h4_protocol.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <cerrno> 19094332d3Sopenharmony_ci#include <cstring> 20094332d3Sopenharmony_ci 21094332d3Sopenharmony_ci#include <hdf_log.h> 22094332d3Sopenharmony_ci 23094332d3Sopenharmony_ci#ifdef LOG_DOMAIN 24094332d3Sopenharmony_ci#undef LOG_DOMAIN 25094332d3Sopenharmony_ci#endif 26094332d3Sopenharmony_ci#define LOG_DOMAIN 0xD000105 27094332d3Sopenharmony_ci 28094332d3Sopenharmony_cinamespace OHOS { 29094332d3Sopenharmony_cinamespace HDI { 30094332d3Sopenharmony_cinamespace Bluetooth { 31094332d3Sopenharmony_cinamespace Hci { 32094332d3Sopenharmony_ciH4Protocol::H4Protocol( 33094332d3Sopenharmony_ci int fd, HciDataCallback onAclReceive, HciDataCallback onScoReceive, HciDataCallback onEventReceive) 34094332d3Sopenharmony_ci : hciFd_(fd), onAclReceive_(onAclReceive), onScoReceive_(onScoReceive), onEventReceive_(onEventReceive) 35094332d3Sopenharmony_ci{} 36094332d3Sopenharmony_ci 37094332d3Sopenharmony_cissize_t H4Protocol::SendPacket(HciPacketType packetType, const std::vector<uint8_t> &packetData) 38094332d3Sopenharmony_ci{ 39094332d3Sopenharmony_ci uint8_t type = packetType; 40094332d3Sopenharmony_ci ssize_t writtenNumber = 0; 41094332d3Sopenharmony_ci 42094332d3Sopenharmony_ci ssize_t ret = Write(hciFd_, &type, sizeof(type)); 43094332d3Sopenharmony_ci if (ret != sizeof(type)) { 44094332d3Sopenharmony_ci return 0; 45094332d3Sopenharmony_ci } else { 46094332d3Sopenharmony_ci do { 47094332d3Sopenharmony_ci ret = Write(hciFd_, packetData.data() + writtenNumber, packetData.size() - writtenNumber); 48094332d3Sopenharmony_ci if (ret > 0) { 49094332d3Sopenharmony_ci writtenNumber += ret; 50094332d3Sopenharmony_ci } else if (ret < 0) { 51094332d3Sopenharmony_ci return ret; 52094332d3Sopenharmony_ci } 53094332d3Sopenharmony_ci } while (static_cast<size_t>(writtenNumber) != packetData.size()); 54094332d3Sopenharmony_ci } 55094332d3Sopenharmony_ci 56094332d3Sopenharmony_ci return writtenNumber; 57094332d3Sopenharmony_ci} 58094332d3Sopenharmony_ci 59094332d3Sopenharmony_civoid H4Protocol::ReadData(int fd) 60094332d3Sopenharmony_ci{ 61094332d3Sopenharmony_ci const int bufsize = 256; 62094332d3Sopenharmony_ci char buf[bufsize] = {0}; 63094332d3Sopenharmony_ci ssize_t readLen; 64094332d3Sopenharmony_ci if (hciPacket_.size() == 0) { 65094332d3Sopenharmony_ci readLen = Read(fd, &packetType_, sizeof(packetType_)); 66094332d3Sopenharmony_ci if (readLen < 0) { 67094332d3Sopenharmony_ci HDF_LOGE("read fd[%d]", fd); 68094332d3Sopenharmony_ci return; 69094332d3Sopenharmony_ci } else if (readLen == 0) { 70094332d3Sopenharmony_ci HDF_LOGE("read fd[%d] readLen = 0.", fd); 71094332d3Sopenharmony_ci return; 72094332d3Sopenharmony_ci } 73094332d3Sopenharmony_ci 74094332d3Sopenharmony_ci if (packetType_ > HCI_PACKET_TYPE_UNKNOWN && packetType_ < HCI_PACKET_TYPE_MAX) { 75094332d3Sopenharmony_ci hciPacket_.resize(header_[packetType_].headerSize); 76094332d3Sopenharmony_ci } 77094332d3Sopenharmony_ci } else if (hciPacket_.size() == header_[packetType_].headerSize) { 78094332d3Sopenharmony_ci readLen = Read(fd, hciPacket_.data() + readLength_, hciPacket_.size() - readLength_); 79094332d3Sopenharmony_ci if (readLen < 0) { 80094332d3Sopenharmony_ci strerror_r(errno, buf, sizeof(buf)); 81094332d3Sopenharmony_ci HDF_LOGE("read fd[%d] err:%s", fd, buf); 82094332d3Sopenharmony_ci return; 83094332d3Sopenharmony_ci } else if (readLen == 0) { 84094332d3Sopenharmony_ci HDF_LOGE("read fd[%d] readLen = 0.", fd); 85094332d3Sopenharmony_ci return; 86094332d3Sopenharmony_ci } 87094332d3Sopenharmony_ci 88094332d3Sopenharmony_ci readLength_ += readLen; 89094332d3Sopenharmony_ci if (readLength_ == hciPacket_.size()) { 90094332d3Sopenharmony_ci size_t dataLen = 0; 91094332d3Sopenharmony_ci for (int ii = 0; ii < header_[packetType_].dataLengthSize; ii++) { 92094332d3Sopenharmony_ci dataLen += (hciPacket_[header_[packetType_].dataLengthOffset + ii] << (ii * 0x08)); 93094332d3Sopenharmony_ci } 94094332d3Sopenharmony_ci hciPacket_.resize(hciPacket_.size() + dataLen); 95094332d3Sopenharmony_ci } 96094332d3Sopenharmony_ci } else { 97094332d3Sopenharmony_ci readLen = Read(fd, hciPacket_.data() + readLength_, hciPacket_.size() - readLength_); 98094332d3Sopenharmony_ci if (readLen < 0) { 99094332d3Sopenharmony_ci strerror_r(errno, buf, sizeof(buf)); 100094332d3Sopenharmony_ci HDF_LOGE("read fd[%d] err:%s", fd, buf); 101094332d3Sopenharmony_ci return; 102094332d3Sopenharmony_ci } else if (readLen == 0) { 103094332d3Sopenharmony_ci HDF_LOGE("read fd[%d] readLen = 0.", fd); 104094332d3Sopenharmony_ci return; 105094332d3Sopenharmony_ci } 106094332d3Sopenharmony_ci 107094332d3Sopenharmony_ci readLength_ += readLen; 108094332d3Sopenharmony_ci if (readLength_ == hciPacket_.size()) { 109094332d3Sopenharmony_ci PacketCallback(); 110094332d3Sopenharmony_ci hciPacket_.clear(); 111094332d3Sopenharmony_ci readLength_ = 0; 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci } 114094332d3Sopenharmony_ci} 115094332d3Sopenharmony_ci 116094332d3Sopenharmony_ciH4Protocol::~H4Protocol() {} 117094332d3Sopenharmony_ci 118094332d3Sopenharmony_civoid H4Protocol::PacketCallback() 119094332d3Sopenharmony_ci{ 120094332d3Sopenharmony_ci switch (packetType_) { 121094332d3Sopenharmony_ci case HCI_PACKET_TYPE_ACL_DATA: 122094332d3Sopenharmony_ci if (onAclReceive_) { 123094332d3Sopenharmony_ci onAclReceive_(hciPacket_); 124094332d3Sopenharmony_ci } 125094332d3Sopenharmony_ci break; 126094332d3Sopenharmony_ci case HCI_PACKET_TYPE_SCO_DATA: 127094332d3Sopenharmony_ci if (onScoReceive_) { 128094332d3Sopenharmony_ci onScoReceive_(hciPacket_); 129094332d3Sopenharmony_ci } 130094332d3Sopenharmony_ci break; 131094332d3Sopenharmony_ci case HCI_PACKET_TYPE_EVENT: 132094332d3Sopenharmony_ci if (onEventReceive_) { 133094332d3Sopenharmony_ci onEventReceive_(hciPacket_); 134094332d3Sopenharmony_ci } 135094332d3Sopenharmony_ci break; 136094332d3Sopenharmony_ci default: 137094332d3Sopenharmony_ci HDF_LOGE("PacketCallback type[%d] error.", packetType_); 138094332d3Sopenharmony_ci break; 139094332d3Sopenharmony_ci } 140094332d3Sopenharmony_ci} 141094332d3Sopenharmony_ci} // namespace Hci 142094332d3Sopenharmony_ci} // namespace Bluetooth 143094332d3Sopenharmony_ci} // namespace HDI 144094332d3Sopenharmony_ci} // namespace OHOS