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 "mct_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_ciMctProtocol::MctProtocol(const int fds[HCI_MAX_CHANNEL], HciDataCallback onAclReceive, HciDataCallback onScoReceive,
33094332d3Sopenharmony_ci    HciDataCallback onEventReceive)
34094332d3Sopenharmony_ci{
35094332d3Sopenharmony_ci    for (int ii = 0; ii < HCI_MAX_CHANNEL; ii++) {
36094332d3Sopenharmony_ci        hciFds_[ii] = fds[ii];
37094332d3Sopenharmony_ci    }
38094332d3Sopenharmony_ci    onAclReceive_ = onAclReceive;
39094332d3Sopenharmony_ci    onScoReceive_ = onScoReceive;
40094332d3Sopenharmony_ci    onEventReceive_ = onEventReceive;
41094332d3Sopenharmony_ci}
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_cissize_t MctProtocol::SendPacket(HciPacketType packetType, const std::vector<uint8_t> &packetData)
44094332d3Sopenharmony_ci{
45094332d3Sopenharmony_ci    uint8_t type = packetType;
46094332d3Sopenharmony_ci
47094332d3Sopenharmony_ci    if (packetType == HciPacketType::HCI_PACKET_TYPE_COMMAND) {
48094332d3Sopenharmony_ci        return Write(hciFds_[hci_channels_t::HCI_CMD], &type, sizeof(type));
49094332d3Sopenharmony_ci    } else if (packetType == HciPacketType::HCI_PACKET_TYPE_ACL_DATA) {
50094332d3Sopenharmony_ci        return Write(hciFds_[hci_channels_t::HCI_ACL_OUT], &type, sizeof(type));
51094332d3Sopenharmony_ci    }
52094332d3Sopenharmony_ci
53094332d3Sopenharmony_ci    return 0;
54094332d3Sopenharmony_ci}
55094332d3Sopenharmony_ci
56094332d3Sopenharmony_civoid MctProtocol::ReadEventData(int fd)
57094332d3Sopenharmony_ci{
58094332d3Sopenharmony_ci    const int bufsize = 256;
59094332d3Sopenharmony_ci    char buf[bufsize] = {0};
60094332d3Sopenharmony_ci    ssize_t readLen;
61094332d3Sopenharmony_ci    if (eventPacket_.size() == header_[HCI_PACKET_TYPE_EVENT].headerSize) {
62094332d3Sopenharmony_ci        readLen = Read(fd, eventPacket_.data() + eventReadLength_, eventPacket_.size() - eventReadLength_);
63094332d3Sopenharmony_ci        if (readLen < 0) {
64094332d3Sopenharmony_ci            strerror_r(errno, buf, sizeof(buf));
65094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] err:%s", fd, buf);
66094332d3Sopenharmony_ci            return;
67094332d3Sopenharmony_ci        } else if (readLen == 0) {
68094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] readLen = 0.", fd);
69094332d3Sopenharmony_ci            return;
70094332d3Sopenharmony_ci        }
71094332d3Sopenharmony_ci
72094332d3Sopenharmony_ci        eventReadLength_ += readLen;
73094332d3Sopenharmony_ci        if (eventReadLength_ == eventPacket_.size()) {
74094332d3Sopenharmony_ci            size_t dataLen = 0;
75094332d3Sopenharmony_ci            dataLen += eventPacket_[header_[HCI_PACKET_TYPE_EVENT].dataLengthOffset];
76094332d3Sopenharmony_ci            eventPacket_.resize(eventPacket_.size() + dataLen);
77094332d3Sopenharmony_ci        }
78094332d3Sopenharmony_ci    } else {
79094332d3Sopenharmony_ci        readLen = Read(fd, eventPacket_.data() + eventReadLength_, eventPacket_.size() - eventReadLength_);
80094332d3Sopenharmony_ci        if (readLen < 0) {
81094332d3Sopenharmony_ci            strerror_r(errno, buf, sizeof(buf));
82094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] err:%s", fd, buf);
83094332d3Sopenharmony_ci            return;
84094332d3Sopenharmony_ci        } else if (readLen == 0) {
85094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] readLen = 0.", fd);
86094332d3Sopenharmony_ci            return;
87094332d3Sopenharmony_ci        }
88094332d3Sopenharmony_ci
89094332d3Sopenharmony_ci        eventReadLength_ += readLen;
90094332d3Sopenharmony_ci        if (eventReadLength_ == eventPacket_.size()) {
91094332d3Sopenharmony_ci            if (onEventReceive_) {
92094332d3Sopenharmony_ci                onEventReceive_(eventPacket_);
93094332d3Sopenharmony_ci            }
94094332d3Sopenharmony_ci            eventPacket_.resize(header_[HCI_PACKET_TYPE_EVENT].headerSize);
95094332d3Sopenharmony_ci            eventReadLength_ = 0;
96094332d3Sopenharmony_ci        }
97094332d3Sopenharmony_ci    }
98094332d3Sopenharmony_ci}
99094332d3Sopenharmony_ci
100094332d3Sopenharmony_ciMctProtocol::~MctProtocol() {}
101094332d3Sopenharmony_ci
102094332d3Sopenharmony_civoid MctProtocol::ReadAclData(int fd)
103094332d3Sopenharmony_ci{
104094332d3Sopenharmony_ci    const int bufsize = 256;
105094332d3Sopenharmony_ci    char buf[bufsize] = {0};
106094332d3Sopenharmony_ci    ssize_t readLen;
107094332d3Sopenharmony_ci    if (aclPacket_.size() == header_[HCI_PACKET_TYPE_ACL_DATA].headerSize) {
108094332d3Sopenharmony_ci        readLen = Read(fd, aclPacket_.data() + aclReadLength_, aclPacket_.size() - aclReadLength_);
109094332d3Sopenharmony_ci        if (readLen < 0) {
110094332d3Sopenharmony_ci            strerror_r(errno, buf, sizeof(buf));
111094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] err:%s", fd, buf);
112094332d3Sopenharmony_ci            return;
113094332d3Sopenharmony_ci        } else if (readLen == 0) {
114094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] readLen = 0.", fd);
115094332d3Sopenharmony_ci            return;
116094332d3Sopenharmony_ci        }
117094332d3Sopenharmony_ci
118094332d3Sopenharmony_ci        aclReadLength_ += readLen;
119094332d3Sopenharmony_ci        if (aclReadLength_ == aclPacket_.size()) {
120094332d3Sopenharmony_ci            size_t dataLen = 0;
121094332d3Sopenharmony_ci            dataLen += aclPacket_[header_[HCI_PACKET_TYPE_ACL_DATA].dataLengthOffset];
122094332d3Sopenharmony_ci            aclPacket_.resize(aclPacket_.size() + dataLen);
123094332d3Sopenharmony_ci        }
124094332d3Sopenharmony_ci    } else {
125094332d3Sopenharmony_ci        readLen = Read(fd, aclPacket_.data() + aclReadLength_, aclPacket_.size() - aclReadLength_);
126094332d3Sopenharmony_ci        if (readLen < 0) {
127094332d3Sopenharmony_ci            strerror_r(errno, buf, sizeof(buf));
128094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] err:%s", fd, buf);
129094332d3Sopenharmony_ci            return;
130094332d3Sopenharmony_ci        } else if (readLen == 0) {
131094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] readLen = 0.", fd);
132094332d3Sopenharmony_ci            return;
133094332d3Sopenharmony_ci        }
134094332d3Sopenharmony_ci
135094332d3Sopenharmony_ci        aclReadLength_ += readLen;
136094332d3Sopenharmony_ci        if (aclReadLength_ == aclPacket_.size()) {
137094332d3Sopenharmony_ci            if (onAclReceive_) {
138094332d3Sopenharmony_ci                onAclReceive_(aclPacket_);
139094332d3Sopenharmony_ci            }
140094332d3Sopenharmony_ci            aclPacket_.resize(header_[HCI_PACKET_TYPE_ACL_DATA].headerSize);
141094332d3Sopenharmony_ci            aclReadLength_ = 0;
142094332d3Sopenharmony_ci        }
143094332d3Sopenharmony_ci    }
144094332d3Sopenharmony_ci}
145094332d3Sopenharmony_ci}  // namespace Hci
146094332d3Sopenharmony_ci}  // namespace Bluetooth
147094332d3Sopenharmony_ci}  // namespace HDI
148094332d3Sopenharmony_ci}  // namespace OHOS