• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 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 <fcntl.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 
27 #include <base/location.h>
28 #include <base/logging.h>
29 #include "buffer_allocator.h"
30 #include "osi/include/log.h"
31 
32 #include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
33 #include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
34 #include <android/hardware/bluetooth/1.0/types.h>
35 #include <hwbinder/ProcessState.h>
36 
37 #define LOG_PATH "/data/misc/bluetooth/logs/firmware_events.log"
38 #define LAST_LOG_PATH "/data/misc/bluetooth/logs/firmware_events.log.last"
39 
40 using ::android::hardware::hidl_death_recipient;
41 using ::android::hardware::hidl_vec;
42 using ::android::hardware::ProcessState;
43 using ::android::hardware::Return;
44 using ::android::hardware::Void;
45 using ::android::hardware::bluetooth::V1_0::HciPacket;
46 using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
47 using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
48 using ::android::hardware::bluetooth::V1_0::Status;
49 
50 extern void initialization_complete();
51 extern void hci_event_received(const base::Location& from_here, BT_HDR* packet);
52 extern void acl_event_received(BT_HDR* packet);
53 extern void sco_data_received(BT_HDR* packet);
54 
55 android::sp<IBluetoothHci> btHci;
56 
57 class BluetoothHciDeathRecipient : public hidl_death_recipient {
58  public:
serviceDied(uint64_t,const android::wp<::android::hidl::base::V1_0::IBase> &)59   virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
60     LOG_ERROR(LOG_TAG, "Bluetooth HAL service died!");
61     abort();
62   }
63 };
64 android::sp<BluetoothHciDeathRecipient> bluetoothHciDeathRecipient = new BluetoothHciDeathRecipient();
65 
66 class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
67  public:
BluetoothHciCallbacks()68   BluetoothHciCallbacks() {
69     buffer_allocator = buffer_allocator_get_interface();
70   }
71 
WrapPacketAndCopy(uint16_t event,const hidl_vec<uint8_t> & data)72   BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
73     size_t packet_size = data.size() + BT_HDR_SIZE;
74     BT_HDR* packet =
75         reinterpret_cast<BT_HDR*>(buffer_allocator->alloc(packet_size));
76     packet->offset = 0;
77     packet->len = data.size();
78     packet->layer_specific = 0;
79     packet->event = event;
80     // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
81     // be the only way the data is accessed, a pointer could be passed here...
82     memcpy(packet->data, data.data(), data.size());
83     return packet;
84   }
85 
initializationComplete(Status status)86   Return<void> initializationComplete(Status status) {
87     CHECK(status == Status::SUCCESS);
88     initialization_complete();
89     return Void();
90   }
91 
hciEventReceived(const hidl_vec<uint8_t> & event)92   Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) {
93     BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, event);
94     hci_event_received(FROM_HERE, packet);
95     return Void();
96   }
97 
aclDataReceived(const hidl_vec<uint8_t> & data)98   Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) {
99     BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_ACL, data);
100     acl_event_received(packet);
101     return Void();
102   }
103 
scoDataReceived(const hidl_vec<uint8_t> & data)104   Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) {
105     BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_SCO, data);
106     sco_data_received(packet);
107     return Void();
108   }
109 
110   const allocator_t* buffer_allocator;
111 };
112 
hci_initialize()113 void hci_initialize() {
114   LOG_INFO(LOG_TAG, "%s", __func__);
115 
116   btHci = IBluetoothHci::getService();
117   // If android.hardware.bluetooth* is not found, Bluetooth can not continue.
118   CHECK(btHci != nullptr);
119   auto death_link = btHci->linkToDeath(bluetoothHciDeathRecipient, 0);
120   if (!death_link.isOk()) {
121     LOG_ERROR(LOG_TAG, "%s: Unable to set the death recipient for the Bluetooth HAL", __func__);
122     abort();
123   }
124   LOG_INFO(LOG_TAG, "%s: IBluetoothHci::getService() returned %p (%s)",
125            __func__, btHci.get(), (btHci->isRemote() ? "remote" : "local"));
126 
127   // Block allows allocation of a variable that might be bypassed by goto.
128   {
129     android::sp<IBluetoothHciCallbacks> callbacks = new BluetoothHciCallbacks();
130     btHci->initialize(callbacks);
131   }
132 }
133 
hci_close()134 void hci_close() {
135   if (btHci != nullptr) {
136     auto death_unlink = btHci->unlinkToDeath(bluetoothHciDeathRecipient);
137     if (!death_unlink.isOk()) {
138       LOG_ERROR(LOG_TAG, "%s: Error unlinking death recipient from the Bluetooth HAL", __func__);
139     }
140   }
141   btHci->close();
142   btHci = nullptr;
143 }
144 
hci_transmit(BT_HDR * packet)145 void hci_transmit(BT_HDR* packet) {
146   HciPacket data;
147   data.setToExternal(packet->data + packet->offset, packet->len);
148 
149   uint16_t event = packet->event & MSG_EVT_MASK;
150   switch (event & MSG_EVT_MASK) {
151     case MSG_STACK_TO_HC_HCI_CMD:
152       btHci->sendHciCommand(data);
153       break;
154     case MSG_STACK_TO_HC_HCI_ACL:
155       btHci->sendAclData(data);
156       break;
157     case MSG_STACK_TO_HC_HCI_SCO:
158       btHci->sendScoData(data);
159       break;
160     default:
161       LOG_ERROR(LOG_TAG, "Unknown packet type (%d)", event);
162       break;
163   }
164 }
165 
hci_open_firmware_log_file()166 int hci_open_firmware_log_file() {
167   if (rename(LOG_PATH, LAST_LOG_PATH) == -1 && errno != ENOENT) {
168     LOG_ERROR(LOG_TAG, "%s unable to rename '%s' to '%s': %s", __func__,
169               LOG_PATH, LAST_LOG_PATH, strerror(errno));
170   }
171 
172   mode_t prevmask = umask(0);
173   int logfile_fd = open(LOG_PATH, O_WRONLY | O_CREAT | O_TRUNC,
174                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
175   umask(prevmask);
176   if (logfile_fd == INVALID_FD) {
177     LOG_ERROR(LOG_TAG, "%s unable to open '%s': %s", __func__, LOG_PATH,
178               strerror(errno));
179   }
180 
181   return logfile_fd;
182 }
183 
hci_close_firmware_log_file(int fd)184 void hci_close_firmware_log_file(int fd) {
185   if (fd != INVALID_FD) close(fd);
186 }
187 
hci_log_firmware_debug_packet(int fd,BT_HDR * packet)188 void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) {
189   TEMP_FAILURE_RETRY(write(fd, packet->data, packet->len));
190 }
191