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