• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
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-btlinux"
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <poll.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <sys/socket.h>
26 
27 #include <utils/Log.h>
28 
29 #include "bluetooth_hci.h"
30 
31 #define BTPROTO_HCI 1
32 
33 #define HCI_CHANNEL_USER 1
34 #define HCI_CHANNEL_CONTROL 3
35 #define HCI_DEV_NONE 0xffff
36 
37 /* reference from <kernel>/include/net/bluetooth/mgmt.h */
38 #define MGMT_OP_INDEX_LIST 0x0003
39 #define MGMT_EV_INDEX_ADDED 0x0004
40 #define MGMT_EV_COMMAND_COMP 0x0001
41 #define MGMT_EV_SIZE_MAX 1024
42 #define WRITE_NO_INTR(fn) \
43   do {                  \
44   } while ((fn) == -1 && errno == EINTR)
45 
46 struct sockaddr_hci {
47     sa_family_t hci_family;
48     unsigned short hci_dev;
49     unsigned short hci_channel;
50 };
51 
52 struct mgmt_pkt {
53     uint16_t opcode;
54     uint16_t index;
55     uint16_t len;
56     uint8_t data[MGMT_EV_SIZE_MAX];
57 } __attribute__((packed));
58 
59 struct mgmt_event_read_index {
60     uint16_t cc_opcode;
61     uint8_t status;
62     uint16_t num_intf;
63     uint16_t index[0];
64   } __attribute__((packed));
65 
66 namespace android {
67 namespace hardware {
68 namespace bluetooth {
69 namespace V1_0 {
70 namespace btlinux {
71 
openBtHci()72 int BluetoothHci::openBtHci() {
73 
74   ALOGI( "%s", __func__);
75 
76   int hci_interface = 0;
77   rfkill_state_ = NULL;
78   rfKill(1);
79 
80   int fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
81   if (fd < 0) {
82     ALOGE( "Bluetooth socket error: %s", strerror(errno));
83     return -1;
84   }
85   bt_soc_fd_ = fd;
86 
87   if (waitHciDev(hci_interface)) {
88     ALOGE( "HCI interface (%d) not found", hci_interface);
89     ::close(fd);
90     return -1;
91   }
92   struct sockaddr_hci addr;
93   memset(&addr, 0, sizeof(addr));
94   addr.hci_family = AF_BLUETOOTH;
95   addr.hci_dev = hci_interface;
96   addr.hci_channel = HCI_CHANNEL_USER;
97   if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
98     ALOGE( "HCI Channel Control: %s", strerror(errno));
99     ::close(fd);
100     return -1;
101   }
102   ALOGI( "HCI device ready");
103   return fd;
104 }
105 
closeBtHci()106 void BluetoothHci::closeBtHci() {
107   if (bt_soc_fd_ != -1) {
108     ::close(bt_soc_fd_);
109     bt_soc_fd_ = -1;
110   }
111   rfKill(0);
112   free(rfkill_state_);
113 }
114 
waitHciDev(int hci_interface)115 int BluetoothHci::waitHciDev(int hci_interface) {
116   struct sockaddr_hci addr;
117   struct pollfd fds[1];
118   struct mgmt_pkt ev;
119   int fd;
120   int ret = 0;
121 
122   ALOGI( "%s", __func__);
123   fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
124   if (fd < 0) {
125     ALOGE( "Bluetooth socket error: %s", strerror(errno));
126     return -1;
127   }
128   memset(&addr, 0, sizeof(addr));
129   addr.hci_family = AF_BLUETOOTH;
130   addr.hci_dev = HCI_DEV_NONE;
131   addr.hci_channel = HCI_CHANNEL_CONTROL;
132   if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
133     ALOGE( "HCI Channel Control: %s", strerror(errno));
134     ret = -1;
135     goto end;
136   }
137 
138   fds[0].fd = fd;
139   fds[0].events = POLLIN;
140 
141   /* Read Controller Index List Command */
142   ev.opcode = MGMT_OP_INDEX_LIST;
143   ev.index = HCI_DEV_NONE;
144   ev.len = 0;
145 
146   ssize_t wrote;
147   WRITE_NO_INTR(wrote = write(fd, &ev, 6));
148   if (wrote != 6) {
149     ALOGE( "Unable to write mgmt command: %s", strerror(errno));
150     ret = -1;
151     goto end;
152   }
153   /* validate mentioned hci interface is present and registered with sock system */
154   while (1) {
155     int n;
156     WRITE_NO_INTR(n = poll(fds, 1, -1));
157     if (n == -1) {
158       ALOGE( "Poll error: %s", strerror(errno));
159       ret = -1;
160       break;
161     } else if (n == 0) {
162       ALOGE( "Timeout, no HCI device detected");
163       ret = -1;
164       break;
165     }
166 
167     if (fds[0].revents & POLLIN) {
168       WRITE_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
169       if (n < 0) {
170         ALOGE( "Error reading control channel: %s",
171                   strerror(errno));
172         ret = -1;
173         break;
174       }
175 
176       if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
177         goto end;
178       } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
179         struct mgmt_event_read_index* cc;
180         int i;
181 
182         cc = (struct mgmt_event_read_index*)ev.data;
183 
184         if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue;
185 
186         for (i = 0; i < cc->num_intf; i++) {
187           if (cc->index[i] == hci_interface) goto end;
188         }
189       }
190     }
191   }
192 
193 end:
194   ::close(fd);
195   return ret;
196 }
197 
findRfKill()198 int BluetoothHci::findRfKill() {
199     char rfkill_type[64];
200     char type[16];
201     int fd, size, i;
202     for(i = 0; rfkill_state_ == NULL; i++)
203     {
204         snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i);
205         if ((fd = open(rfkill_type, O_RDONLY)) < 0)
206         {
207             ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno);
208             return -1;
209         }
210 
211         size = read(fd, &type, sizeof(type));
212         ::close(fd);
213 
214         if ((size >= 9) && !memcmp(type, "bluetooth", 9))
215         {
216             ::asprintf(&rfkill_state_, "/sys/class/rfkill/rfkill%d/state", i);
217             break;
218         }
219     }
220     return 0;
221 }
222 
rfKill(int block)223 int BluetoothHci::rfKill(int block) {
224   int fd;
225   char on = (block)?'1':'0';
226   if (findRfKill() != 0) return 0;
227 
228   fd = open(rfkill_state_, O_WRONLY);
229   if (fd < 0) {
230     ALOGE( "Unable to open /dev/rfkill");
231     return -1;
232   }
233   ssize_t len;
234   WRITE_NO_INTR(len = write(fd, &on, 1));
235   if (len < 0) {
236     ALOGE( "Failed to change rfkill state");
237     ::close(fd);
238     return -1;
239   }
240   ::close(fd);
241   return 0;
242 }
243 
244 class BluetoothDeathRecipient : public hidl_death_recipient {
245  public:
BluetoothDeathRecipient(const sp<IBluetoothHci> hci)246   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
247 
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)248   virtual void serviceDied(
249       uint64_t /*cookie*/,
250       const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
251     ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
252     has_died_ = true;
253     mHci->close();
254   }
255   sp<IBluetoothHci> mHci;
getHasDied() const256   bool getHasDied() const { return has_died_; }
setHasDied(bool has_died)257   void setHasDied(bool has_died) { has_died_ = has_died; }
258 
259  private:
260   bool has_died_;
261 };
262 
BluetoothHci()263 BluetoothHci::BluetoothHci()
264     : death_recipient_(new BluetoothDeathRecipient(this)) {}
265 
initialize(const::android::sp<IBluetoothHciCallbacks> & cb)266 Return<void> BluetoothHci::initialize(
267     const ::android::sp<IBluetoothHciCallbacks>& cb) {
268   ALOGI("BluetoothHci::initialize()");
269   if (cb == nullptr) {
270     ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
271     return Void();
272   }
273 
274   death_recipient_->setHasDied(false);
275   cb->linkToDeath(death_recipient_, 0);
276   int hci_fd = openBtHci();
277   auto hidl_status = cb->initializationComplete(
278           hci_fd > 0 ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
279   if (!hidl_status.isOk()) {
280       ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
281   }
282   hci::H4Protocol* h4_hci = new hci::H4Protocol(
283       hci_fd,
284       [cb](const hidl_vec<uint8_t>& packet) { cb->hciEventReceived(packet); },
285       [cb](const hidl_vec<uint8_t>& packet) { cb->aclDataReceived(packet); },
286       [cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); });
287 
288   fd_watcher_.WatchFdForNonBlockingReads(
289           hci_fd, [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
290   hci_handle_ = h4_hci;
291 
292   unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
293     if (death_recipient->getHasDied())
294       ALOGI("Skipping unlink call, service died.");
295     else
296       cb->unlinkToDeath(death_recipient);
297   };
298 
299   return Void();
300 }
301 
close()302 Return<void> BluetoothHci::close() {
303   ALOGI("BluetoothHci::close()");
304   unlink_cb_(death_recipient_);
305   fd_watcher_.StopWatchingFileDescriptors();
306 
307   if (hci_handle_ != nullptr) {
308     delete hci_handle_;
309     hci_handle_ = nullptr;
310   }
311   closeBtHci();
312   return Void();
313 }
314 
sendHciCommand(const hidl_vec<uint8_t> & command)315 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& command) {
316   sendDataToController(HCI_DATA_TYPE_COMMAND, command);
317   return Void();
318 }
319 
sendAclData(const hidl_vec<uint8_t> & data)320 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& data) {
321   sendDataToController(HCI_DATA_TYPE_ACL, data);
322   return Void();
323 }
324 
sendScoData(const hidl_vec<uint8_t> & data)325 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {
326   sendDataToController(HCI_DATA_TYPE_SCO, data);
327   return Void();
328 }
329 
sendDataToController(const uint8_t type,const hidl_vec<uint8_t> & data)330 void BluetoothHci::sendDataToController(const uint8_t type,
331                                         const hidl_vec<uint8_t>& data) {
332   hci_handle_->Send(type, data.data(), data.size());
333 }
334 
HIDL_FETCH_IBluetoothHci(const char *)335 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
336   return new BluetoothHci();
337 }
338 
339 }  // namespace btlinux
340 }  // namespace V1_0
341 }  // namespace bluetooth
342 }  // namespace hardware
343 }  // namespace android
344