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 
28 namespace OHOS {
29 namespace HDI {
30 namespace Bluetooth {
31 namespace Hci {
MctProtocol(const int fds[HCI_MAX_CHANNEL],HciDataCallback onAclReceive,HciDataCallback onScoReceive,HciDataCallback onEventReceive)32 MctProtocol::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 
SendPacket(HciPacketType packetType,const std::vector<uint8_t> & packetData)43 ssize_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 
ReadEventData(int fd)56 void 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 
~MctProtocol()100 MctProtocol::~MctProtocol() {}
101 
ReadAclData(int fd)102 void 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