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 "hci/include/bt_vendor_lib.h"
33 #include "osi/include/log.h"
34 #include "osi/include/properties.h"
37 #define HCI_CHANNEL_USER 1
38 #define HCI_CHANNEL_CONTROL 3
39 #define HCI_DEV_NONE 0xffff
41 #define RFKILL_TYPE_BLUETOOTH 2
42 #define RFKILL_OP_CHANGE_ALL 3
44 #define MGMT_OP_INDEX_LIST 0x0003
45 #define MGMT_EV_INDEX_ADDED 0x0004
46 #define MGMT_EV_COMMAND_COMP 0x0001
47 #define MGMT_EV_SIZE_MAX 1024
48 #define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */
50 #define IOCTL_HCIDEVDOWN _IOW('H', 202, int)
53 sa_family_t hci_family;
54 unsigned short hci_dev;
55 unsigned short hci_channel;
63 } __attribute__((packed));
69 uint8_t data[MGMT_EV_SIZE_MAX];
70 } __attribute__((packed));
72 struct mgmt_event_read_index {
77 } __attribute__((packed));
79 static const bt_vendor_callbacks_t *bt_vendor_callbacks;
80 static unsigned char bt_vendor_local_bdaddr[6];
81 static int bt_vendor_fd = -1;
82 static int hci_interface;
84 static int bt_hwcfg_en;
86 static int bt_vendor_init(const bt_vendor_callbacks_t *p_cb,
87 unsigned char *local_bdaddr)
89 char prop_value[PROPERTY_VALUE_MAX];
91 LOG_INFO(LOG_TAG, "%s", __func__);
94 LOG_ERROR(LOG_TAG, "init failed with no user callbacks!");
98 bt_vendor_callbacks = p_cb;
100 memcpy(bt_vendor_local_bdaddr, local_bdaddr,
101 sizeof(bt_vendor_local_bdaddr));
103 osi_property_get("bluetooth.interface", prop_value, "0");
106 if (memcmp(prop_value, "hci", 3))
107 hci_interface = strtol(prop_value, NULL, 10);
109 hci_interface = strtol(prop_value + 3, NULL, 10);
113 LOG_INFO(LOG_TAG, "Using interface hci%d", hci_interface);
115 osi_property_get("bluetooth.rfkill", prop_value, "0");
117 rfkill_en = atoi(prop_value);
119 LOG_INFO(LOG_TAG, "RFKILL enabled");
121 bt_hwcfg_en = osi_property_get("bluetooth.hwcfg",
122 prop_value, NULL) > 0 ? 1 : 0;
124 LOG_INFO(LOG_TAG, "HWCFG enabled");
129 static int bt_vendor_hw_cfg(int stop)
135 if (osi_property_set("bluetooth.hwcfg", "stop") < 0) {
136 LOG_ERROR(LOG_TAG, "%s cannot stop btcfg service via prop", __func__);
140 if (osi_property_set("bluetooth.hwcfg", "start") < 0) {
141 LOG_ERROR(LOG_TAG, "%s cannot start btcfg service via prop", __func__);
148 static int bt_vendor_wait_hcidev(void)
150 struct sockaddr_hci addr;
151 struct pollfd fds[1];
156 LOG_INFO(LOG_TAG, "%s", __func__);
158 fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
160 LOG_ERROR(LOG_TAG, "Bluetooth socket error: %s", strerror(errno));
164 memset(&addr, 0, sizeof(addr));
165 addr.hci_family = AF_BLUETOOTH;
166 addr.hci_dev = HCI_DEV_NONE;
167 addr.hci_channel = HCI_CHANNEL_CONTROL;
169 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
170 LOG_ERROR(LOG_TAG, "HCI Channel Control: %s", strerror(errno));
176 fds[0].events = POLLIN;
178 /* Read Controller Index List Command */
179 ev.opcode = MGMT_OP_INDEX_LIST;
180 ev.index = HCI_DEV_NONE;
182 if (write(fd, &ev, 6) != 6) {
183 LOG_ERROR(LOG_TAG, "Unable to write mgmt command: %s", strerror(errno));
189 int n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT);
191 LOG_ERROR(LOG_TAG, "Poll error: %s", strerror(errno));
195 LOG_ERROR(LOG_TAG, "Timeout, no HCI device detected");
200 if (fds[0].revents & POLLIN) {
201 n = read(fd, &ev, sizeof(struct mgmt_pkt));
204 "Error reading control channel");
209 if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
211 } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
212 struct mgmt_event_read_index *cc;
215 cc = (struct mgmt_event_read_index *)ev.data;
217 if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0)
220 for (i = 0; i < cc->num_intf; i++) {
221 if (cc->index[i] == hci_interface)
233 static int bt_vendor_open(void *param)
235 int (*fd_array)[] = (int (*)[]) param;
238 LOG_INFO(LOG_TAG, "%s", __func__);
240 fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
242 LOG_ERROR(LOG_TAG, "socket create error %s", strerror(errno));
246 (*fd_array)[CH_CMD] = fd;
247 (*fd_array)[CH_EVT] = fd;
248 (*fd_array)[CH_ACL_OUT] = fd;
249 (*fd_array)[CH_ACL_IN] = fd;
253 LOG_INFO(LOG_TAG, "%s returning %d", __func__, bt_vendor_fd);
258 static int bt_vendor_close(void *param)
262 LOG_INFO(LOG_TAG, "%s", __func__);
264 if (bt_vendor_fd != -1) {
272 static int bt_vendor_rfkill(int block)
274 struct rfkill_event event;
277 LOG_INFO(LOG_TAG, "%s", __func__);
279 fd = open("/dev/rfkill", O_WRONLY);
281 LOG_ERROR(LOG_TAG, "Unable to open /dev/rfkill");
285 memset(&event, 0, sizeof(struct rfkill_event));
286 event.op = RFKILL_OP_CHANGE_ALL;
287 event.type = RFKILL_TYPE_BLUETOOTH;
291 len = write(fd, &event, sizeof(event));
293 LOG_ERROR(LOG_TAG, "Failed to change rfkill state");
302 /* TODO: fw config should thread the device waiting and return immedialty */
303 static void bt_vendor_fw_cfg(void)
305 struct sockaddr_hci addr;
306 int fd = bt_vendor_fd;
308 LOG_INFO(LOG_TAG, "%s", __func__);
311 LOG_ERROR(LOG_TAG, "bt_vendor_fd: %s", strerror(EBADF));
315 memset(&addr, 0, sizeof(addr));
316 addr.hci_family = AF_BLUETOOTH;
317 addr.hci_dev = hci_interface;
318 addr.hci_channel = HCI_CHANNEL_USER;
320 if (bt_vendor_wait_hcidev()) {
321 LOG_ERROR(LOG_TAG, "HCI interface (%d) not found", hci_interface);
325 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
326 LOG_ERROR(LOG_TAG, "socket bind error %s", strerror(errno));
330 LOG_INFO(LOG_TAG, "HCI device ready");
332 bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
337 LOG_ERROR(LOG_TAG, "Hardware Config Error");
338 bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
341 static int bt_vendor_op(bt_vendor_opcode_t opcode, void *param)
345 LOG_INFO(LOG_TAG, "%s op %d", __func__, opcode);
348 case BT_VND_OP_POWER_CTRL:
349 if (!rfkill_en || !param)
352 if (*((int *)param) == BT_VND_PWR_ON) {
353 retval = bt_vendor_rfkill(0);
355 retval = bt_vendor_hw_cfg(0);
357 retval = bt_vendor_hw_cfg(1);
359 retval = bt_vendor_rfkill(1);
364 case BT_VND_OP_FW_CFG:
368 case BT_VND_OP_SCO_CFG:
369 bt_vendor_callbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
372 case BT_VND_OP_USERIAL_OPEN:
373 retval = bt_vendor_open(param);
376 case BT_VND_OP_USERIAL_CLOSE:
377 retval = bt_vendor_close(param);
380 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
381 *((uint32_t *)param) = 3000;
385 case BT_VND_OP_LPM_SET_MODE:
386 bt_vendor_callbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
389 case BT_VND_OP_LPM_WAKE_SET_STATE:
392 case BT_VND_OP_SET_AUDIO_STATE:
393 bt_vendor_callbacks->audio_state_cb(BT_VND_OP_RESULT_SUCCESS);
396 case BT_VND_OP_EPILOG:
397 bt_vendor_callbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
401 LOG_INFO(LOG_TAG, "%s op %d retval %d", __func__, opcode, retval);
406 static void bt_vendor_cleanup(void)
408 LOG_INFO(LOG_TAG, "%s", __func__);
410 bt_vendor_callbacks = NULL;
413 EXPORT_SYMBOL const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
414 sizeof(bt_vendor_interface_t),