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