3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
38 #include <sys/signalfd.h>
40 #include <sys/prctl.h>
41 #include <sys/capability.h>
46 #include "lib/bluetooth.h"
51 #include "src/shared/util.h"
53 #include "ipc-common.h"
55 #include "bluetooth.h"
62 #include "handsfree.h"
65 #include "handsfree-client.h"
66 #include "map-client.h"
69 #define DEFAULT_VENDOR "BlueZ"
70 #define DEFAULT_MODEL "BlueZ for Android"
71 #define DEFAULT_NAME "BlueZ for Android"
73 #define STARTUP_GRACE_SECONDS 5
74 #define SHUTDOWN_GRACE_SECONDS 5
76 static char *config_vendor = NULL;
77 static char *config_model = NULL;
78 static char *config_name = NULL;
79 static char *config_serial = NULL;
80 static char *config_fw_rev = NULL;
81 static char *config_hw_rev = NULL;
82 static uint64_t config_system_id = 0;
83 static uint16_t config_pnp_source = 0x0002; /* USB */
84 static uint16_t config_pnp_vendor = 0x1d6b; /* Linux Foundation */
85 static uint16_t config_pnp_product = 0x0247; /* BlueZ for Android */
86 static uint16_t config_pnp_version = 0x0000;
88 static guint quit_timeout = 0;
90 static bdaddr_t adapter_bdaddr;
92 static GMainLoop *event_loop;
94 static struct ipc *hal_ipc = NULL;
96 static bool services[HAL_SERVICE_ID_MAX + 1] = { false };
98 const char *bt_config_get_vendor(void)
101 return config_vendor;
103 return DEFAULT_VENDOR;
106 const char *bt_config_get_name(void)
114 const char *bt_config_get_model(void)
119 return DEFAULT_MODEL;
122 const char *bt_config_get_serial(void)
124 return config_serial;
127 const char *bt_config_get_fw_rev(void)
129 return config_fw_rev;
132 const char *bt_config_get_hw_rev(void)
134 return config_hw_rev;
137 uint64_t bt_config_get_system_id(void)
139 return config_system_id;
142 uint16_t bt_config_get_pnp_source(void)
144 return config_pnp_source;
147 uint16_t bt_config_get_pnp_vendor(void)
149 return config_pnp_vendor;
152 uint16_t bt_config_get_pnp_product(void)
154 return config_pnp_product;
157 uint16_t bt_config_get_pnp_version(void)
159 return config_pnp_version;
162 static void service_register(const void *buf, uint16_t len)
164 const struct hal_cmd_register_module *m = buf;
167 if (m->service_id > HAL_SERVICE_ID_MAX || services[m->service_id]) {
168 status = HAL_STATUS_FAILED;
172 switch (m->service_id) {
173 case HAL_SERVICE_ID_BLUETOOTH:
174 if (!bt_bluetooth_register(hal_ipc, m->mode)) {
175 status = HAL_STATUS_FAILED;
180 case HAL_SERVICE_ID_SOCKET:
181 bt_socket_register(hal_ipc, &adapter_bdaddr, m->mode);
184 case HAL_SERVICE_ID_HIDHOST:
185 if (!bt_hid_register(hal_ipc, &adapter_bdaddr, m->mode)) {
186 status = HAL_STATUS_FAILED;
191 case HAL_SERVICE_ID_A2DP:
192 if (!bt_a2dp_register(hal_ipc, &adapter_bdaddr, m->mode)) {
193 status = HAL_STATUS_FAILED;
198 case HAL_SERVICE_ID_PAN:
199 if (!bt_pan_register(hal_ipc, &adapter_bdaddr, m->mode)) {
200 status = HAL_STATUS_FAILED;
205 case HAL_SERVICE_ID_AVRCP:
206 if (!bt_avrcp_register(hal_ipc, &adapter_bdaddr, m->mode)) {
207 status = HAL_STATUS_FAILED;
212 case HAL_SERVICE_ID_HANDSFREE:
213 if (!bt_handsfree_register(hal_ipc, &adapter_bdaddr, m->mode,
215 status = HAL_STATUS_FAILED;
220 case HAL_SERVICE_ID_GATT:
221 if (!bt_gatt_register(hal_ipc, &adapter_bdaddr)) {
222 status = HAL_STATUS_FAILED;
227 case HAL_SERVICE_ID_HEALTH:
228 if (!bt_health_register(hal_ipc, &adapter_bdaddr, m->mode)) {
229 status = HAL_STATUS_FAILED;
234 case HAL_SERVICE_ID_HANDSFREE_CLIENT:
235 if (!bt_hf_client_register(hal_ipc, &adapter_bdaddr)) {
236 status = HAL_STATUS_FAILED;
241 case HAL_SERVICE_ID_MAP_CLIENT:
242 if (!bt_map_client_register(hal_ipc, &adapter_bdaddr,
244 status = HAL_STATUS_FAILED;
250 DBG("service %u not supported", m->service_id);
251 status = HAL_STATUS_FAILED;
255 services[m->service_id] = true;
257 status = HAL_STATUS_SUCCESS;
259 info("Service ID=%u registered", m->service_id);
262 ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
266 static bool unregister_service(uint8_t id)
268 if (id > HAL_SERVICE_ID_MAX || !services[id])
272 case HAL_SERVICE_ID_BLUETOOTH:
273 bt_bluetooth_unregister();
275 case HAL_SERVICE_ID_SOCKET:
276 bt_socket_unregister();
278 case HAL_SERVICE_ID_HIDHOST:
281 case HAL_SERVICE_ID_A2DP:
282 bt_a2dp_unregister();
284 case HAL_SERVICE_ID_PAN:
287 case HAL_SERVICE_ID_AVRCP:
288 bt_avrcp_unregister();
290 case HAL_SERVICE_ID_HANDSFREE:
291 bt_handsfree_unregister();
293 case HAL_SERVICE_ID_GATT:
294 bt_gatt_unregister();
296 case HAL_SERVICE_ID_HEALTH:
297 bt_health_unregister();
299 case HAL_SERVICE_ID_HANDSFREE_CLIENT:
300 bt_hf_client_unregister();
302 case HAL_SERVICE_ID_MAP_CLIENT:
303 bt_map_client_unregister();
306 DBG("service %u not supported", id);
310 services[id] = false;
315 static void service_unregister(const void *buf, uint16_t len)
317 const struct hal_cmd_unregister_module *m = buf;
320 if (!unregister_service(m->service_id)) {
321 status = HAL_STATUS_FAILED;
325 status = HAL_STATUS_SUCCESS;
327 info("Service ID=%u unregistered", m->service_id);
330 ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
334 static char *get_prop(char *prop, uint16_t len, const uint8_t *val)
336 /* TODO should fail if set more than once ? */
343 memcpy(prop, val, len);
344 prop[len - 1] = '\0';
349 static void parse_pnp_id(uint16_t len, const uint8_t *val)
352 uint16_t vendor, product, version , source;
355 /* version is optional */
356 version = config_pnp_version;
358 pnp = get_prop(NULL, len, val);
362 DBG("pnp_id %s", pnp);
364 result = sscanf(pnp, "bluetooth:%4hx:%4hx:%4hx",
365 &vendor, &product, &version);
366 if (result != EOF && result >= 2) {
371 result = sscanf(pnp, "usb:%4hx:%4hx:%4hx", &vendor, &product, &version);
372 if (result != EOF && result >= 2) {
382 config_pnp_source = source;
383 config_pnp_vendor = vendor;
384 config_pnp_product = product;
385 config_pnp_version = version;
388 static void parse_system_id(uint16_t len, const uint8_t *val)
393 id = get_prop(NULL, len, val);
397 res = strtoull(id, NULL, 16);
398 if (res == ULLONG_MAX && errno == ERANGE)
401 config_system_id = res;
406 static void configuration(const void *buf, uint16_t len)
408 const struct hal_cmd_configuration *cmd = buf;
409 const struct hal_config_prop *prop;
415 for (i = 0; i < cmd->num; i++) {
418 if (len < sizeof(*prop) || len < sizeof(*prop) + prop->len) {
419 error("Invalid configuration command, terminating");
424 switch (prop->type) {
425 case HAL_CONFIG_VENDOR:
426 config_vendor = get_prop(config_vendor, prop->len,
428 DBG("vendor %s", config_vendor);
430 case HAL_CONFIG_NAME:
431 config_name = get_prop(config_name, prop->len,
433 DBG("name %s", config_name);
435 case HAL_CONFIG_MODEL:
436 config_model = get_prop(config_model, prop->len,
438 DBG("model %s", config_model);
440 case HAL_CONFIG_SERIAL_NUMBER:
441 config_serial = get_prop(config_serial, prop->len,
443 DBG("serial %s", config_serial);
445 case HAL_CONFIG_SYSTEM_ID:
446 parse_system_id(prop->len, prop->val);
448 case HAL_CONFIG_PNP_ID:
449 parse_pnp_id(prop->len, prop->val);
451 case HAL_CONFIG_FW_REV:
452 config_fw_rev = get_prop(config_fw_rev, prop->len,
454 DBG("fw_rev %s", config_fw_rev);
456 case HAL_CONFIG_HW_REV:
457 config_hw_rev = get_prop(config_hw_rev, prop->len,
459 DBG("hw_rev %s", config_hw_rev);
462 error("Invalid configuration option (%u), terminating",
468 buf += sizeof(*prop) + prop->len;
469 len -= sizeof(*prop) + prop->len;
472 ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_CONFIGURATION,
476 static const struct ipc_handler cmd_handlers[] = {
477 /* HAL_OP_REGISTER_MODULE */
478 { service_register, false, sizeof(struct hal_cmd_register_module) },
479 /* HAL_OP_UNREGISTER_MODULE */
480 { service_unregister, false, sizeof(struct hal_cmd_unregister_module) },
481 /* HAL_OP_CONFIGURATION */
482 { configuration, true, sizeof(struct hal_cmd_configuration) },
485 static void bluetooth_stopped(void)
487 g_main_loop_quit(event_loop);
490 static gboolean quit_eventloop(gpointer user_data)
492 g_main_loop_quit(event_loop);
499 static void stop_bluetooth(void)
501 static bool __stop = false;
508 if (!bt_bluetooth_stop(bluetooth_stopped)) {
509 g_main_loop_quit(event_loop);
513 quit_timeout = g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS,
514 quit_eventloop, NULL);
517 static void ipc_disconnected(void *data)
522 static void adapter_ready(int err, const bdaddr_t *addr)
525 error("Adapter initialization failed: %s", strerror(-err));
529 bacpy(&adapter_bdaddr, addr);
531 if (quit_timeout > 0) {
532 g_source_remove(quit_timeout);
536 info("Adapter initialized");
538 hal_ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH),
539 HAL_SERVICE_ID_MAX, true,
540 ipc_disconnected, NULL);
542 error("Failed to initialize IPC");
546 ipc_register(hal_ipc, HAL_SERVICE_ID_CORE, cmd_handlers,
547 G_N_ELEMENTS(cmd_handlers));
550 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
553 static bool __terminated = false;
554 struct signalfd_siginfo si;
558 if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
561 fd = g_io_channel_unix_get_fd(channel);
563 result = read(fd, &si, sizeof(si));
564 if (result != sizeof(si))
567 switch (si.ssi_signo) {
582 static guint setup_signalfd(void)
590 sigaddset(&mask, SIGINT);
591 sigaddset(&mask, SIGTERM);
593 if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
594 perror("Failed to set signal mask");
598 fd = signalfd(-1, &mask, 0);
600 perror("Failed to create signal descriptor");
604 channel = g_io_channel_unix_new(fd);
606 g_io_channel_set_close_on_unref(channel, TRUE);
607 g_io_channel_set_encoding(channel, NULL, NULL);
608 g_io_channel_set_buffered(channel, FALSE);
610 source = g_io_add_watch(channel,
611 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
612 signal_handler, NULL);
614 g_io_channel_unref(channel);
619 static gboolean option_version = FALSE;
620 static gint option_index = -1;
621 static gboolean option_dbg = FALSE;
622 static gboolean option_mgmt_dbg = FALSE;
624 static GOptionEntry options[] = {
625 { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
626 "Show version information and exit", NULL },
627 { "index", 'i', 0, G_OPTION_ARG_INT, &option_index,
628 "Use specified controller", "INDEX"},
629 { "debug", 'd', 0, G_OPTION_ARG_NONE, &option_dbg,
630 "Enable debug logs", NULL},
631 { "mgmt-debug", 0, 0, G_OPTION_ARG_NONE, &option_mgmt_dbg,
632 "Enable mgmt debug logs", NULL},
637 static void cleanup_services(void)
643 for (i = HAL_SERVICE_ID_MAX; i > HAL_SERVICE_ID_CORE; i--)
644 unregister_service(i);
647 static bool set_capabilities(void)
650 struct __user_cap_header_struct header;
651 struct __user_cap_data_struct cap;
653 header.version = _LINUX_CAPABILITY_VERSION;
657 * CAP_NET_ADMIN: Allow use of MGMT interface
658 * CAP_NET_BIND_SERVICE: Allow use of privileged PSM
659 * CAP_NET_RAW: Allow use of bnep ioctl calls
661 cap.effective = cap.permitted =
662 CAP_TO_MASK(CAP_NET_RAW) |
663 CAP_TO_MASK(CAP_NET_ADMIN) |
664 CAP_TO_MASK(CAP_NET_BIND_SERVICE);
667 /* don't clear capabilities when dropping root */
668 if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
669 error("%s: prctl(): %s", __func__, strerror(errno));
673 /* Android bluetooth user UID=1002 */
674 if (setuid(1002) < 0) {
675 error("%s: setuid(): %s", __func__, strerror(errno));
679 /* TODO: Move to cap_set_proc once bionic support it */
680 if (capset(&header, &cap) < 0) {
681 error("%s: capset(): %s", __func__, strerror(errno));
685 /* TODO: Move to cap_get_proc once bionic support it */
686 if (capget(&header, &cap) < 0) {
687 error("%s: capget(): %s", __func__, strerror(errno));
691 DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
692 cap.permitted, cap.inheritable);
698 static void set_version(void)
700 uint8_t major, minor;
702 if (sscanf(VERSION, "%hhu.%hhu", &major, &minor) != 2)
705 config_pnp_version = major << 8 | minor;
708 int main(int argc, char *argv[])
710 GOptionContext *context;
716 context = g_option_context_new(NULL);
717 g_option_context_add_main_entries(context, options, NULL);
719 if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) {
721 g_printerr("%s\n", err->message);
724 g_printerr("An unknown error occurred\n");
729 g_option_context_free(context);
731 if (option_version == TRUE) {
732 printf("%s\n", VERSION);
736 signal = setup_signalfd();
740 if (option_dbg || option_mgmt_dbg)
741 __btd_log_init("*", 0);
743 __btd_log_init(NULL, 0);
745 if (!set_capabilities()) {
747 g_source_remove(signal);
751 quit_timeout = g_timeout_add_seconds(STARTUP_GRACE_SECONDS,
752 quit_eventloop, NULL);
753 if (quit_timeout == 0) {
754 error("Failed to init startup timeout");
756 g_source_remove(signal);
760 if (!bt_bluetooth_start(option_index, option_mgmt_dbg, adapter_ready)) {
762 g_source_remove(quit_timeout);
763 g_source_remove(signal);
767 /* Use params: mtu = 0, flags = 0 */
768 start_sdp_server(0, 0);
770 DBG("Entering main loop");
772 event_loop = g_main_loop_new(NULL, FALSE);
774 g_main_loop_run(event_loop);
776 g_source_remove(signal);
778 if (quit_timeout > 0)
779 g_source_remove(quit_timeout);
784 bt_bluetooth_cleanup();
785 g_main_loop_unref(event_loop);
787 /* If no adapter was initialized, hal_ipc is NULL */
789 ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE);
790 ipc_cleanup(hal_ipc);