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: 55 BluetoothHciCallbacks() { 56 buffer_allocator = buffer_allocator_get_interface(); 57 } 58 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 73 Return<void> initializationComplete(Status status) { 74 CHECK(status == Status::SUCCESS); 75 initialization_complete(); 76 return Void(); 77 } 78 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 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 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 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 116 void hci_close() { 117 btHci->close(); 118 btHci = nullptr; 119 } 120 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 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 160 void hci_close_firmware_log_file(int fd) { 161 if (fd != INVALID_FD) close(fd); 162 } 163 164 void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) { 165 TEMP_FAILURE_RETRY(write(fd, packet->data, packet->len)); 166 } 167