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 "mct_protocol.h" 17 18#include <cerrno> 19#include <cstring> 20 21#include <hdf_log.h> 22 23#ifdef LOG_DOMAIN 24#undef LOG_DOMAIN 25#endif 26#define LOG_DOMAIN 0xD000105 27 28namespace OHOS { 29namespace HDI { 30namespace Bluetooth { 31namespace Hci { 32MctProtocol::MctProtocol(const int fds[HCI_MAX_CHANNEL], HciDataCallback onAclReceive, HciDataCallback onScoReceive, 33 HciDataCallback onEventReceive) 34{ 35 for (int ii = 0; ii < HCI_MAX_CHANNEL; ii++) { 36 hciFds_[ii] = fds[ii]; 37 } 38 onAclReceive_ = onAclReceive; 39 onScoReceive_ = onScoReceive; 40 onEventReceive_ = onEventReceive; 41} 42 43ssize_t MctProtocol::SendPacket(HciPacketType packetType, const std::vector<uint8_t> &packetData) 44{ 45 uint8_t type = packetType; 46 47 if (packetType == HciPacketType::HCI_PACKET_TYPE_COMMAND) { 48 return Write(hciFds_[hci_channels_t::HCI_CMD], &type, sizeof(type)); 49 } else if (packetType == HciPacketType::HCI_PACKET_TYPE_ACL_DATA) { 50 return Write(hciFds_[hci_channels_t::HCI_ACL_OUT], &type, sizeof(type)); 51 } 52 53 return 0; 54} 55 56void MctProtocol::ReadEventData(int fd) 57{ 58 const int bufsize = 256; 59 char buf[bufsize] = {0}; 60 ssize_t readLen; 61 if (eventPacket_.size() == header_[HCI_PACKET_TYPE_EVENT].headerSize) { 62 readLen = Read(fd, eventPacket_.data() + eventReadLength_, eventPacket_.size() - eventReadLength_); 63 if (readLen < 0) { 64 strerror_r(errno, buf, sizeof(buf)); 65 HDF_LOGE("read fd[%d] err:%s", fd, buf); 66 return; 67 } else if (readLen == 0) { 68 HDF_LOGE("read fd[%d] readLen = 0.", fd); 69 return; 70 } 71 72 eventReadLength_ += readLen; 73 if (eventReadLength_ == eventPacket_.size()) { 74 size_t dataLen = 0; 75 dataLen += eventPacket_[header_[HCI_PACKET_TYPE_EVENT].dataLengthOffset]; 76 eventPacket_.resize(eventPacket_.size() + dataLen); 77 } 78 } else { 79 readLen = Read(fd, eventPacket_.data() + eventReadLength_, eventPacket_.size() - eventReadLength_); 80 if (readLen < 0) { 81 strerror_r(errno, buf, sizeof(buf)); 82 HDF_LOGE("read fd[%d] err:%s", fd, buf); 83 return; 84 } else if (readLen == 0) { 85 HDF_LOGE("read fd[%d] readLen = 0.", fd); 86 return; 87 } 88 89 eventReadLength_ += readLen; 90 if (eventReadLength_ == eventPacket_.size()) { 91 if (onEventReceive_) { 92 onEventReceive_(eventPacket_); 93 } 94 eventPacket_.resize(header_[HCI_PACKET_TYPE_EVENT].headerSize); 95 eventReadLength_ = 0; 96 } 97 } 98} 99 100MctProtocol::~MctProtocol() {} 101 102void MctProtocol::ReadAclData(int fd) 103{ 104 const int bufsize = 256; 105 char buf[bufsize] = {0}; 106 ssize_t readLen; 107 if (aclPacket_.size() == header_[HCI_PACKET_TYPE_ACL_DATA].headerSize) { 108 readLen = Read(fd, aclPacket_.data() + aclReadLength_, aclPacket_.size() - aclReadLength_); 109 if (readLen < 0) { 110 strerror_r(errno, buf, sizeof(buf)); 111 HDF_LOGE("read fd[%d] err:%s", fd, buf); 112 return; 113 } else if (readLen == 0) { 114 HDF_LOGE("read fd[%d] readLen = 0.", fd); 115 return; 116 } 117 118 aclReadLength_ += readLen; 119 if (aclReadLength_ == aclPacket_.size()) { 120 size_t dataLen = 0; 121 dataLen += aclPacket_[header_[HCI_PACKET_TYPE_ACL_DATA].dataLengthOffset]; 122 aclPacket_.resize(aclPacket_.size() + dataLen); 123 } 124 } else { 125 readLen = Read(fd, aclPacket_.data() + aclReadLength_, aclPacket_.size() - aclReadLength_); 126 if (readLen < 0) { 127 strerror_r(errno, buf, sizeof(buf)); 128 HDF_LOGE("read fd[%d] err:%s", fd, buf); 129 return; 130 } else if (readLen == 0) { 131 HDF_LOGE("read fd[%d] readLen = 0.", fd); 132 return; 133 } 134 135 aclReadLength_ += readLen; 136 if (aclReadLength_ == aclPacket_.size()) { 137 if (onAclReceive_) { 138 onAclReceive_(aclPacket_); 139 } 140 aclPacket_.resize(header_[HCI_PACKET_TYPE_ACL_DATA].headerSize); 141 aclReadLength_ = 0; 142 } 143 } 144} 145} // namespace Hci 146} // namespace Bluetooth 147} // namespace HDI 148} // namespace OHOS