blob: fe2b782b6d219904fc7766bc6b14d9c643638b11 [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
Myles Watson90ee15b2017-02-09 16:47:33 -080021#include <android-base/logging.h>
Myles Watson761dc492017-03-03 13:50:49 -080022#include <sys/ioctl.h>
23#include <sys/socket.h>
24#include <unistd.h>
25#include <utils/Log.h>
Myles Watson90ee15b2017-02-09 16:47:33 -080026
27namespace android {
28namespace hardware {
29namespace bluetooth {
30namespace V1_0 {
31namespace hikey {
32
Myles Watson761dc492017-03-03 13:50:49 -080033using android::hardware::hidl_vec;
34
Myles Watson7cc9c402017-03-03 14:58:47 -080035BluetoothHci::BluetoothHci()
36 : deathRecipient(new BluetoothDeathRecipient(this)) {}
37
Myles Watson90ee15b2017-02-09 16:47:33 -080038Return<void> BluetoothHci::initialize(
39 const ::android::sp<IBluetoothHciCallbacks>& cb) {
40 ALOGI("BluetoothHci::initialize()");
41
Myles Watson90ee15b2017-02-09 16:47:33 -080042 hci_tty_fd_ = open("/dev/hci_tty", O_RDWR);
43 if (hci_tty_fd_ < 0) {
Myles Watson761dc492017-03-03 13:50:49 -080044 ALOGE("%s: Can't open hci_tty (%s)", __func__, strerror(errno));
45 cb->initializationComplete(Status::INITIALIZATION_ERROR);
46 return Void();
Myles Watson90ee15b2017-02-09 16:47:33 -080047 }
48
Myles Watson761dc492017-03-03 13:50:49 -080049 event_cb_ = cb;
Myles Watson7cc9c402017-03-03 14:58:47 -080050 event_cb_->linkToDeath(deathRecipient, 0);
Myles Watson761dc492017-03-03 13:50:49 -080051
52 hci_ = new hci::H4Protocol(
53 hci_tty_fd_,
54 [cb](const hidl_vec<uint8_t>& packet) { cb->hciEventReceived(packet); },
55 [cb](const hidl_vec<uint8_t>& packet) { cb->aclDataReceived(packet); },
56 [cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); });
57
58 // Use a socket pair to enforce the TI FIONREAD requirement.
59 int sockfd[2];
60 socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
61 int shim_fd = sockfd[0];
62 int for_hci = sockfd[1];
63
64 fd_watcher_.WatchFdForNonBlockingReads(hci_tty_fd_, [this, shim_fd](int fd) {
65 int tty_bytes = 0;
66 if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, &tty_bytes)))
67 ALOGE("%s:FIONREAD %s", __func__, strerror(errno));
68 ALOGV("%s:tty_bytes = %d", __func__, tty_bytes);
69
70 uint8_t* tmp_buffer = new uint8_t[tty_bytes];
71 size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, tmp_buffer, tty_bytes));
72 CHECK(static_cast<int>(bytes_read) == tty_bytes);
73 size_t bytes_written =
74 TEMP_FAILURE_RETRY(write(shim_fd, tmp_buffer, tty_bytes));
75 CHECK(static_cast<int>(bytes_written) == tty_bytes);
76 delete[] tmp_buffer;
77 });
Myles Watson90ee15b2017-02-09 16:47:33 -080078
79 fd_watcher_.WatchFdForNonBlockingReads(
Myles Watson761dc492017-03-03 13:50:49 -080080 for_hci, [this](int fd) { hci_->OnDataReady(fd); });
Myles Watson90ee15b2017-02-09 16:47:33 -080081
Myles Watson761dc492017-03-03 13:50:49 -080082 cb->initializationComplete(Status::SUCCESS);
Myles Watson90ee15b2017-02-09 16:47:33 -080083 return Void();
84}
85
86Return<void> BluetoothHci::close() {
Myles Watson761dc492017-03-03 13:50:49 -080087 ALOGI("BluetoothHci::close()");
88
89 if (hci_tty_fd_ >= 0) {
90 fd_watcher_.StopWatchingFileDescriptors();
91 ::close(hci_tty_fd_);
92 hci_tty_fd_ = -1;
93 }
94
Myles Watson7cc9c402017-03-03 14:58:47 -080095 event_cb_->unlinkToDeath(deathRecipient);
96
Myles Watson761dc492017-03-03 13:50:49 -080097 if (hci_ != nullptr) {
98 delete hci_;
99 hci_ = nullptr;
100 }
101
Myles Watson90ee15b2017-02-09 16:47:33 -0800102 return Void();
103}
104
105Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
Myles Watson761dc492017-03-03 13:50:49 -0800106 hci_->Send(HCI_PACKET_TYPE_COMMAND, packet.data(), packet.size());
Myles Watson90ee15b2017-02-09 16:47:33 -0800107 return Void();
108}
109
110Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
Myles Watson761dc492017-03-03 13:50:49 -0800111 hci_->Send(HCI_PACKET_TYPE_ACL_DATA, packet.data(), packet.size());
Myles Watson90ee15b2017-02-09 16:47:33 -0800112 return Void();
113}
114
115Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
Myles Watson761dc492017-03-03 13:50:49 -0800116 hci_->Send(HCI_PACKET_TYPE_SCO_DATA, packet.data(), packet.size());
Myles Watson90ee15b2017-02-09 16:47:33 -0800117 return Void();
118}
119
Myles Watson90ee15b2017-02-09 16:47:33 -0800120} // namespace hikey
121} // namespace V1_0
122} // namespace bluetooth
123} // namespace hardware
124} // namespace android