1 /**********************************************************************
3 * Copyright (C) 2015 Intel Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 **********************************************************************/
20 #define LOG_TAG "bt_vendor"
29 #include <sys/socket.h>
30 #include <sys/ioctl.h>
32 #include <cutils/properties.h>
34 #include "hci/include/bt_vendor_lib.h"
35 #include "osi/include/log.h"
38 #define HCI_CHANNEL_USER 1
39 #define HCI_CHANNEL_CONTROL 3
40 #define HCI_DEV_NONE 0xffff
42 #define RFKILL_TYPE_BLUETOOTH 2
43 #define RFKILL_OP_CHANGE_ALL 3
45 #define MGMT_OP_INDEX_LIST 0x0003
46 #define MGMT_EV_INDEX_ADDED 0x0004
47 #define MGMT_EV_COMMAND_COMP 0x0001
48 #define MGMT_EV_SIZE_MAX 1024
49 #define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */
51 #define IOCTL_HCIDEVDOWN _IOW('H', 202, int)
54 sa_family_t hci_family;
55 unsigned short hci_dev;
56 unsigned short hci_channel;
64 } __attribute__((packed));
70 uint8_t data[MGMT_EV_SIZE_MAX];
71 } __attribute__((packed));
73 struct mgmt_event_read_index {
78 } __attribute__((packed));
80 static const bt_vendor_callbacks_t *bt_vendor_callbacks;
81 static unsigned char bt_vendor_local_bdaddr[6];
82 static int bt_vendor_fd = -1;
83 static int hci_interface;
85 static int bt_hwcfg_en;
87 static int bt_vendor_init(const bt_vendor_callbacks_t *p_cb,
88 unsigned char *local_bdaddr)
90 char prop_value[PROPERTY_VALUE_MAX];
92 LOG_INFO(LOG_TAG, "%s", __func__);
95 LOG_ERROR(LOG_TAG, "init failed with no user callbacks!");
99 bt_vendor_callbacks = p_cb;
101 memcpy(bt_vendor_local_bdaddr, local_bdaddr,
102 sizeof(bt_vendor_local_bdaddr));
104 property_get("bluetooth.interface", prop_value, "0");
107 if (memcmp(prop_value, "hci", 3))
108 hci_interface = strtol(prop_value, NULL, 10);
110 hci_interface = strtol(prop_value + 3, NULL, 10);
114 LOG_INFO(LOG_TAG, "Using interface hci%d", hci_interface);
116 property_get("bluetooth.rfkill", prop_value, "0");
118 rfkill_en = atoi(prop_value);
120 LOG_INFO(LOG_TAG, "RFKILL enabled");
122 bt_hwcfg_en = property_get("bluetooth.hwcfg",
123 prop_value, NULL) > 0 ? 1 : 0;
125 LOG_INFO(LOG_TAG, "HWCFG enabled");
130 static int bt_vendor_hw_cfg(int stop)
136 if (property_set("bluetooth.hwcfg", "stop") < 0) {
137 LOG_ERROR(LOG_TAG, "%s cannot stop btcfg service via prop", __func__);
141 if (property_set("bluetooth.hwcfg", "start") < 0) {
142 LOG_ERROR(LOG_TAG, "%s cannot start btcfg service via prop", __func__);
149 static int bt_vendor_wait_hcidev(void)
151 struct sockaddr_hci addr;
152 struct pollfd fds[1];
157 LOG_INFO(LOG_TAG, "%s", __func__);
159 fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
161 LOG_ERROR(LOG_TAG, "Bluetooth socket error: %s", strerror(errno));
165 memset(&addr, 0, sizeof(addr));
166 addr.hci_family = AF_BLUETOOTH;
167 addr.hci_dev = HCI_DEV_NONE;
168 addr.hci_channel = HCI_CHANNEL_CONTROL;
170 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
171 LOG_ERROR(LOG_TAG, "HCI Channel Control: %s", strerror(errno));
177 fds[0].events = POLLIN;
179 /* Read Controller Index List Command */
180 ev.opcode = MGMT_OP_INDEX_LIST;
181 ev.index = HCI_DEV_NONE;
183 if (write(fd, &ev, 6) != 6) {
184 LOG_ERROR(LOG_TAG, "Unable to write mgmt command: %s", strerror(errno));
190 int n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT);
192 LOG_ERROR(LOG_TAG, "Poll error: %s", strerror(errno));
196 LOG_ERROR(LOG_TAG, "Timeout, no HCI device detected");
201 if (fds[0].revents & POLLIN) {
202 n = read(fd, &ev, sizeof(struct mgmt_pkt));
205 "Error reading control channel");
210 if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
212 } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
213 struct mgmt_event_read_index *cc;
216 cc = (struct mgmt_event_read_index *)ev.data;
218 if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0)
221 for (i = 0; i < cc->num_intf; i++) {
222 if (cc->index[i] == hci_interface)
234 static int bt_vendor_open(void *param)
236 int (*fd_array)[] = (int (*)[]) param;
239 LOG_INFO(LOG_TAG, "%s", __func__);
241 fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
243 LOG_ERROR(LOG_TAG, "socket create error %s", strerror(errno));
247 (*fd_array)[CH_CMD] = fd;
248 (*fd_array)[CH_EVT] = fd;
249 (*fd_array)[CH_ACL_OUT] = fd;
250 (*fd_array)[CH_ACL_IN] = fd;
254 LOG_INFO(LOG_TAG, "%s returning %d", __func__, bt_vendor_fd);
259 static int bt_vendor_close(void *param)
263 LOG_INFO(LOG_TAG, "%s", __func__);
265 if (bt_vendor_fd != -1) {
273 static int bt_vendor_rfkill(int block)
275 struct rfkill_event event;
278 LOG_INFO(LOG_TAG, "%s", __func__);
280 fd = open("/dev/rfkill", O_WRONLY);
282 LOG_ERROR(LOG_TAG, "Unable to open /dev/rfkill");
286 memset(&event, 0, sizeof(struct rfkill_event));
287 event.op = RFKILL_OP_CHANGE_ALL;
288 event.type = RFKILL_TYPE_BLUETOOTH;
292 len = write(fd, &event, sizeof(event));
294 LOG_ERROR(LOG_TAG, "Failed to change rfkill state");
303 /* TODO: fw config should thread the device waiting and return immedialty */
304 static void bt_vendor_fw_cfg(void)
306 struct sockaddr_hci addr;
307 int fd = bt_vendor_fd;
309 LOG_INFO(LOG_TAG, "%s", __func__);
312 LOG_ERROR(LOG_TAG, "bt_vendor_fd: %s", strerror(EBADF));
316 memset(&addr, 0, sizeof(addr));
317 addr.hci_family = AF_BLUETOOTH;
318 addr.hci_dev = hci_interface;
319 addr.hci_channel = HCI_CHANNEL_USER;
321 if (bt_vendor_wait_hcidev()) {
322 LOG_ERROR(LOG_TAG, "HCI interface (%d) not found", hci_interface);
326 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
327 LOG_ERROR(LOG_TAG, "socket bind error %s", strerror(errno));
331 LOG_INFO(LOG_TAG, "HCI device ready");
333 bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
338 LOG_ERROR(LOG_TAG, "Hardware Config Error");
339 bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
342 static int bt_vendor_op(bt_vendor_opcode_t opcode, void *param)
346 LOG_INFO(LOG_TAG, "%s op %d", __func__, opcode);
349 case BT_VND_OP_POWER_CTRL:
350 if (!rfkill_en || !param)
353 if (*((int *)param) == BT_VND_PWR_ON) {
354 retval = bt_vendor_rfkill(0);
356 retval = bt_vendor_hw_cfg(0);
358 retval = bt_vendor_hw_cfg(1);
360 retval = bt_vendor_rfkill(1);
365 case BT_VND_OP_FW_CFG:
369 case BT_VND_OP_SCO_CFG:
370 bt_vendor_callbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
373 case BT_VND_OP_USERIAL_OPEN:
374 retval = bt_vendor_open(param);
377 case BT_VND_OP_USERIAL_CLOSE:
378 retval = bt_vendor_close(param);
381 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
382 *((uint32_t *)param) = 3000;
386 case BT_VND_OP_LPM_SET_MODE:
387 bt_vendor_callbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
390 case BT_VND_OP_LPM_WAKE_SET_STATE:
393 case BT_VND_OP_SET_AUDIO_STATE:
394 bt_vendor_callbacks->audio_state_cb(BT_VND_OP_RESULT_SUCCESS);
397 case BT_VND_OP_EPILOG:
398 bt_vendor_callbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
402 LOG_INFO(LOG_TAG, "%s op %d retval %d", __func__, opcode, retval);
407 static void bt_vendor_cleanup(void)
409 LOG_INFO(LOG_TAG, "%s", __func__);
411 bt_vendor_callbacks = NULL;
414 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
415 sizeof(bt_vendor_interface_t),