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;
184 OSI_NO_INTR(wrote = write(fd, &ev, 6));
186 LOG_ERROR(LOG_TAG, "Unable to write mgmt command: %s", strerror(errno));
193 OSI_NO_INTR(n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT));
195 LOG_ERROR(LOG_TAG, "Poll error: %s", strerror(errno));
199 LOG_ERROR(LOG_TAG, "Timeout, no HCI device detected");
204 if (fds[0].revents & POLLIN) {
205 OSI_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
207 LOG_ERROR(LOG_TAG, "Error reading control channel: %s",
213 if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
215 } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
216 struct mgmt_event_read_index *cc;
219 cc = (struct mgmt_event_read_index *)ev.data;
221 if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0)
224 for (i = 0; i < cc->num_intf; i++) {
225 if (cc->index[i] == hci_interface)
237 static int bt_vendor_open(void *param)
239 int (*fd_array)[] = (int (*)[]) param;
242 LOG_INFO(LOG_TAG, "%s", __func__);
244 fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
246 LOG_ERROR(LOG_TAG, "socket create error %s", strerror(errno));
250 (*fd_array)[CH_CMD] = fd;
251 (*fd_array)[CH_EVT] = fd;
252 (*fd_array)[CH_ACL_OUT] = fd;
253 (*fd_array)[CH_ACL_IN] = fd;
257 LOG_INFO(LOG_TAG, "%s returning %d", __func__, bt_vendor_fd);
262 static int bt_vendor_close(void *param)
266 LOG_INFO(LOG_TAG, "%s", __func__);
268 if (bt_vendor_fd != -1) {
276 static int bt_vendor_rfkill(int block)
278 struct rfkill_event event;
281 LOG_INFO(LOG_TAG, "%s", __func__);
283 fd = open("/dev/rfkill", O_WRONLY);
285 LOG_ERROR(LOG_TAG, "Unable to open /dev/rfkill");
289 memset(&event, 0, sizeof(struct rfkill_event));
290 event.op = RFKILL_OP_CHANGE_ALL;
291 event.type = RFKILL_TYPE_BLUETOOTH;
296 OSI_NO_INTR(len = write(fd, &event, sizeof(event)));
298 LOG_ERROR(LOG_TAG, "Failed to change rfkill state");
307 /* TODO: fw config should thread the device waiting and return immedialty */
308 static void bt_vendor_fw_cfg(void)
310 struct sockaddr_hci addr;
311 int fd = bt_vendor_fd;
313 LOG_INFO(LOG_TAG, "%s", __func__);
316 LOG_ERROR(LOG_TAG, "bt_vendor_fd: %s", strerror(EBADF));
320 memset(&addr, 0, sizeof(addr));
321 addr.hci_family = AF_BLUETOOTH;
322 addr.hci_dev = hci_interface;
323 addr.hci_channel = HCI_CHANNEL_USER;
325 if (bt_vendor_wait_hcidev()) {
326 LOG_ERROR(LOG_TAG, "HCI interface (%d) not found", hci_interface);
330 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
331 LOG_ERROR(LOG_TAG, "socket bind error %s", strerror(errno));
335 LOG_INFO(LOG_TAG, "HCI device ready");
337 bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
342 LOG_ERROR(LOG_TAG, "Hardware Config Error");
343 bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
346 static int bt_vendor_op(bt_vendor_opcode_t opcode, void *param)
350 LOG_INFO(LOG_TAG, "%s op %d", __func__, opcode);
353 case BT_VND_OP_POWER_CTRL:
354 if (!rfkill_en || !param)
357 if (*((int *)param) == BT_VND_PWR_ON) {
358 retval = bt_vendor_rfkill(0);
360 retval = bt_vendor_hw_cfg(0);
362 retval = bt_vendor_hw_cfg(1);
364 retval = bt_vendor_rfkill(1);
369 case BT_VND_OP_FW_CFG:
373 case BT_VND_OP_SCO_CFG:
374 bt_vendor_callbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
377 case BT_VND_OP_USERIAL_OPEN:
378 retval = bt_vendor_open(param);
381 case BT_VND_OP_USERIAL_CLOSE:
382 retval = bt_vendor_close(param);
385 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
386 *((uint32_t *)param) = 3000;
390 case BT_VND_OP_LPM_SET_MODE:
391 bt_vendor_callbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
394 case BT_VND_OP_LPM_WAKE_SET_STATE:
397 case BT_VND_OP_SET_AUDIO_STATE:
398 bt_vendor_callbacks->audio_state_cb(BT_VND_OP_RESULT_SUCCESS);
401 case BT_VND_OP_EPILOG:
402 bt_vendor_callbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
406 LOG_INFO(LOG_TAG, "%s op %d retval %d", __func__, opcode, retval);
411 static void bt_vendor_cleanup(void)
413 LOG_INFO(LOG_TAG, "%s", __func__);
415 bt_vendor_callbacks = NULL;
418 EXPORT_SYMBOL const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
419 sizeof(bt_vendor_interface_t),