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::bluetooth::V1_0::IBluetoothHci; 41 using android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks; 42 using android::hardware::bluetooth::V1_0::HciPacket; 43 using android::hardware::bluetooth::V1_0::Status; 44 using android::hardware::ProcessState; 45 using ::android::hardware::Return; 46 using ::android::hardware::Void; 47 using ::android::hardware::hidl_vec; 48 49 extern void initialization_complete(); 50 extern void hci_event_received(const tracked_objects::Location& from_here, 51 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 BluetoothHciCallbacks : public IBluetoothHciCallbacks { 58 public: 59 BluetoothHciCallbacks() { 60 buffer_allocator = buffer_allocator_get_interface(); 61 } 62 63 BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) { 64 size_t packet_size = data.size() + BT_HDR_SIZE; 65 BT_HDR* packet = 66 reinterpret_cast<BT_HDR*>(buffer_allocator->alloc(packet_size)); 67 packet->offset = 0; 68 packet->len = data.size(); 69 packet->layer_specific = 0; 70 packet->event = event; 71 // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to 72 // be the only way the data is accessed, a pointer could be passed here... 73 memcpy(packet->data, data.data(), data.size()); 74 return packet; 75 } 76 77 Return<void> initializationComplete(Status status) { 78 CHECK(status == Status::SUCCESS); 79 initialization_complete(); 80 return Void(); 81 } 82 83 Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) { 84 BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, event); 85 hci_event_received(FROM_HERE, packet); 86 return Void(); 87 } 88 89 Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) { 90 BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_ACL, data); 91 acl_event_received(packet); 92 return Void(); 93 } 94 95 Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) { 96 BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_SCO, data); 97 sco_data_received(packet); 98 return Void(); 99 } 100 101 const allocator_t* buffer_allocator; 102 }; 103 104 void hci_initialize() { 105 LOG_INFO(LOG_TAG, "%s", __func__); 106 107 btHci = IBluetoothHci::getService(); 108 // If android.hardware.bluetooth* is not found, Bluetooth can not continue. 109 CHECK(btHci != nullptr); 110 LOG_INFO(LOG_TAG, "%s: IBluetoothHci::getService() returned %p (%s)", 111 __func__, btHci.get(), (btHci->isRemote() ? "remote" : "local")); 112 113 // Block allows allocation of a variable that might be bypassed by goto. 114 { 115 android::sp<IBluetoothHciCallbacks> callbacks = new BluetoothHciCallbacks(); 116 btHci->initialize(callbacks); 117 } 118 } 119 120 void hci_close() { 121 btHci->close(); 122 btHci = nullptr; 123 } 124 125 void hci_transmit(BT_HDR* packet) { 126 HciPacket data; 127 data.setToExternal(packet->data + packet->offset, packet->len); 128 129 uint16_t event = packet->event & MSG_EVT_MASK; 130 switch (event & MSG_EVT_MASK) { 131 case MSG_STACK_TO_HC_HCI_CMD: 132 btHci->sendHciCommand(data); 133 break; 134 case MSG_STACK_TO_HC_HCI_ACL: 135 btHci->sendAclData(data); 136 break; 137 case MSG_STACK_TO_HC_HCI_SCO: 138 btHci->sendScoData(data); 139 break; 140 default: 141 LOG_ERROR(LOG_TAG, "Unknown packet type (%d)", event); 142 break; 143 } 144 } 145 146 int hci_open_firmware_log_file() { 147 if (rename(LOG_PATH, LAST_LOG_PATH) == -1 && errno != ENOENT) { 148 LOG_ERROR(LOG_TAG, "%s unable to rename '%s' to '%s': %s", __func__, 149 LOG_PATH, LAST_LOG_PATH, strerror(errno)); 150 } 151 152 mode_t prevmask = umask(0); 153 int logfile_fd = open(LOG_PATH, O_WRONLY | O_CREAT | O_TRUNC, 154 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); 155 umask(prevmask); 156 if (logfile_fd == INVALID_FD) { 157 LOG_ERROR(LOG_TAG, "%s unable to open '%s': %s", __func__, LOG_PATH, 158 strerror(errno)); 159 } 160 161 return logfile_fd; 162 } 163 164 void hci_close_firmware_log_file(int fd) { 165 if (fd != INVALID_FD) close(fd); 166 } 167 168 void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) { 169 TEMP_FAILURE_RETRY(write(fd, packet->data, packet->len)); 170 } 171