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 "h4_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_ciH4Protocol::H4Protocol(
33094332d3Sopenharmony_ci    int fd, HciDataCallback onAclReceive, HciDataCallback onScoReceive, HciDataCallback onEventReceive)
34094332d3Sopenharmony_ci    : hciFd_(fd), onAclReceive_(onAclReceive), onScoReceive_(onScoReceive), onEventReceive_(onEventReceive)
35094332d3Sopenharmony_ci{}
36094332d3Sopenharmony_ci
37094332d3Sopenharmony_cissize_t H4Protocol::SendPacket(HciPacketType packetType, const std::vector<uint8_t> &packetData)
38094332d3Sopenharmony_ci{
39094332d3Sopenharmony_ci    uint8_t type = packetType;
40094332d3Sopenharmony_ci    ssize_t writtenNumber = 0;
41094332d3Sopenharmony_ci
42094332d3Sopenharmony_ci    ssize_t ret = Write(hciFd_, &type, sizeof(type));
43094332d3Sopenharmony_ci    if (ret != sizeof(type)) {
44094332d3Sopenharmony_ci        return 0;
45094332d3Sopenharmony_ci    } else {
46094332d3Sopenharmony_ci        do {
47094332d3Sopenharmony_ci            ret = Write(hciFd_, packetData.data() + writtenNumber, packetData.size() - writtenNumber);
48094332d3Sopenharmony_ci            if (ret > 0) {
49094332d3Sopenharmony_ci                writtenNumber += ret;
50094332d3Sopenharmony_ci            } else if (ret < 0) {
51094332d3Sopenharmony_ci                return ret;
52094332d3Sopenharmony_ci            }
53094332d3Sopenharmony_ci        } while (static_cast<size_t>(writtenNumber) != packetData.size());
54094332d3Sopenharmony_ci    }
55094332d3Sopenharmony_ci
56094332d3Sopenharmony_ci    return writtenNumber;
57094332d3Sopenharmony_ci}
58094332d3Sopenharmony_ci
59094332d3Sopenharmony_civoid H4Protocol::ReadData(int fd)
60094332d3Sopenharmony_ci{
61094332d3Sopenharmony_ci    const int bufsize = 256;
62094332d3Sopenharmony_ci    char buf[bufsize] = {0};
63094332d3Sopenharmony_ci    ssize_t readLen;
64094332d3Sopenharmony_ci    if (hciPacket_.size() == 0) {
65094332d3Sopenharmony_ci        readLen = Read(fd, &packetType_, sizeof(packetType_));
66094332d3Sopenharmony_ci        if (readLen < 0) {
67094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d]", fd);
68094332d3Sopenharmony_ci            return;
69094332d3Sopenharmony_ci        } else if (readLen == 0) {
70094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] readLen = 0.", fd);
71094332d3Sopenharmony_ci            return;
72094332d3Sopenharmony_ci        }
73094332d3Sopenharmony_ci
74094332d3Sopenharmony_ci        if (packetType_ > HCI_PACKET_TYPE_UNKNOWN && packetType_ < HCI_PACKET_TYPE_MAX) {
75094332d3Sopenharmony_ci            hciPacket_.resize(header_[packetType_].headerSize);
76094332d3Sopenharmony_ci        }
77094332d3Sopenharmony_ci    } else if (hciPacket_.size() == header_[packetType_].headerSize) {
78094332d3Sopenharmony_ci        readLen = Read(fd, hciPacket_.data() + readLength_, hciPacket_.size() - readLength_);
79094332d3Sopenharmony_ci        if (readLen < 0) {
80094332d3Sopenharmony_ci            strerror_r(errno, buf, sizeof(buf));
81094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] err:%s", fd, buf);
82094332d3Sopenharmony_ci            return;
83094332d3Sopenharmony_ci        } else if (readLen == 0) {
84094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] readLen = 0.", fd);
85094332d3Sopenharmony_ci            return;
86094332d3Sopenharmony_ci        }
87094332d3Sopenharmony_ci
88094332d3Sopenharmony_ci        readLength_ += readLen;
89094332d3Sopenharmony_ci        if (readLength_ == hciPacket_.size()) {
90094332d3Sopenharmony_ci            size_t dataLen = 0;
91094332d3Sopenharmony_ci            for (int ii = 0; ii < header_[packetType_].dataLengthSize; ii++) {
92094332d3Sopenharmony_ci                dataLen += (hciPacket_[header_[packetType_].dataLengthOffset + ii] << (ii * 0x08));
93094332d3Sopenharmony_ci            }
94094332d3Sopenharmony_ci            hciPacket_.resize(hciPacket_.size() + dataLen);
95094332d3Sopenharmony_ci        }
96094332d3Sopenharmony_ci    } else {
97094332d3Sopenharmony_ci        readLen = Read(fd, hciPacket_.data() + readLength_, hciPacket_.size() - readLength_);
98094332d3Sopenharmony_ci        if (readLen < 0) {
99094332d3Sopenharmony_ci            strerror_r(errno, buf, sizeof(buf));
100094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] err:%s", fd, buf);
101094332d3Sopenharmony_ci            return;
102094332d3Sopenharmony_ci        } else if (readLen == 0) {
103094332d3Sopenharmony_ci            HDF_LOGE("read fd[%d] readLen = 0.", fd);
104094332d3Sopenharmony_ci            return;
105094332d3Sopenharmony_ci        }
106094332d3Sopenharmony_ci
107094332d3Sopenharmony_ci        readLength_ += readLen;
108094332d3Sopenharmony_ci        if (readLength_ == hciPacket_.size()) {
109094332d3Sopenharmony_ci            PacketCallback();
110094332d3Sopenharmony_ci            hciPacket_.clear();
111094332d3Sopenharmony_ci            readLength_ = 0;
112094332d3Sopenharmony_ci        }
113094332d3Sopenharmony_ci    }
114094332d3Sopenharmony_ci}
115094332d3Sopenharmony_ci
116094332d3Sopenharmony_ciH4Protocol::~H4Protocol() {}
117094332d3Sopenharmony_ci
118094332d3Sopenharmony_civoid H4Protocol::PacketCallback()
119094332d3Sopenharmony_ci{
120094332d3Sopenharmony_ci    switch (packetType_) {
121094332d3Sopenharmony_ci        case HCI_PACKET_TYPE_ACL_DATA:
122094332d3Sopenharmony_ci            if (onAclReceive_) {
123094332d3Sopenharmony_ci                onAclReceive_(hciPacket_);
124094332d3Sopenharmony_ci            }
125094332d3Sopenharmony_ci            break;
126094332d3Sopenharmony_ci        case HCI_PACKET_TYPE_SCO_DATA:
127094332d3Sopenharmony_ci            if (onScoReceive_) {
128094332d3Sopenharmony_ci                onScoReceive_(hciPacket_);
129094332d3Sopenharmony_ci            }
130094332d3Sopenharmony_ci            break;
131094332d3Sopenharmony_ci        case HCI_PACKET_TYPE_EVENT:
132094332d3Sopenharmony_ci            if (onEventReceive_) {
133094332d3Sopenharmony_ci                onEventReceive_(hciPacket_);
134094332d3Sopenharmony_ci            }
135094332d3Sopenharmony_ci            break;
136094332d3Sopenharmony_ci        default:
137094332d3Sopenharmony_ci            HDF_LOGE("PacketCallback type[%d] error.", packetType_);
138094332d3Sopenharmony_ci            break;
139094332d3Sopenharmony_ci    }
140094332d3Sopenharmony_ci}
141094332d3Sopenharmony_ci}  // namespace Hci
142094332d3Sopenharmony_ci}  // namespace Bluetooth
143094332d3Sopenharmony_ci}  // namespace HDI
144094332d3Sopenharmony_ci}  // namespace OHOS