blob: 64107656aa591b40528616060233d73514c671d0 [file] [log] [blame]
Myles Watson90ee15b2017-02-09 16:47:33 -08001//
2// Copyright 2016 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#define LOG_TAG "android.hardware.bluetooth@1.0.hikey"
18
19#include "bluetooth_hci.h"
20
21#include <utils/Log.h>
22
23#include <android-base/logging.h>
24
25#include "hci_internals.h"
26
27namespace {
28
29using android::hardware::bluetooth::V1_0::hikey::BluetoothHci;
30using android::hardware::hidl_vec;
31
32BluetoothHci* g_bluetooth_hci = nullptr;
33
34size_t write_safely(int fd, const uint8_t* data, size_t length) {
35 size_t transmitted_length = 0;
36 while (length > 0) {
37 ssize_t ret =
38 TEMP_FAILURE_RETRY(write(fd, data + transmitted_length, length));
39
40 if (ret == -1) {
41 if (errno == EAGAIN) continue;
42 ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
43 break;
44
45 } else if (ret == 0) {
46 // Nothing written :(
47 ALOGE("%s zero bytes written - something went wrong...", __func__);
48 break;
49 }
50
51 transmitted_length += ret;
52 length -= ret;
53 }
54
55 return transmitted_length;
56}
57
58} // namespace
59
60namespace android {
61namespace hardware {
62namespace bluetooth {
63namespace V1_0 {
64namespace hikey {
65
66Return<void> BluetoothHci::initialize(
67 const ::android::sp<IBluetoothHciCallbacks>& cb) {
68 ALOGI("BluetoothHci::initialize()");
69
70 CHECK(cb != nullptr);
71 event_cb_ = cb;
72
73 hci_tty_fd_ = open("/dev/hci_tty", O_RDWR);
74 if (hci_tty_fd_ < 0) {
75 ALOGE("%s: Can't open hci_tty", __func__);
76 event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
77 }
78
79 CHECK(g_bluetooth_hci == nullptr) << __func__ << " is not reentrant";
80 g_bluetooth_hci = this;
81
82 fd_watcher_.WatchFdForNonBlockingReads(
83 hci_tty_fd_, [this](int fd) { hci_packetizer_.OnDataReadyHikey(fd); });
84
85 event_cb_->initializationComplete(Status::SUCCESS);
86 return Void();
87}
88
89Return<void> BluetoothHci::close() {
90 ALOGW("BluetoothHci::close()");
91 ::close(hci_tty_fd_);
92 hci_tty_fd_ = -1;
93 g_bluetooth_hci = nullptr;
94 return Void();
95}
96
97Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
98 uint8_t type = HCI_PACKET_TYPE_COMMAND;
99 int rv = write_safely(hci_tty_fd_, &type, sizeof(type));
100 if (rv == sizeof(type))
101 rv = write_safely(hci_tty_fd_, packet.data(), packet.size());
102 return Void();
103}
104
105Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
106 uint8_t type = HCI_PACKET_TYPE_ACL_DATA;
107 int rv = write_safely(hci_tty_fd_, &type, sizeof(type));
108 if (rv == sizeof(type))
109 rv = write_safely(hci_tty_fd_, packet.data(), packet.size());
110 return Void();
111}
112
113Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
114 uint8_t type = HCI_PACKET_TYPE_SCO_DATA;
115 int rv = write_safely(hci_tty_fd_, &type, sizeof(type));
116 if (rv == sizeof(type))
117 rv = write_safely(hci_tty_fd_, packet.data(), packet.size());
118 return Void();
119}
120
121BluetoothHci* BluetoothHci::get() { return g_bluetooth_hci; }
122
123void BluetoothHci::OnPacketReady() {
124 BluetoothHci::get()->HandleIncomingPacket();
125}
126
127void BluetoothHci::HandleIncomingPacket() {
128 HciPacketType hci_packet_type = hci_packetizer_.GetPacketType();
129 hidl_vec<uint8_t> hci_packet = hci_packetizer_.GetPacket();
130
131 switch (hci_packet_type) {
132 case HCI_PACKET_TYPE_EVENT:
133 event_cb_->hciEventReceived(hci_packet);
134 break;
135 case HCI_PACKET_TYPE_ACL_DATA:
136 event_cb_->aclDataReceived(hci_packet);
137 break;
138 case HCI_PACKET_TYPE_SCO_DATA:
139 event_cb_->scoDataReceived(hci_packet);
140 break;
141 default: {
142 bool hci_packet_type_corrupted = true;
143 CHECK(hci_packet_type_corrupted == false);
144 }
145 }
146}
147
148} // namespace hikey
149} // namespace V1_0
150} // namespace bluetooth
151} // namespace hardware
152} // namespace android