device.c revision 632a9432774ff3a0c6e556e8f32a565b38890767
1c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky/* 272074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * 372074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * BlueZ - Bluetooth protocol stack for Linux 472074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * 572074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * Copyright (C) 2000-2001 Qualcomm Incorporated 672074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> 71798ef015acd1da838f3a265bb0003efe94757adMarcel Holtmann * Copyright (C) 2002-2005 Marcel Holtmann <marcel@holtmann.org> 872074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * 972074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * 1072074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * This program is free software; you can redistribute it and/or modify 11632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * it under the terms of the GNU General Public License as published by 12632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * the Free Software Foundation; either version 2 of the License, or 13632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * (at your option) any later version. 1472074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * 15632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * This program is distributed in the hope that it will be useful, 16632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 17632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * GNU General Public License for more details. 1972074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * 20632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * You should have received a copy of the GNU General Public License 21632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * along with this program; if not, write to the Free Software 22632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2372074e1e63e6cbe934c1e5eb9fd583ec81057a22Marcel Holtmann * 24c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky */ 25c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 261d3715db11f573060cb02a2b7b7c44f06607d337Marcel Holtmann#ifdef HAVE_CONFIG_H 271d3715db11f573060cb02a2b7b7c44f06607d337Marcel Holtmann#include <config.h> 281d3715db11f573060cb02a2b7b7c44f06607d337Marcel Holtmann#endif 291d3715db11f573060cb02a2b7b7c44f06607d337Marcel Holtmann 30c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <stdio.h> 31632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann#include <errno.h> 32632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann#include <fcntl.h> 33c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <unistd.h> 34632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann#include <stdlib.h> 35c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <string.h> 36c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <signal.h> 37c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <syslog.h> 38c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include <sys/time.h> 39f79b2c879c633667916d1fb17870c54597294d8eMax Krasnyansky#include <sys/stat.h> 40632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann#include <sys/ioctl.h> 41632a9432774ff3a0c6e556e8f32a565b38890767Marcel Holtmann#include <sys/socket.h> 42c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 43f79b2c879c633667916d1fb17870c54597294d8eMax Krasnyansky#include <bluetooth/bluetooth.h> 44f79b2c879c633667916d1fb17870c54597294d8eMax Krasnyansky#include <bluetooth/hci.h> 45f79b2c879c633667916d1fb17870c54597294d8eMax Krasnyansky#include <bluetooth/hci_lib.h> 46c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 47c7c04aac86fec5084e3e1caf3eaaa3abd545f58dMarcel Holtmann#include "glib-ectomy.h" 48c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 49c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include "hcid.h" 50c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky#include "lib.h" 51c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 52c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystruct hcid_opts hcid; 535ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstruct device_opts default_device; 545ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstruct device_opts *parser_device; 555ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstatic struct device_list *device_list = NULL; 56c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 57c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic GMainLoop *event_loop; 58c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 59c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic void usage(void) 60c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 61c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky printf("hcid - HCI daemon ver %s\n", VERSION); 62c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky printf("Usage: \n"); 63c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky printf("\thcid [-n not_daemon] [-f config file]\n"); 64c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 65c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 665ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstatic inline void init_device_defaults(struct device_opts *device_opts) 675ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann{ 685ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann memset(device_opts, 0, sizeof(*device_opts)); 695ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_opts->scan = SCAN_PAGE | SCAN_INQUIRY; 705ac3c1ef76b8d1640bad9a21b74b197a82111874Marcel Holtmann device_opts->name = strdup("BlueZ"); 715ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann} 725ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 735ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstruct device_opts *alloc_device_opts(char *ref) 745ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann{ 755ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann struct device_list *device; 765ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 775ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device = malloc(sizeof(struct device_list)); 785ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (!device) { 790dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_INFO, "Can't allocate devlist opts buffer: %s (%d)", 800dab40dad416805e31cb5312956880609dc21443Marcel Holtmann strerror(errno), errno); 815ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann exit(1); 825ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann } 835ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 845ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device->ref = ref; 855ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device->next = device_list; 865ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_list = device; 875ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 885ac3c1ef76b8d1640bad9a21b74b197a82111874Marcel Holtmann memcpy(&device->opts, &default_device, sizeof(struct device_opts)); 895ac3c1ef76b8d1640bad9a21b74b197a82111874Marcel Holtmann device->opts.name = strdup(default_device.name); 905ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 915ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann return &device->opts; 925ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann} 935ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 945ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstatic void free_device_opts(void) 955ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann{ 965ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann struct device_list *device, *next; 975ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 985ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (default_device.name) { 995ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann free(default_device.name); 1005ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann default_device.name = NULL; 1015ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann } 1025ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1035ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann for (device = device_list; device; device = next) { 1045ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann free(device->ref); 1055ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (device->opts.name) 1065ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann free(device->opts.name); 1075ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann next = device->next; 1085ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann free(device); 1095ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann } 1105ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1115ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_list = NULL; 1125ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann} 1135ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1145ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstatic inline struct device_opts *find_device_opts(char *ref) 1155ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann{ 1165ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann struct device_list *device; 1175ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1185ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann for (device = device_list; device; device = device->next) 1195ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (!strcmp(ref, device->ref)) 1205ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann return &device->opts; 1215ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1225ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann return NULL; 1235ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann} 1245ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1255ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannstatic struct device_opts *get_device_opts(int sock, int hdev) 1265ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann{ 1275ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann struct device_opts *device_opts = NULL; 1285ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann struct hci_dev_info di; 1295ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1305ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann /* First try to get BD_ADDR based settings ... */ 1315ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann di.dev_id = hdev; 1325ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (!ioctl(sock, HCIGETDEVINFO, (void *) &di)) { 1335ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann char addr[18]; 1345ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann ba2str(&di.bdaddr, addr); 1355ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_opts = find_device_opts(addr); 1365ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann } 1375ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1385ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann /* ... then try HCI based settings ... */ 1395ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (!device_opts) { 1405ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann char ref[8]; 1415ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann snprintf(ref, sizeof(ref) - 1, "hci%d", hdev); 1425ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_opts = find_device_opts(ref); 1435ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann } 1445ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1455ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann /* ... and last use the default settings. */ 1465ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (!device_opts) 1475ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_opts = &default_device; 1485ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 1495ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann return device_opts; 1505ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann} 1515ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 15230fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyanskystatic void configure_device(int hdev) 153c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 1545ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann struct device_opts *device_opts; 155c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct hci_dev_req dr; 156747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann struct hci_dev_info di; 157c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky int s; 158c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 15930fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky /* Do configuration in the separate process */ 160c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky switch (fork()) { 161c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case 0: 162c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 163c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case -1: 1640dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Fork failed. Can't init device hci%d: %s (%d)", 1650dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 166c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky default: 167c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return; 168c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 169c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 17030fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky set_title("hci%d config", hdev); 171c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 172c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if ((s = hci_open_dev(hdev)) < 0) { 1730dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", 1740dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 175c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 176c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 177c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 178747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann di.dev_id = hdev; 179747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann if (ioctl(s, HCIGETDEVINFO, (void *) &di) < 0) 180747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann exit(1); 181747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann 182747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann if (hci_test_bit(HCI_RAW, &di.flags)) 183747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann exit(0); 184747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann 1855ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann dr.dev_id = hdev; 1865ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_opts = get_device_opts(s, hdev); 187c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 188c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Set scan mode */ 1895ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann dr.dev_opt = device_opts->scan; 1905ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (ioctl(s, HCISETSCAN, (unsigned long) &dr) < 0) { 1910dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)", 1920dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 193c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 194c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 195c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Set authentication */ 1965ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (device_opts->auth) 197c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky dr.dev_opt = AUTH_ENABLED; 198c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky else 199c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky dr.dev_opt = AUTH_DISABLED; 200c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2015ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (ioctl(s, HCISETAUTH, (unsigned long) &dr) < 0) { 2020dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't set auth on hci%d: %s (%d)", 2030dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 204c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 205c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 206c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Set encryption */ 2075ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (device_opts->encrypt) 208c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky dr.dev_opt = ENCRYPT_P2P; 209c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky else 210c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky dr.dev_opt = ENCRYPT_DISABLED; 211c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2125ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (ioctl(s, HCISETENCRYPT, (unsigned long) &dr) < 0) { 2130dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't set encrypt on hci%d: %s (%d)", 2140dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 215c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 216c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2172bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann /* Set device name */ 2182bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_NAME)) && device_opts->name) { 2192bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann change_local_name_cp cp; 22052bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann write_ext_inquiry_response_cp ip; 22152bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann uint8_t len; 22252bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann 2232bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann memset(cp.name, 0, sizeof(cp.name)); 2241f422e5f2b343d35a8c77ce4be16f74b2819b2bfMarcel Holtmann expand_name((char *) cp.name, sizeof(cp.name), device_opts->name, hdev); 2252bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann 22652bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann ip.fec = 0x00; 22752bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann memset(ip.data, 0, sizeof(ip.data)); 22852bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann len = strlen((char *) cp.name); 22952bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann if (len > 48) { 23052bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann len = 48; 23152bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann ip.data[1] = 0x08; 23252bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann } else 23352bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann ip.data[1] = 0x09; 23452bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann ip.data[0] = len + 1; 23552bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann memcpy(ip.data + 2, cp.name, len); 23652bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann 2372bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, 2388d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann CHANGE_LOCAL_NAME_CP_SIZE, &cp); 23952bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann 24052bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann if (di.features[6] & LMP_EXT_INQ) 24152bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_EXT_INQUIRY_RESPONSE, 24252bd6030faf7f3448beadab2b9388e339de08811Marcel Holtmann WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &ip); 2432bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann } 2442bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann 2455ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann /* Set device class */ 2462bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_CLASS))) { 2475ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann uint32_t class = htobl(device_opts->class); 248c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky write_class_of_dev_cp cp; 2495ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 250c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky memcpy(cp.dev_class, &class, 3); 251c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, 2528d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann WRITE_CLASS_OF_DEV_CP_SIZE, &cp); 253c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 254c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2552bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann /* Set voice setting */ 2562bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_VOICE))) { 2572bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann write_voice_setting_cp cp; 258c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 2592bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann cp.voice_setting = htobl(device_opts->voice); 2602bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING, 2618d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann WRITE_VOICE_SETTING_CP_SIZE, &cp); 262c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 263c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 264959b1e8c1d5ad023e1b3c8157a844c61df44a0a1Marcel Holtmann /* Set inquiry mode */ 26514e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_INQMODE))) { 266959b1e8c1d5ad023e1b3c8157a844c61df44a0a1Marcel Holtmann write_inquiry_mode_cp cp; 267959b1e8c1d5ad023e1b3c8157a844c61df44a0a1Marcel Holtmann 26814e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann switch (device_opts->inqmode) { 26914e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann case 2: 27014e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann if (di.features[6] & LMP_EXT_INQ) { 27114e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann cp.mode = 2; 27214e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann break; 27314e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann } 27414e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann case 1: 27514e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann if (di.features[3] & LMP_RSSI_INQ) { 27614e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann cp.mode = 1; 27714e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann break; 27814e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann } 27914e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann default: 28014e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann cp.mode = 0; 28114e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann break; 28214e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann } 28314e7b4e9a3c868b3bded7b08488aac89210984a6Marcel Holtmann 284959b1e8c1d5ad023e1b3c8157a844c61df44a0a1Marcel Holtmann hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, 2858d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann WRITE_INQUIRY_MODE_CP_SIZE, &cp); 2868d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann } 2878d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann 2888d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann /* Set page timeout */ 2898d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_PAGETO))) { 2908d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann write_page_timeout_cp cp; 2918d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann 2928d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann cp.timeout = htobs(device_opts->pageto); 2938d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, 2948d07fe695736cfc4126f1aad4144303161c61e21Marcel Holtmann WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); 295959b1e8c1d5ad023e1b3c8157a844c61df44a0a1Marcel Holtmann } 296959b1e8c1d5ad023e1b3c8157a844c61df44a0a1Marcel Holtmann 297c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(0); 298c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 299c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 30030fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyanskystatic void init_device(int hdev) 30130fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky{ 3025ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann struct device_opts *device_opts; 30330fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky struct hci_dev_req dr; 304747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann struct hci_dev_info di; 30530fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky int s; 30630fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 30730fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky /* Do initialization in the separate process */ 30830fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky switch (fork()) { 30930fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky case 0: 31030fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky break; 31130fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky case -1: 3120dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Fork failed. Can't init device hci%d: %s (%d)", 3130dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 31430fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky default: 31530fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky return; 31630fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 31730fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 31830fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky set_title("hci%d init", hdev); 31930fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 32030fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky if ((s = hci_open_dev(hdev)) < 0) { 3210dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", 3220dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 32330fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky exit(1); 32430fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 32530fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 326cbc274c6e3ce3b2135c21c101d19271d66d3215eMax Krasnyansky /* Start HCI device */ 327cbc274c6e3ce3b2135c21c101d19271d66d3215eMax Krasnyansky if (ioctl(s, HCIDEVUP, hdev) < 0 && errno != EALREADY) { 3280dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't init device hci%d: %s (%d)", 3290dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 330cbc274c6e3ce3b2135c21c101d19271d66d3215eMax Krasnyansky exit(1); 331cbc274c6e3ce3b2135c21c101d19271d66d3215eMax Krasnyansky } 332cbc274c6e3ce3b2135c21c101d19271d66d3215eMax Krasnyansky 333747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann di.dev_id = hdev; 334747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann if (ioctl(s, HCIGETDEVINFO, (void *) &di) < 0) 335747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann exit(1); 336747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann 337747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann if (hci_test_bit(HCI_RAW, &di.flags)) 338747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann exit(0); 339747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann 3405ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann dr.dev_id = hdev; 3415ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann device_opts = get_device_opts(s, hdev); 34230fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 34330fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky /* Set packet type */ 3442bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_PTYPE))) { 3455ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann dr.dev_opt = device_opts->pkt_type; 3465ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (ioctl(s, HCISETPTYPE, (unsigned long) &dr) < 0) { 3470dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't set packet type on hci%d: %s (%d)", 3480dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 34930fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 35030fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 35130fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 35230fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky /* Set link mode */ 3532bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_LM))) { 3545ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann dr.dev_opt = device_opts->link_mode; 3555ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (ioctl(s, HCISETLINKMODE, (unsigned long) &dr) < 0) { 3560dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't set link mode on hci%d: %s (%d)", 3570dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 35830fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 35930fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 36030fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 36130fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky /* Set link policy */ 3622bc66b1d0af2e2a01e545493510347578928ae33Marcel Holtmann if ((device_opts->flags & (1 << HCID_SET_LP))) { 3635ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann dr.dev_opt = device_opts->link_policy; 3645ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (ioctl(s, HCISETLINKPOL, (unsigned long) &dr) < 0) { 3650dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't set link policy on hci%d: %s (%d)", 3660dab40dad416805e31cb5312956880609dc21443Marcel Holtmann hdev, strerror(errno), errno); 36730fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 36830fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky } 36930fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 37030fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky exit(0); 37130fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky} 37230fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 373c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic void init_all_devices(int ctl) 374c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 375c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct hci_dev_list_req *dl; 376c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct hci_dev_req *dr; 377c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky int i; 378c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 379c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) { 3800dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_INFO, "Can't allocate devlist buffer: %s (%d)", 3810dab40dad416805e31cb5312956880609dc21443Marcel Holtmann strerror(errno), errno); 382c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 383c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 384c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky dl->dev_num = HCI_MAX_DEV; 385c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky dr = dl->dev_req; 386c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 3875ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { 3880dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_INFO, "Can't get device list: %s (%d)", 3890dab40dad416805e31cb5312956880609dc21443Marcel Holtmann strerror(errno), errno); 390c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 391c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 392c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 3935ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann for (i = 0; i < dl->dev_num; i++, dr++) { 394c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (hcid.auto_init) 395c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky init_device(dr->dev_id); 396c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 397747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann if (hcid.auto_init && hci_test_bit(HCI_UP, &dr->dev_opt)) 39830fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky configure_device(dr->dev_id); 39930fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky 400747bc0b292ee5655ef2695c4e8e18f55c4037567Marcel Holtmann if (hcid.security && hci_test_bit(HCI_UP, &dr->dev_opt)) 401c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky start_security_manager(dr->dev_id); 40234e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann 40334e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#ifdef ENABLE_DBUS 4047a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann if (hci_test_bit(HCI_UP, &dr->dev_opt)) 4057a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann hcid_dbus_register_manager(dr->dev_id); 4067a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann 40734e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann hcid_dbus_register_device(dr->dev_id); 40834e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#endif 409c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 4105ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 411c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky free(dl); 412c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 413c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 414c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic void init_defaults(void) 415c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 416c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hcid.auto_init = 0; 417c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hcid.security = 0; 418c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4195ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann init_device_defaults(&default_device); 420c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 421c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 422c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic void sig_usr1(int sig) 423c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 424c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyansky toggle_pairing(0); 425c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyansky} 426c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyansky 427c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyanskystatic void sig_usr2(int sig) 428c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyansky{ 429c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyansky toggle_pairing(1); 430c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 431c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 432c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic void sig_term(int sig) 433c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 434c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky g_main_quit(event_loop); 435c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 436c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 437c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic void sig_hup(int sig) 438c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 439c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "Reloading config file"); 4405ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 441c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky init_defaults(); 4425ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 443c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (read_config(hcid.config_file) < 0) 444c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_ERR, "Config reload failed"); 445c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 446ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky init_security_data(); 447ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky 448c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky init_all_devices(hcid.sock); 449c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 450c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 451c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskystatic inline void device_event(GIOChannel *chan, evt_stack_internal *si) 452c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 453c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky evt_si_device *sd = (void *) &si->data; 454c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 455c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky switch (sd->event) { 456c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case HCI_DEV_REG: 457c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "HCI dev %d registered", sd->dev_id); 458c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (hcid.auto_init) 459c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky init_device(sd->dev_id); 4607a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann#ifdef ENABLE_DBUS 4617a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann hcid_dbus_register_device(sd->dev_id); 4627a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann#endif 463c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 464c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 465c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case HCI_DEV_UNREG: 466c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "HCI dev %d unregistered", sd->dev_id); 4677a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann#ifdef ENABLE_DBUS 4687a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann hcid_dbus_unregister_device(sd->dev_id); 4697a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann#endif 470c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 471c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 472c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case HCI_DEV_UP: 473c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "HCI dev %d up", sd->dev_id); 47430fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky if (hcid.auto_init) 47530fc590d680e1dddd718316e9a0936e6dfa04be6Max Krasnyansky configure_device(sd->dev_id); 476c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (hcid.security) 477c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky start_security_manager(sd->dev_id); 47834e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#ifdef ENABLE_DBUS 4797a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann hcid_dbus_register_manager(sd->dev_id); 48034e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#endif 481c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 482c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 483c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case HCI_DEV_DOWN: 484c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "HCI dev %d down", sd->dev_id); 485c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (hcid.security) 486c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky stop_security_manager(sd->dev_id); 48734e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#ifdef ENABLE_DBUS 4887a58f1b38a86d30477048e84d979d627ebfec10bMarcel Holtmann hcid_dbus_unregister_manager(sd->dev_id); 48934e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#endif 490c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 491c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 492c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 493c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 4941798ef015acd1da838f3a265bb0003efe94757adMarcel Holtmannstatic gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data) 495c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 4968100e0c660e200a9d789dcd054f25a20778379cdMarcel Holtmann unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; 497c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky evt_stack_internal *si; 498c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hci_event_hdr *eh; 4998100e0c660e200a9d789dcd054f25a20778379cdMarcel Holtmann int type; 5008100e0c660e200a9d789dcd054f25a20778379cdMarcel Holtmann size_t len; 501c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky GIOError err; 502c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 503c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky ptr = buf; 504c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 5051f422e5f2b343d35a8c77ce4be16f74b2819b2bfMarcel Holtmann if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { 506c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (err == G_IO_ERROR_AGAIN) 507c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return TRUE; 508c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 5090dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Read from control socket failed: %s (%d)", 5100dab40dad416805e31cb5312956880609dc21443Marcel Holtmann strerror(errno), errno); 511c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky g_main_quit(event_loop); 512c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return FALSE; 513c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 514c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 515c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky type = *ptr++; 516c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 517c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (type != HCI_EVENT_PKT) 518c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return TRUE; 519c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 520c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky eh = (hci_event_hdr *) ptr; 521c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (eh->evt != EVT_STACK_INTERNAL) 522c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return TRUE; 523c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 524c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky ptr += HCI_EVENT_HDR_SIZE; 525c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 526c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky si = (evt_stack_internal *) ptr; 527c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky switch (si->type) { 528c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky case EVT_SI_DEVICE: 529c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky device_event(chan, si); 530c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky break; 531c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 532c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 533c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return TRUE; 534c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 535c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 5365ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmannextern int optind, opterr, optopt; 537c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskyextern char *optarg; 538c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 539c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyanskyint main(int argc, char *argv[], char *env[]) 540c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky{ 541c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky int daemon, dofork, opt, fd; 542c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct sockaddr_hci addr; 543c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct hci_filter flt; 544c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky struct sigaction sa; 545c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky GIOChannel *ctl_io; 546c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 547c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky daemon = 1; dofork = 1; 548c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 549c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Default HCId settings */ 550c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hcid.config_file = HCID_CONFIG_FILE; 5515ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann hcid.host_name = get_host_name(); 5525ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann hcid.security = HCID_SEC_AUTO; 5535ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann hcid.pairing = HCID_PAIRING_MULTI; 554c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 5555ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann hcid.pin_file = strdup(HCID_PIN_FILE); 5565ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann hcid.pin_helper = strdup(HCID_PIN_HELPER); 5575ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann hcid.key_file = strdup(HCID_KEY_FILE); 558c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 559c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky init_defaults(); 5606aa87b34ea5135cfb8dd403f1bfca8fe10172fd1Marcel Holtmann 5615ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann while ((opt = getopt(argc, argv, "f:n")) != EOF) { 5625ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann switch (opt) { 563ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky case 'n': 564ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky daemon = 0; 565ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky break; 566c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 567ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky case 'f': 568ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky hcid.config_file = strdup(optarg); 569ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky break; 570c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 571ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky default: 572ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky usage(); 573ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky exit(1); 574c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 575c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 576c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 577c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (daemon) { 578c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (dofork && fork()) 579c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(0); 580c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 581c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Direct stdin,stdout,stderr to '/dev/null' */ 582c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky fd = open("/dev/null", O_RDWR); 583c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); 584c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky close(fd); 585c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 586c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky setsid(); 587c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 588c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky chdir("/"); 589c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 590c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 591f79b2c879c633667916d1fb17870c54597294d8eMax Krasnyansky umask(0077); 5925ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 5935ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann init_title(argc, argv, env, "hcid: "); 594c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky set_title("initializing"); 595c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 596c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Start logging to syslog and stderr */ 597c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky openlog("hcid", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); 5984c65d109ee2ced4a49a511ec185da11a8b27f069Marcel Holtmann syslog(LOG_INFO, "Bluetooth HCI daemon"); 599c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 600c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky memset(&sa, 0, sizeof(sa)); 601c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sa.sa_flags = SA_NOCLDSTOP; 602c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sa.sa_handler = sig_term; 603c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sigaction(SIGTERM, &sa, NULL); 604c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sigaction(SIGINT, &sa, NULL); 605c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sa.sa_handler = sig_hup; 606c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sigaction(SIGHUP, &sa, NULL); 607c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sa.sa_handler = sig_usr1; 608c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sigaction(SIGUSR1, &sa, NULL); 609c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyansky sa.sa_handler = sig_usr2; 610c5dca08e234386563667e8f790b4e1122c364c5dMax Krasnyansky sigaction(SIGUSR2, &sa, NULL); 611c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 612c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sa.sa_handler = SIG_IGN; 613c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sigaction(SIGCHLD, &sa, NULL); 614c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky sigaction(SIGPIPE, &sa, NULL); 615c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 616c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Create and bind HCI socket */ 617c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if ((hcid.sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { 6180dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", 6190dab40dad416805e31cb5312956880609dc21443Marcel Holtmann strerror(errno), errno); 620c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 621c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 622c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 623c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Set filter */ 624c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hci_filter_clear(&flt); 625c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hci_filter_set_ptype(HCI_EVENT_PKT, &flt); 626c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky hci_filter_set_event(EVT_STACK_INTERNAL, &flt); 627c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (setsockopt(hcid.sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { 6280dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't set filter: %s (%d)", 6290dab40dad416805e31cb5312956880609dc21443Marcel Holtmann strerror(errno), errno); 630c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 631c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 632c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 633c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky addr.hci_family = AF_BLUETOOTH; 634c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky addr.hci_dev = HCI_DEV_NONE; 6355ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann if (bind(hcid.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 6360dab40dad416805e31cb5312956880609dc21443Marcel Holtmann syslog(LOG_ERR, "Can't bind HCI socket: %s (%d)", 6370dab40dad416805e31cb5312956880609dc21443Marcel Holtmann strerror(errno), errno); 638c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky exit(1); 639c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky } 640c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 641c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky if (read_config(hcid.config_file) < 0) 642c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_ERR, "Config load failed"); 643c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 644f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann#ifdef ENABLE_DBUS 645f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann if (hcid_dbus_init() == FALSE && hcid.dbus_pin_helper) { 646f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann syslog(LOG_ERR, "Unable to get on D-BUS"); 647f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann exit(1); 648f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann } 649f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann#else 650f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann if (hcid.dbus_pin_helper) { 651f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann syslog(LOG_ERR, "D-BUS not configured in this build of hcid"); 652f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann exit(1); 653f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann } 654f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann#endif 655f17bb94f47090f3397b60b5e264aa9f18dbf203dMarcel Holtmann 656ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky init_security_data(); 657ccb0bf6ad34beb532176a49731537f09fe01875cMax Krasnyansky 658c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Create event loop */ 659c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky event_loop = g_main_new(FALSE); 660c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 661c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Initialize already connected devices */ 662c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky init_all_devices(hcid.sock); 663c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 664c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky set_title("processing events"); 665c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 666c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky ctl_io = g_io_channel_unix_new(hcid.sock); 667c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); 668c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 669c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky /* Start event processor */ 670c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky g_main_run(event_loop); 671c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky 6725ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann free_device_opts(); 6735ff58cb0e277fb4cb4613aa3d2a83e7237c59894Marcel Holtmann 67434e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#ifdef ENABLE_DBUS 67534e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann hcid_dbus_exit(); 67634e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann#endif 67734e266aaa88d0ff1e5930946d96783420c232895Marcel Holtmann 678c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky syslog(LOG_INFO, "Exit."); 679c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky return 0; 680c98b2f82a4e532ca61592b08e3ad60749eb9f8dMax Krasnyansky} 681