1 /******************************************************************************
2 *
3 * Copyright (C) 2017 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_hci"
20
21 #include "hci_layer.h"
22
23 #include <base/logging.h>
24 #include "buffer_allocator.h"
25 #include "osi/include/log.h"
26 #include "sys/stat.h"
27 #include "sys/types.h"
28
29 #include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
30 #include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
31 #include <android/hardware/bluetooth/1.0/types.h>
32 #include <hwbinder/ProcessState.h>
33
34 #define LOG_PATH "/data/misc/bluetooth/logs/firmware_events.log"
35 #define LAST_LOG_PATH "/data/misc/bluetooth/logs/firmware_events.log.last"
36
37 using android::hardware::bluetooth::V1_0::IBluetoothHci;
38 using android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
39 using android::hardware::bluetooth::V1_0::HciPacket;
40 using android::hardware::bluetooth::V1_0::Status;
41 using android::hardware::ProcessState;
42 using ::android::hardware::Return;
43 using ::android::hardware::Void;
44 using ::android::hardware::hidl_vec;
45
46 extern void initialization_complete();
47 extern void hci_event_received(BT_HDR* packet);
48 extern void acl_event_received(BT_HDR* packet);
49 extern void sco_data_received(BT_HDR* packet);
50
51 android::sp<IBluetoothHci> btHci;
52
53 class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
54 public:
BluetoothHciCallbacks()55 BluetoothHciCallbacks() {
56 buffer_allocator = buffer_allocator_get_interface();
57 }
58
WrapPacketAndCopy(uint16_t event,const hidl_vec<uint8_t> & data)59 BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
60 size_t packet_size = data.size() + BT_HDR_SIZE;
61 BT_HDR* packet =
62 reinterpret_cast<BT_HDR*>(buffer_allocator->alloc(packet_size));
63 packet->offset = 0;
64 packet->len = data.size();
65 packet->layer_specific = 0;
66 packet->event = event;
67 // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
68 // be the only way the data is accessed, a pointer could be passed here...
69 memcpy(packet->data, data.data(), data.size());
70 return packet;
71 }
72
initializationComplete(Status status)73 Return<void> initializationComplete(Status status) {
74 CHECK(status == Status::SUCCESS);
75 initialization_complete();
76 return Void();
77 }
78
hciEventReceived(const hidl_vec<uint8_t> & event)79 Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) {
80 BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, event);
81 hci_event_received(packet);
82 return Void();
83 }
84
aclDataReceived(const hidl_vec<uint8_t> & data)85 Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) {
86 BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_ACL, data);
87 acl_event_received(packet);
88 return Void();
89 }
90
scoDataReceived(const hidl_vec<uint8_t> & data)91 Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) {
92 BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_SCO, data);
93 sco_data_received(packet);
94 return Void();
95 }
96
97 const allocator_t* buffer_allocator;
98 };
99
hci_initialize()100 void hci_initialize() {
101 LOG_INFO(LOG_TAG, "%s", __func__);
102
103 btHci = IBluetoothHci::getService();
104 // If android.hardware.bluetooth* is not found, Bluetooth can not continue.
105 CHECK(btHci != nullptr);
106 LOG_INFO(LOG_TAG, "%s: IBluetoothHci::getService() returned %p (%s)",
107 __func__, btHci.get(), (btHci->isRemote() ? "remote" : "local"));
108
109 // Block allows allocation of a variable that might be bypassed by goto.
110 {
111 android::sp<IBluetoothHciCallbacks> callbacks = new BluetoothHciCallbacks();
112 btHci->initialize(callbacks);
113 }
114 }
115
hci_close()116 void hci_close() {
117 btHci->close();
118 btHci = nullptr;
119 }
120
hci_transmit(BT_HDR * packet)121 void hci_transmit(BT_HDR* packet) {
122 HciPacket data;
123 data.setToExternal(packet->data + packet->offset, packet->len);
124
125 uint16_t event = packet->event & MSG_EVT_MASK;
126 switch (event & MSG_EVT_MASK) {
127 case MSG_STACK_TO_HC_HCI_CMD:
128 btHci->sendHciCommand(data);
129 break;
130 case MSG_STACK_TO_HC_HCI_ACL:
131 btHci->sendAclData(data);
132 break;
133 case MSG_STACK_TO_HC_HCI_SCO:
134 btHci->sendScoData(data);
135 break;
136 default:
137 LOG_ERROR(LOG_TAG, "Unknown packet type (%d)", event);
138 break;
139 }
140 }
141
hci_open_firmware_log_file()142 int hci_open_firmware_log_file() {
143 if (rename(LOG_PATH, LAST_LOG_PATH) == -1 && errno != ENOENT) {
144 LOG_ERROR(LOG_TAG, "%s unable to rename '%s' to '%s': %s", __func__,
145 LOG_PATH, LAST_LOG_PATH, strerror(errno));
146 }
147
148 mode_t prevmask = umask(0);
149 int logfile_fd = open(LOG_PATH, O_WRONLY | O_CREAT | O_TRUNC,
150 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
151 umask(prevmask);
152 if (logfile_fd == INVALID_FD) {
153 LOG_ERROR(LOG_TAG, "%s unable to open '%s': %s", __func__, LOG_PATH,
154 strerror(errno));
155 }
156
157 return logfile_fd;
158 }
159
hci_close_firmware_log_file(int fd)160 void hci_close_firmware_log_file(int fd) {
161 if (fd != INVALID_FD) close(fd);
162 }
163
hci_log_firmware_debug_packet(int fd,BT_HDR * packet)164 void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) {
165 TEMP_FAILURE_RETRY(write(fd, packet->data, packet->len));
166 }
167