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 "h4_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 {
H4Protocol( int fd, HciDataCallback onAclReceive, HciDataCallback onScoReceive, HciDataCallback onEventReceive)32 H4Protocol::H4Protocol(
33     int fd, HciDataCallback onAclReceive, HciDataCallback onScoReceive, HciDataCallback onEventReceive)
34     : hciFd_(fd), onAclReceive_(onAclReceive), onScoReceive_(onScoReceive), onEventReceive_(onEventReceive)
35 {}
36 
SendPacket(HciPacketType packetType, const std::vector<uint8_t> &packetData)37 ssize_t H4Protocol::SendPacket(HciPacketType packetType, const std::vector<uint8_t> &packetData)
38 {
39     uint8_t type = packetType;
40     ssize_t writtenNumber = 0;
41 
42     ssize_t ret = Write(hciFd_, &type, sizeof(type));
43     if (ret != sizeof(type)) {
44         return 0;
45     } else {
46         do {
47             ret = Write(hciFd_, packetData.data() + writtenNumber, packetData.size() - writtenNumber);
48             if (ret > 0) {
49                 writtenNumber += ret;
50             } else if (ret < 0) {
51                 return ret;
52             }
53         } while (static_cast<size_t>(writtenNumber) != packetData.size());
54     }
55 
56     return writtenNumber;
57 }
58 
ReadData(int fd)59 void H4Protocol::ReadData(int fd)
60 {
61     const int bufsize = 256;
62     char buf[bufsize] = {0};
63     ssize_t readLen;
64     if (hciPacket_.size() == 0) {
65         readLen = Read(fd, &packetType_, sizeof(packetType_));
66         if (readLen < 0) {
67             HDF_LOGE("read fd[%d]", fd);
68             return;
69         } else if (readLen == 0) {
70             HDF_LOGE("read fd[%d] readLen = 0.", fd);
71             return;
72         }
73 
74         if (packetType_ > HCI_PACKET_TYPE_UNKNOWN && packetType_ < HCI_PACKET_TYPE_MAX) {
75             hciPacket_.resize(header_[packetType_].headerSize);
76         }
77     } else if (hciPacket_.size() == header_[packetType_].headerSize) {
78         readLen = Read(fd, hciPacket_.data() + readLength_, hciPacket_.size() - readLength_);
79         if (readLen < 0) {
80             strerror_r(errno, buf, sizeof(buf));
81             HDF_LOGE("read fd[%d] err:%s", fd, buf);
82             return;
83         } else if (readLen == 0) {
84             HDF_LOGE("read fd[%d] readLen = 0.", fd);
85             return;
86         }
87 
88         readLength_ += readLen;
89         if (readLength_ == hciPacket_.size()) {
90             size_t dataLen = 0;
91             for (int ii = 0; ii < header_[packetType_].dataLengthSize; ii++) {
92                 dataLen += (hciPacket_[header_[packetType_].dataLengthOffset + ii] << (ii * 0x08));
93             }
94             hciPacket_.resize(hciPacket_.size() + dataLen);
95         }
96     } else {
97         readLen = Read(fd, hciPacket_.data() + readLength_, hciPacket_.size() - readLength_);
98         if (readLen < 0) {
99             strerror_r(errno, buf, sizeof(buf));
100             HDF_LOGE("read fd[%d] err:%s", fd, buf);
101             return;
102         } else if (readLen == 0) {
103             HDF_LOGE("read fd[%d] readLen = 0.", fd);
104             return;
105         }
106 
107         readLength_ += readLen;
108         if (readLength_ == hciPacket_.size()) {
109             PacketCallback();
110             hciPacket_.clear();
111             readLength_ = 0;
112         }
113     }
114 }
115 
~H4Protocol()116 H4Protocol::~H4Protocol() {}
117 
PacketCallback()118 void H4Protocol::PacketCallback()
119 {
120     switch (packetType_) {
121         case HCI_PACKET_TYPE_ACL_DATA:
122             if (onAclReceive_) {
123                 onAclReceive_(hciPacket_);
124             }
125             break;
126         case HCI_PACKET_TYPE_SCO_DATA:
127             if (onScoReceive_) {
128                 onScoReceive_(hciPacket_);
129             }
130             break;
131         case HCI_PACKET_TYPE_EVENT:
132             if (onEventReceive_) {
133                 onEventReceive_(hciPacket_);
134             }
135             break;
136         default:
137             HDF_LOGE("PacketCallback type[%d] error.", packetType_);
138             break;
139     }
140 }
141 }  // namespace Hci
142 }  // namespace Bluetooth
143 }  // namespace HDI
144 }  // namespace OHOS