static void configure_device(int index) { struct hci_dev_info di; uint16_t policy; int dd; if (hci_devinfo(index, &di) < 0) return; if (hci_test_bit(HCI_RAW, &di.flags)) return; dd = hci_open_dev(index); if (dd < 0) { error("Can't open device hci%d: %s (%d)", index, strerror(errno), errno); return; } /* Set device name */ if ((main_opts.flags & (1 << HCID_SET_NAME)) && main_opts.name) { change_local_name_cp cp; memset(cp.name, 0, sizeof(cp.name)); expand_name((char *) cp.name, sizeof(cp.name), main_opts.name, index); hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, &cp); } /* Set device class */ if ((main_opts.flags & (1 << HCID_SET_CLASS))) { write_class_of_dev_cp cp; uint32_t class; uint8_t cls[3]; if (read_local_class(&di.bdaddr, cls) < 0) { class = htobl(main_opts.class); cls[2] = get_service_classes(&di.bdaddr); memcpy(cp.dev_class, &class, 3); } else { if (!(main_opts.scan & SCAN_INQUIRY))
static void configure_device(int dev_id) { struct device_opts *device_opts; struct hci_dev_req dr; struct hci_dev_info di; char mode[14]; int dd; device_opts = get_device_opts(dev_id); if (hci_devinfo(dev_id, &di) < 0) return; if (hci_test_bit(HCI_RAW, &di.flags)) return; /* Set default discoverable timeout if not set */ if (!(device_opts->flags & (1 << HCID_SET_DISCOVTO))) device_opts->discovto = HCID_DEFAULT_DISCOVERABLE_TIMEOUT; /* Set scan mode */ if (read_device_mode(&di.bdaddr, mode, sizeof(mode)) == 0) { if (!strcmp(mode, "off") && hcid.offmode == HCID_OFFMODE_NOSCAN) { device_opts->mode = MODE_OFF; device_opts->scan = SCAN_DISABLED; } else if (!strcmp(mode, "connectable")) { device_opts->mode = MODE_CONNECTABLE; device_opts->scan = SCAN_PAGE; } else if (!strcmp(mode, "discoverable")) { /* Set discoverable only if timeout is 0 */ if (!get_discoverable_timeout(dev_id)) { device_opts->scan = SCAN_PAGE | SCAN_INQUIRY; device_opts->mode = MODE_DISCOVERABLE; } else { device_opts->scan = SCAN_PAGE; device_opts->mode = MODE_CONNECTABLE; } } else if (!strcmp(mode, "limited")) { /* Set discoverable only if timeout is 0 */ if (!get_discoverable_timeout(dev_id)) { device_opts->scan = SCAN_PAGE | SCAN_INQUIRY; device_opts->mode = MODE_LIMITED; } else { device_opts->scan = SCAN_PAGE; device_opts->mode = MODE_CONNECTABLE; } } } /* Do configuration in the separate process */ switch (fork()) { case 0: atexit(at_child_exit); break; case -1: error("Fork failed. Can't init device hci%d: %s (%d)", dev_id, strerror(errno), errno); default: return; } dd = hci_open_dev(dev_id); if (dd < 0) { error("Can't open device hci%d: %s (%d)", dev_id, strerror(errno), errno); exit(1); } memset(&dr, 0, sizeof(dr)); dr.dev_id = dev_id; /* Set packet type */ if ((device_opts->flags & (1 << HCID_SET_PTYPE))) { dr.dev_opt = device_opts->pkt_type; if (ioctl(dd, HCISETPTYPE, (unsigned long) &dr) < 0) { error("Can't set packet type on hci%d: %s (%d)", dev_id, strerror(errno), errno); } } /* Set link mode */ if ((device_opts->flags & (1 << HCID_SET_LM))) { dr.dev_opt = device_opts->link_mode; if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) { error("Can't set link mode on hci%d: %s (%d)", dev_id, strerror(errno), errno); } } /* Set link policy */ if ((device_opts->flags & (1 << HCID_SET_LP))) { dr.dev_opt = device_opts->link_policy; if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0) { error("Can't set link policy on hci%d: %s (%d)", dev_id, strerror(errno), errno); } } /* Set device name */ if ((device_opts->flags & (1 << HCID_SET_NAME)) && device_opts->name) { change_local_name_cp cp; memset(cp.name, 0, sizeof(cp.name)); expand_name((char *) cp.name, sizeof(cp.name), device_opts->name, dev_id); hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, &cp); } /* Set device class */ if ((device_opts->flags & (1 << HCID_SET_CLASS))) { write_class_of_dev_cp cp; uint32_t class; uint8_t cls[3]; if (read_local_class(&di.bdaddr, cls) < 0) { class = htobl(device_opts->class); cls[2] = get_service_classes(&di.bdaddr); memcpy(cp.dev_class, &class, 3); } else { if (!(device_opts->scan & SCAN_INQUIRY))
} /* Set device class */ if ((device_opts->flags & (1 << HCID_SET_CLASS))) { write_class_of_dev_cp cp; uint32_t class; uint8_t cls[3]; if (read_local_class(&di.bdaddr, cls) < 0) { class = htobl(device_opts->class); cls[2] = get_service_classes(&di.bdaddr); memcpy(cp.dev_class, &class, 3); } else { if (!(device_opts->scan & SCAN_INQUIRY)) cls[1] &= 0xdf; /* Clear discoverable bit */ cls[2] = get_service_classes(&di.bdaddr); memcpy(cp.dev_class, cls, 3); } hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, WRITE_CLASS_OF_DEV_CP_SIZE, &cp); } /* Set page timeout */ if ((device_opts->flags & (1 << HCID_SET_PAGETO))) { write_page_timeout_cp cp; cp.timeout = htobs(device_opts->pageto); hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); }