diff --git a/bluez-4.78-cc758c498ed98de11e890e56d4500ca85587bc07.diff b/bluez-4.78-cc758c498ed98de11e890e56d4500ca85587bc07.diff deleted file mode 100644 index afa88d1..0000000 --- a/bluez-4.78-cc758c498ed98de11e890e56d4500ca85587bc07.diff +++ /dev/null @@ -1,1675 +0,0 @@ -Index: b/lib/mgmt.h -=================================================================== ---- a/lib/mgmt.h -+++ b/lib/mgmt.h -@@ -30,64 +30,75 @@ struct mgmt_hdr { - uint16_t len; - } __packed; - #define MGMT_HDR_SIZE 4 - - #define MGMT_OP_READ_VERSION 0x0001 --struct mgmt_read_version_rp { -+struct mgmt_rp_read_version { - uint8_t version; - uint16_t revision; - } __packed; --#define MGMT_READ_VERSION_RP_SIZE 3 - - #define MGMT_OP_READ_FEATURES 0x0002 --struct mgmt_read_features_rp { -+struct mgmt_rp_read_features { - uint8_t features[8]; - } __packed; --#define MGMT_READ_FEATURES_RP_SIZE 8 - - #define MGMT_OP_READ_INDEX_LIST 0x0003 --struct mgmt_read_index_list_rp { -+struct mgmt_rp_read_index_list { - uint16_t num_controllers; - uint16_t index[0]; - } __packed; --#define MGMT_READ_INDEX_LIST_RP_SIZE 2 - - #define MGMT_OP_READ_INFO 0x0004 --struct mgmt_read_info_cp { -+struct mgmt_cp_read_info { - uint16_t index; - } __packed; --#define MGMT_READ_INFO_CP_SIZE 2 --struct mgmt_read_info_rp { -+struct mgmt_rp_read_info { - uint8_t status; - uint16_t index; - uint8_t type; - bdaddr_t bdaddr; - uint8_t features[8]; - } __packed; --#define MGMT_READ_INFO_RP_SIZE 18 - - #define MGMT_OP_READ_STATISTICS 0x0005 - - #define MGMT_OP_READ_MODE 0x0006 --struct mgmt_read_mode_cp { -+struct mgmt_cp_read_mode { - uint16_t index; - } __packed; --#define MGMT_READ_MODE_CP_SIZE 2 --struct mgmt_read_mode_rp { -+struct mgmt_rp_read_mode { - uint8_t status; - uint16_t index; - uint8_t enabled; - uint8_t mode; - } __packed; --#define MGMT_READ_MODE_RP_SIZE 5 - - #define MGMT_OP_WRITE_MODE 0x0007 - - #define MGMT_EV_CMD_COMPLETE 0x0001 --struct mgmt_cmd_complete_ev { -+struct mgmt_ev_cmd_complete { - uint16_t opcode; - uint8_t data[0]; - } __packed; --#define MGMT_CMD_COMPLETE_SIZE 2 - - #define MGMT_EV_CMD_STATUS 0x0002 -+struct mgmt_ev_cmd_status { -+ uint8_t status; -+ uint16_t opcode; -+} __packed; -+ - #define MGMT_EV_CONTROLLER_ERROR 0x0003 -+struct mgmt_ev_controller_error { -+ uint16_t index; -+ uint8_t error_code; -+} __packed; -+ -+#define MGMT_EV_INDEX_ADDED 0x0004 -+struct mgmt_ev_index_added { -+ uint16_t index; -+} __packed; -+ -+#define MGMT_EV_INDEX_REMOVED 0x0005 -+struct mgmt_ev_index_removed { -+ uint16_t index; -+} __packed; -Index: b/plugins/hciops.c -=================================================================== ---- a/plugins/hciops.c -+++ b/plugins/hciops.c -@@ -55,15 +55,26 @@ static int child_pipe[2] = { -1, -1 }; - static guint child_io_id = 0; - static guint ctl_io_id = 0; - - #define SK(index) devs[(index)].sk - #define BDADDR(index) devs[(index)].bdaddr -+#define UP(index) devs[(index)].up -+#define READY(index) devs[(index)].ready -+#define CHANNEL(index) devs[(index)].channel -+#define WATCH_ID(index) devs[(index)].watch_id -+#define PIN_LENGTH(index) devs[(index)].pin_length - - static int max_dev = -1; - static struct dev_info { - int sk; - bdaddr_t bdaddr; -+ gboolean up; -+ gboolean ready; -+ -+ GIOChannel *channel; -+ guint watch_id; -+ int pin_length; - } *devs = NULL; - - static int ignore_device(struct hci_dev_info *di) - { - return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR; -@@ -71,10 +82,11 @@ static int ignore_device(struct hci_dev_ - - static void init_dev_info(int index, int sk) - { - memset(&devs[index], 0, sizeof(struct dev_info)); - SK(index) = sk; -+ PIN_LENGTH(index) = -1; - } - - /* Async HCI command handling with callback support */ - - struct hci_cmd_data { -@@ -249,33 +261,23 @@ static int hciops_encrypt_link(int index - - /* End async HCI command handling */ - - /* Start of HCI event callbacks */ - --struct g_io_info { -- GIOChannel *channel; -- int watch_id; -- int pin_length; --}; -- --static struct g_io_info io_data[HCI_MAX_DEV]; -- --static int get_handle(int dev, bdaddr_t *sba, bdaddr_t *dba, uint16_t *handle) -+static int get_handle(int index, bdaddr_t *dba, uint16_t *handle) - { - struct hci_conn_list_req *cl; - struct hci_conn_info *ci; -- char addr[18]; - int i; - - cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); - -- ba2str(sba, addr); -- cl->dev_id = hci_devid(addr); -+ cl->dev_id = index; - cl->conn_num = 10; - ci = cl->conn_info; - -- if (ioctl(dev, HCIGETCONNLIST, (void *) cl) < 0) { -+ if (ioctl(SK(index), HCIGETCONNLIST, (void *) cl) < 0) { - g_free(cl); - return -EIO; - } - - for (i = 0; i < cl->conn_num; i++, ci++) { -@@ -289,25 +291,23 @@ static int get_handle(int dev, bdaddr_t - g_free(cl); - - return -ENOENT; - } - --static inline int get_bdaddr(int dev, bdaddr_t *sba, uint16_t handle, bdaddr_t *dba) -+static inline int get_bdaddr(int index, uint16_t handle, bdaddr_t *dba) - { - struct hci_conn_list_req *cl; - struct hci_conn_info *ci; -- char addr[18]; - int i; - - cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); - -- ba2str(sba, addr); -- cl->dev_id = hci_devid(addr); -+ cl->dev_id = index; - cl->conn_num = 10; - ci = cl->conn_info; - -- if (ioctl(dev, HCIGETCONNLIST, (void *) cl) < 0) { -+ if (ioctl(SK(index), HCIGETCONNLIST, (void *) cl) < 0) { - g_free(cl); - return -EIO; - } - - for (i = 0; i < cl->conn_num; i++, ci++) -@@ -344,33 +344,33 @@ static inline void update_lastused(bdadd - write_lastused_info(sba, dba, tm); - } - - /* Link Key handling */ - --static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) -+static void link_key_request(int index, bdaddr_t *dba) - { - struct btd_adapter *adapter; - struct btd_device *device; - struct hci_auth_info_req req; - unsigned char key[16]; - char sa[18], da[18]; - uint8_t type; - int err; - -- ba2str(sba, sa); ba2str(dba, da); -+ ba2str(&BDADDR(index), sa); ba2str(dba, da); - info("link_key_request (sba=%s, dba=%s)", sa, da); - -- adapter = manager_find_adapter(sba); -+ adapter = manager_find_adapter(&BDADDR(index)); - if (adapter) - device = adapter_find_device(adapter, da); - else - device = NULL; - - memset(&req, 0, sizeof(req)); - bacpy(&req.bdaddr, dba); - -- err = ioctl(dev, HCIGETAUTHINFO, (unsigned long) &req); -+ err = ioctl(SK(index), HCIGETAUTHINFO, (unsigned long) &req); - if (err < 0) { - if (errno != EINVAL) - DBG("HCIGETAUTHINFO failed %s (%d)", - strerror(errno), errno); - req.type = 0x00; -@@ -378,244 +378,232 @@ static void link_key_request(int dev, bd - - DBG("kernel auth requirements = 0x%02x", req.type); - - if (main_opts.debug_keys && device && device_get_debug_key(device, key)) - type = 0x03; -- else if (read_link_key(sba, dba, key, &type) < 0 || type == 0x03) { -+ else if (read_link_key(&BDADDR(index), dba, key, &type) < 0 || -+ type == 0x03) { - /* Link key not found */ -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba); -+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, -+ 6, dba); - return; - } - - /* Link key found */ - - DBG("link key type = 0x%02x", type); - - /* Don't use unauthenticated combination keys if MITM is - * required */ - if (type == 0x04 && req.type != 0xff && (req.type & 0x01)) -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, -+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, - 6, dba); - else { - link_key_reply_cp lr; - - memcpy(lr.link_key, key, 16); - bacpy(&lr.bdaddr, dba); - -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, -+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_LINK_KEY_REPLY, - LINK_KEY_REPLY_CP_SIZE, &lr); - } - } - --static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) -+static void link_key_notify(int index, void *ptr) - { - evt_link_key_notify *evt = ptr; - bdaddr_t *dba = &evt->bdaddr; - char sa[18], da[18]; -- int dev_id, err; -+ int err; - unsigned char old_key[16]; - uint8_t old_key_type; - -- ba2str(sba, sa); ba2str(dba, da); -+ ba2str(&BDADDR(index), sa); ba2str(dba, da); - info("link_key_notify (sba=%s, dba=%s, type=%d)", sa, da, - evt->key_type); - -- err = read_link_key(sba, dba, old_key, &old_key_type); -+ err = read_link_key(&BDADDR(index), dba, old_key, &old_key_type); - if (err < 0) - old_key_type = 0xff; - -- dev_id = hci_devid(sa); -- if (dev_id < 0) -- err = -errno; -- else { -- err = btd_event_link_key_notify(sba, dba, evt->link_key, -- evt->key_type, -- io_data[dev_id].pin_length, -- old_key_type); -- io_data[dev_id].pin_length = -1; -- } -+ err = btd_event_link_key_notify(&BDADDR(index), dba, evt->link_key, -+ evt->key_type, PIN_LENGTH(index), -+ old_key_type); -+ PIN_LENGTH(index) = -1; - - if (err < 0) { - uint16_t handle; - - if (err == -ENODEV) -- btd_event_bonding_process_complete(sba, dba, -+ btd_event_bonding_process_complete(&BDADDR(index), dba, - HCI_OE_LOW_RESOURCES); - else -- btd_event_bonding_process_complete(sba, dba, -+ btd_event_bonding_process_complete(&BDADDR(index), dba, - HCI_MEMORY_FULL); - -- if (get_handle(dev, sba, dba, &handle) == 0) { -+ if (get_handle(index, dba, &handle) == 0) { - disconnect_cp cp; - - memset(&cp, 0, sizeof(cp)); - cp.handle = htobs(handle); - cp.reason = HCI_OE_LOW_RESOURCES; - -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_DISCONNECT, -+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_DISCONNECT, - DISCONNECT_CP_SIZE, &cp); - } - } - } - --static void return_link_keys(int dev, bdaddr_t *sba, void *ptr) -+static void return_link_keys(int index, void *ptr) - { - evt_return_link_keys *evt = ptr; - uint8_t num = evt->num_keys; - unsigned char key[16]; - char sa[18], da[18]; - bdaddr_t dba; - int i; - -- ba2str(sba, sa); -+ ba2str(&BDADDR(index), sa); - ptr++; - - for (i = 0; i < num; i++) { - bacpy(&dba, ptr); ba2str(&dba, da); - memcpy(key, ptr + 6, 16); - - info("return_link_keys (sba=%s, dba=%s)", sa, da); - -- btd_event_returned_link_key(sba, &dba); -+ btd_event_returned_link_key(&BDADDR(index), &dba); - - ptr += 22; - } - } - - /* Simple Pairing handling */ - --static void user_confirm_request(int dev, bdaddr_t *sba, void *ptr) -+static void user_confirm_request(int index, void *ptr) - { - evt_user_confirm_request *req = ptr; - -- if (btd_event_user_confirm(sba, &req->bdaddr, -+ if (btd_event_user_confirm(&BDADDR(index), &req->bdaddr, - btohl(req->passkey)) < 0) -- hci_send_cmd(dev, OGF_LINK_CTL, -+ hci_send_cmd(SK(index), OGF_LINK_CTL, - OCF_USER_CONFIRM_NEG_REPLY, 6, ptr); - } - --static void user_passkey_request(int dev, bdaddr_t *sba, void *ptr) -+static void user_passkey_request(int index, void *ptr) - { - evt_user_passkey_request *req = ptr; - -- if (btd_event_user_passkey(sba, &req->bdaddr) < 0) -- hci_send_cmd(dev, OGF_LINK_CTL, -+ if (btd_event_user_passkey(&BDADDR(index), &req->bdaddr) < 0) -+ hci_send_cmd(SK(index), OGF_LINK_CTL, - OCF_USER_PASSKEY_NEG_REPLY, 6, ptr); - } - --static void user_passkey_notify(int dev, bdaddr_t *sba, void *ptr) -+static void user_passkey_notify(int index, void *ptr) - { - evt_user_passkey_notify *req = ptr; - -- btd_event_user_notify(sba, &req->bdaddr, btohl(req->passkey)); -+ btd_event_user_notify(&BDADDR(index), &req->bdaddr, -+ btohl(req->passkey)); - } - --static void remote_oob_data_request(int dev, bdaddr_t *sba, void *ptr) -+static void remote_oob_data_request(int index, void *ptr) - { -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr); -+ hci_send_cmd(SK(index), OGF_LINK_CTL, -+ OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr); - } - --static void io_capa_request(int dev, bdaddr_t *sba, bdaddr_t *dba) -+static void io_capa_request(int index, void *ptr) - { -+ bdaddr_t *dba = ptr; - char sa[18], da[18]; - uint8_t cap, auth; - -- ba2str(sba, sa); ba2str(dba, da); -+ ba2str(&BDADDR(index), sa); ba2str(dba, da); - info("io_capa_request (sba=%s, dba=%s)", sa, da); - -- if (btd_event_get_io_cap(sba, dba, &cap, &auth) < 0) { -+ if (btd_event_get_io_cap(&BDADDR(index), dba, &cap, &auth) < 0) { - io_capability_neg_reply_cp cp; - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, dba); - cp.reason = HCI_PAIRING_NOT_ALLOWED; -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_NEG_REPLY, -+ hci_send_cmd(SK(index), OGF_LINK_CTL, -+ OCF_IO_CAPABILITY_NEG_REPLY, - IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); - } else { - io_capability_reply_cp cp; - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, dba); - cp.capability = cap; - cp.oob_data = 0x00; - cp.authentication = auth; -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, -+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, - IO_CAPABILITY_REPLY_CP_SIZE, &cp); - } - } - --static void io_capa_response(int dev, bdaddr_t *sba, void *ptr) -+static void io_capa_response(int index, void *ptr) - { - evt_io_capability_response *evt = ptr; - char sa[18], da[18]; - -- ba2str(sba, sa); ba2str(&evt->bdaddr, da); -+ ba2str(&BDADDR(index), sa); ba2str(&evt->bdaddr, da); - info("io_capa_response (sba=%s, dba=%s)", sa, da); - -- btd_event_set_io_cap(sba, &evt->bdaddr, -+ btd_event_set_io_cap(&BDADDR(index), &evt->bdaddr, - evt->capability, evt->authentication); - } - - /* PIN code handling */ - --void set_pin_length(bdaddr_t *sba, int length) --{ -- char addr[18]; -- int dev_id; -- -- ba2str(sba, addr); -- dev_id = hci_devid(addr); -- -- if (dev_id >= 0) -- io_data[dev_id].pin_length = length; --} -- --static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) -+static void pin_code_request(int index, bdaddr_t *dba) - { - pin_code_reply_cp pr; - struct hci_conn_info_req *cr; - struct hci_conn_info *ci; - char sa[18], da[18], pin[17]; - int pinlen; - - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, dba); - -- ba2str(sba, sa); ba2str(dba, da); -+ ba2str(&BDADDR(index), sa); ba2str(dba, da); - info("pin_code_request (sba=%s, dba=%s)", sa, da); - - cr = g_malloc0(sizeof(*cr) + sizeof(*ci)); - - bacpy(&cr->bdaddr, dba); - cr->type = ACL_LINK; -- if (ioctl(dev, HCIGETCONNINFO, (unsigned long) cr) < 0) { -+ if (ioctl(SK(index), HCIGETCONNINFO, (unsigned long) cr) < 0) { - error("Can't get conn info: %s (%d)", strerror(errno), errno); - goto reject; - } - ci = cr->conn_info; - - memset(pin, 0, sizeof(pin)); -- pinlen = read_pin_code(sba, dba, pin); -+ pinlen = read_pin_code(&BDADDR(index), dba, pin); - - if (pinlen > 0) { -- set_pin_length(sba, pinlen); -+ PIN_LENGTH(index) = pinlen; - memcpy(pr.pin_code, pin, pinlen); - pr.pin_len = pinlen; -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, -- PIN_CODE_REPLY_CP_SIZE, &pr); -+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_PIN_CODE_REPLY, -+ PIN_CODE_REPLY_CP_SIZE, &pr); - } else { - /* Request PIN from passkey agent */ -- if (btd_event_request_pin(dev, sba, ci) < 0) -+ if (btd_event_request_pin(&BDADDR(index), ci) < 0) - goto reject; - } - - g_free(cr); - - return; - - reject: - g_free(cr); - -- hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); -+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); - } - - static void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic) - { - struct btd_adapter *adapter; -@@ -663,20 +651,22 @@ static void inquiry_complete(bdaddr_t *l - state = adapter_get_state(adapter); - state &= ~(STATE_STDINQ | STATE_PINQ); - adapter_set_state(adapter, state); - } - --static inline void remote_features_notify(int dev, bdaddr_t *sba, void *ptr) -+static inline void remote_features_notify(int index, void *ptr) - { - evt_remote_host_features_notify *evt = ptr; - - if (evt->features[0] & 0x01) -- btd_event_set_legacy_pairing(sba, &evt->bdaddr, FALSE); -+ btd_event_set_legacy_pairing(&BDADDR(index), &evt->bdaddr, -+ FALSE); - else -- btd_event_set_legacy_pairing(sba, &evt->bdaddr, TRUE); -+ btd_event_set_legacy_pairing(&BDADDR(index), &evt->bdaddr, -+ TRUE); - -- write_features_info(sba, &evt->bdaddr, NULL, evt->features); -+ write_features_info(&BDADDR(index), &evt->bdaddr, NULL, evt->features); - } - - static void write_le_host_complete(bdaddr_t *sba, uint8_t status) - { - struct btd_adapter *adapter; -@@ -712,140 +702,163 @@ static void read_local_ext_features_comp - return; - - btd_adapter_update_local_ext_features(adapter, rp->features); - } - --static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) -+static void read_bd_addr_complete(int index, read_bd_addr_rp *rp) -+{ -+ if (rp->status) -+ return; -+ -+ bacpy(&BDADDR(index), &rp->bdaddr); -+ -+ if (READY(index)) -+ return; -+ -+ READY(index) = TRUE; -+ -+ info("Got bdaddr for hci%d", index); -+ -+ if (UP(index)) -+ manager_start_adapter(index); -+} -+ -+static inline void cmd_status(int index, void *ptr) - { - evt_cmd_status *evt = ptr; - uint16_t opcode = btohs(evt->opcode); - - if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) -- start_inquiry(sba, evt->status, FALSE); -+ start_inquiry(&BDADDR(index), evt->status, FALSE); - } - --static void read_scan_complete(bdaddr_t *sba, uint8_t status, void *ptr) -+static void read_scan_complete(int index, uint8_t status, void *ptr) - { - struct btd_adapter *adapter; - read_scan_enable_rp *rp = ptr; - -- adapter = manager_find_adapter(sba); -+ adapter = manager_find_adapter(&BDADDR(index)); - - if (!adapter) { - error("Unable to find matching adapter"); - return; - } - - adapter_mode_changed(adapter, rp->enable); - } - --static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) -+static inline void cmd_complete(int index, void *ptr) - { - evt_cmd_complete *evt = ptr; - uint16_t opcode = btohs(evt->opcode); - uint8_t status = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE); - - switch (opcode) { - case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_EXT_FEATURES): - ptr += sizeof(evt_cmd_complete); -- read_local_ext_features_complete(sba, ptr); -+ read_local_ext_features_complete(&BDADDR(index), ptr); -+ break; -+ case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR): -+ ptr += sizeof(evt_cmd_complete); -+ read_bd_addr_complete(index, ptr); - break; - case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY): -- start_inquiry(sba, status, TRUE); -+ start_inquiry(&BDADDR(index), status, TRUE); - break; - case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY): -- inquiry_complete(sba, status, TRUE); -+ inquiry_complete(&BDADDR(index), status, TRUE); - break; - case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): -- inquiry_complete(sba, status, FALSE); -+ inquiry_complete(&BDADDR(index), status, FALSE); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED): -- write_le_host_complete(sba, status); -+ write_le_host_complete(&BDADDR(index), status); - break; - case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE): -- btd_event_le_set_scan_enable_complete(sba, status); -+ btd_event_le_set_scan_enable_complete(&BDADDR(index), status); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): -- adapter_setname_complete(sba, status); -+ adapter_setname_complete(&BDADDR(index), status); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): -- btd_event_setscan_enable_complete(sba); -+ btd_event_setscan_enable_complete(&BDADDR(index)); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SCAN_ENABLE): - ptr += sizeof(evt_cmd_complete); -- read_scan_complete(sba, status, ptr); -+ read_scan_complete(index, status, ptr); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV): -- adapter_set_class_complete(sba, status); -+ adapter_set_class_complete(&BDADDR(index), status); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SIMPLE_PAIRING_MODE): -- btd_event_write_simple_pairing_mode_complete(sba); -+ btd_event_write_simple_pairing_mode_complete(&BDADDR(index)); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SIMPLE_PAIRING_MODE): - ptr += sizeof(evt_cmd_complete); -- btd_event_read_simple_pairing_mode_complete(sba, ptr); -+ btd_event_read_simple_pairing_mode_complete(&BDADDR(index), -+ ptr); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_NAME): - ptr += sizeof(evt_cmd_complete); -- adapter_update_local_name(sba, status, ptr); -+ adapter_update_local_name(&BDADDR(index), status, ptr); - break; - case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL): - ptr += sizeof(evt_cmd_complete); -- adapter_update_tx_power(sba, status, ptr); -+ adapter_update_tx_power(&BDADDR(index), status, ptr); - break; - }; - } - --static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr) -+static inline void remote_name_information(int index, void *ptr) - { - evt_remote_name_req_complete *evt = ptr; - char name[MAX_NAME_LENGTH + 1]; - - memset(name, 0, sizeof(name)); - - if (!evt->status) - memcpy(name, evt->name, MAX_NAME_LENGTH); - -- btd_event_remote_name(sba, &evt->bdaddr, evt->status, name); -+ btd_event_remote_name(&BDADDR(index), &evt->bdaddr, evt->status, name); - } - --static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr) -+static inline void remote_version_information(int index, void *ptr) - { - evt_read_remote_version_complete *evt = ptr; - bdaddr_t dba; - - if (evt->status) - return; - -- if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) -+ if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) - return; - -- write_version_info(sba, &dba, btohs(evt->manufacturer), -+ write_version_info(&BDADDR(index), &dba, btohs(evt->manufacturer), - evt->lmp_ver, btohs(evt->lmp_subver)); - } - --static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) -+static inline void inquiry_result(int index, int plen, void *ptr) - { - uint8_t num = *(uint8_t *) ptr++; - int i; - - for (i = 0; i < num; i++) { - inquiry_info *info = ptr; -- uint32_t class = info->dev_class[0] -- | (info->dev_class[1] << 8) -- | (info->dev_class[2] << 16); -+ uint32_t class = info->dev_class[0] | -+ (info->dev_class[1] << 8) | -+ (info->dev_class[2] << 16); - -- btd_event_inquiry_result(sba, &info->bdaddr, class, 0, NULL); -+ btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, class, -+ 0, NULL); - -- update_lastseen(sba, &info->bdaddr); -+ update_lastseen(&BDADDR(index), &info->bdaddr); - - ptr += INQUIRY_INFO_SIZE; - } - } - --static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, -- int plen, void *ptr) -+static inline void inquiry_result_with_rssi(int index, int plen, void *ptr) - { - uint8_t num = *(uint8_t *) ptr++; - int i; - - if (!num) -@@ -853,99 +866,97 @@ static inline void inquiry_result_with_r - - if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { - for (i = 0; i < num; i++) { - inquiry_info_with_rssi_and_pscan_mode *info = ptr; - uint32_t class = info->dev_class[0] -- | (info->dev_class[1] << 8) -- | (info->dev_class[2] << 16); -+ | (info->dev_class[1] << 8) -+ | (info->dev_class[2] << 16); - -- btd_event_inquiry_result(sba, &info->bdaddr, -+ btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, - class, info->rssi, NULL); - -- update_lastseen(sba, &info->bdaddr); -+ update_lastseen(&BDADDR(index), &info->bdaddr); - - ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; - } - } else { - for (i = 0; i < num; i++) { - inquiry_info_with_rssi *info = ptr; - uint32_t class = info->dev_class[0] -- | (info->dev_class[1] << 8) -- | (info->dev_class[2] << 16); -+ | (info->dev_class[1] << 8) -+ | (info->dev_class[2] << 16); - -- btd_event_inquiry_result(sba, &info->bdaddr, -+ btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, - class, info->rssi, NULL); - -- update_lastseen(sba, &info->bdaddr); -+ update_lastseen(&BDADDR(index), &info->bdaddr); - - ptr += INQUIRY_INFO_WITH_RSSI_SIZE; - } - } - } - --static inline void extended_inquiry_result(int dev, bdaddr_t *sba, -- int plen, void *ptr) -+static inline void extended_inquiry_result(int index, int plen, void *ptr) - { - uint8_t num = *(uint8_t *) ptr++; - int i; - - for (i = 0; i < num; i++) { - extended_inquiry_info *info = ptr; - uint32_t class = info->dev_class[0] -- | (info->dev_class[1] << 8) -- | (info->dev_class[2] << 16); -+ | (info->dev_class[1] << 8) -+ | (info->dev_class[2] << 16); - -- btd_event_inquiry_result(sba, &info->bdaddr, class, -+ btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, class, - info->rssi, info->data); - -- update_lastseen(sba, &info->bdaddr); -+ update_lastseen(&BDADDR(index), &info->bdaddr); - - ptr += EXTENDED_INQUIRY_INFO_SIZE; - } - } - --static inline void remote_features_information(int dev, bdaddr_t *sba, -- void *ptr) -+static inline void remote_features_information(int index, void *ptr) - { - evt_read_remote_features_complete *evt = ptr; - bdaddr_t dba; - - if (evt->status) - return; - -- if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) -+ if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) - return; - -- write_features_info(sba, &dba, evt->features, NULL); -+ write_features_info(&BDADDR(index), &dba, evt->features, NULL); - } - --static inline void conn_complete(int dev, int dev_id, bdaddr_t *sba, void *ptr) -+static inline void conn_complete(int index, void *ptr) - { - evt_conn_complete *evt = ptr; - char filename[PATH_MAX]; - char local_addr[18], peer_addr[18], *str; - struct btd_adapter *adapter; - -- adapter = manager_find_adapter(sba); -+ adapter = manager_find_adapter(&BDADDR(index)); - if (!adapter) { - error("Unable to find matching adapter"); - return; - } - - if (evt->link_type != ACL_LINK) - return; - -- btd_event_conn_complete(sba, evt->status, btohs(evt->handle), -- &evt->bdaddr); -+ btd_event_conn_complete(&BDADDR(index), evt->status, -+ btohs(evt->handle), &evt->bdaddr); - - if (evt->status) - return; - -- update_lastused(sba, &evt->bdaddr); -+ update_lastused(&BDADDR(index), &evt->bdaddr); - - /* check if the remote version needs be requested */ -- ba2str(sba, local_addr); -+ ba2str(&BDADDR(index), local_addr); - ba2str(&evt->bdaddr, peer_addr); - - create_name(filename, sizeof(filename), STORAGEDIR, local_addr, - "manufacturers"); - -@@ -955,46 +966,47 @@ static inline void conn_complete(int dev - TRUE); - else - free(str); - } - --static inline void disconn_complete(int dev, bdaddr_t *sba, void *ptr) -+static inline void disconn_complete(int index, void *ptr) - { - evt_disconn_complete *evt = ptr; - -- btd_event_disconn_complete(sba, evt->status, btohs(evt->handle), -- evt->reason); -+ btd_event_disconn_complete(&BDADDR(index), evt->status, -+ btohs(evt->handle), evt->reason); - } - --static inline void auth_complete(int dev, bdaddr_t *sba, void *ptr) -+static inline void auth_complete(int index, void *ptr) - { - evt_auth_complete *evt = ptr; - bdaddr_t dba; - -- if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) -+ if (get_bdaddr(index, btohs(evt->handle), &dba) < 0) - return; - -- btd_event_bonding_process_complete(sba, &dba, evt->status); -+ btd_event_bonding_process_complete(&BDADDR(index), &dba, evt->status); - } - --static inline void simple_pairing_complete(int dev, bdaddr_t *sba, void *ptr) -+static inline void simple_pairing_complete(int index, void *ptr) - { - evt_simple_pairing_complete *evt = ptr; - -- btd_event_simple_pairing_complete(sba, &evt->bdaddr, evt->status); -+ btd_event_simple_pairing_complete(&BDADDR(index), &evt->bdaddr, -+ evt->status); - } - --static inline void conn_request(int dev, bdaddr_t *sba, void *ptr) -+static inline void conn_request(int index, void *ptr) - { - evt_conn_request *evt = ptr; - uint32_t class = evt->dev_class[0] | (evt->dev_class[1] << 8) - | (evt->dev_class[2] << 16); - -- btd_event_remote_class(sba, &evt->bdaddr, class); -+ btd_event_remote_class(&BDADDR(index), &evt->bdaddr, class); - } - --static inline void le_metaevent(int dev, bdaddr_t *sba, void *ptr) -+static inline void le_metaevent(int index, void *ptr) - { - evt_le_meta_event *meta = ptr; - le_advertising_info *info; - uint8_t *rssi, num, i; - -@@ -1007,65 +1019,51 @@ static inline void le_metaevent(int dev, - info = (le_advertising_info *) (meta->data + 1); - - for (i = 0; i < num; i++) { - /* RSSI is last byte of the advertising report event */ - rssi = info->data + info->length; -- btd_event_inquiry_result(sba, &info->bdaddr, 0, *rssi, NULL); -+ btd_event_inquiry_result(&BDADDR(index), &info->bdaddr, 0, -+ *rssi, NULL); - info = (le_advertising_info *) (rssi + 1); - } - } - --static void stop_hci_dev(int hdev) -+static void stop_hci_dev(int index) - { -- GIOChannel *chan = io_data[hdev].channel; -+ GIOChannel *chan = CHANNEL(index); - - if (!chan) - return; - -- info("Stopping hci%d event socket", hdev); -- -- g_source_remove(io_data[hdev].watch_id); -- g_io_channel_unref(io_data[hdev].channel); -- io_data[hdev].watch_id = -1; -- io_data[hdev].channel = NULL; -- io_data[hdev].pin_length = -1; --} -- --static void delete_channel(GIOChannel *chan) --{ -- int i; -- -- /* Look for the GIOChannel in the table */ -- for (i = 0; i < HCI_MAX_DEV; i++) -- if (io_data[i].channel == chan) { -- stop_hci_dev(i); -- return; -- } -+ info("Stopping hci%d event socket", index); - -- error("IO channel not found in the io_data table"); -+ g_source_remove(WATCH_ID(index)); -+ g_io_channel_unref(CHANNEL(index)); -+ hci_close_dev(SK(index)); -+ init_dev_info(index, -1); - } - - static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, - gpointer data) - { - unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; -- struct hci_dev_info *di = data; -- int type, dev; -+ int type, index = GPOINTER_TO_INT(data); -+ struct hci_dev_info di; - size_t len; - hci_event_hdr *eh; - GIOError err; - evt_cmd_status *evt; - - if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { -- delete_channel(chan); -+ stop_hci_dev(index); - return FALSE; - } - - if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { - if (err == G_IO_ERROR_AGAIN) - return TRUE; -- delete_channel(chan); -+ stop_hci_dev(index); - return FALSE; - } - - type = *ptr++; - -@@ -1073,143 +1071,135 @@ static gboolean io_security_event(GIOCha - return TRUE; - - eh = (hci_event_hdr *) ptr; - ptr += HCI_EVENT_HDR_SIZE; - -- dev = g_io_channel_unix_get_fd(chan); -- -- ioctl(dev, HCIGETDEVINFO, (void *) di); -+ memset(&di, 0, sizeof(di)); -+ if (hci_devinfo(index, &di) == 0) { -+ bacpy(&BDADDR(index), &di.bdaddr); - -- if (ignore_device(di)) -- return TRUE; -+ if (ignore_device(&di)) -+ return TRUE; -+ } - - switch (eh->evt) { - case EVT_CMD_STATUS: -- cmd_status(dev, &di->bdaddr, ptr); -+ cmd_status(index, ptr); - break; - - case EVT_CMD_COMPLETE: -- cmd_complete(dev, &di->bdaddr, ptr); -+ cmd_complete(index, ptr); - break; - - case EVT_REMOTE_NAME_REQ_COMPLETE: -- remote_name_information(dev, &di->bdaddr, ptr); -+ remote_name_information(index, ptr); - break; - - case EVT_READ_REMOTE_VERSION_COMPLETE: -- remote_version_information(dev, &di->bdaddr, ptr); -+ remote_version_information(index, ptr); - break; - - case EVT_READ_REMOTE_FEATURES_COMPLETE: -- remote_features_information(dev, &di->bdaddr, ptr); -+ remote_features_information(index, ptr); - break; - - case EVT_REMOTE_HOST_FEATURES_NOTIFY: -- remote_features_notify(dev, &di->bdaddr, ptr); -+ remote_features_notify(index, ptr); - break; - - case EVT_INQUIRY_COMPLETE: - evt = (evt_cmd_status *) ptr; -- inquiry_complete(&di->bdaddr, evt->status, FALSE); -+ inquiry_complete(&BDADDR(index), evt->status, FALSE); - break; - - case EVT_INQUIRY_RESULT: -- inquiry_result(dev, &di->bdaddr, eh->plen, ptr); -+ inquiry_result(index, eh->plen, ptr); - break; - - case EVT_INQUIRY_RESULT_WITH_RSSI: -- inquiry_result_with_rssi(dev, &di->bdaddr, eh->plen, ptr); -+ inquiry_result_with_rssi(index, eh->plen, ptr); - break; - - case EVT_EXTENDED_INQUIRY_RESULT: -- extended_inquiry_result(dev, &di->bdaddr, eh->plen, ptr); -+ extended_inquiry_result(index, eh->plen, ptr); - break; - - case EVT_CONN_COMPLETE: -- conn_complete(dev, di->dev_id, &di->bdaddr, ptr); -+ conn_complete(index, ptr); - break; - - case EVT_DISCONN_COMPLETE: -- disconn_complete(dev, &di->bdaddr, ptr); -+ disconn_complete(index, ptr); - break; - - case EVT_AUTH_COMPLETE: -- auth_complete(dev, &di->bdaddr, ptr); -+ auth_complete(index, ptr); - break; - - case EVT_SIMPLE_PAIRING_COMPLETE: -- simple_pairing_complete(dev, &di->bdaddr, ptr); -+ simple_pairing_complete(index, ptr); - break; - - case EVT_CONN_REQUEST: -- conn_request(dev, &di->bdaddr, ptr); -+ conn_request(index, ptr); - break; - case EVT_LE_META_EVENT: -- le_metaevent(dev, &di->bdaddr, ptr); -+ le_metaevent(index, ptr); - break; - case EVT_PIN_CODE_REQ: -- pin_code_request(dev, &di->bdaddr, (bdaddr_t *) ptr); -+ pin_code_request(index, (bdaddr_t *) ptr); - break; - - case EVT_LINK_KEY_REQ: -- link_key_request(dev, &di->bdaddr, (bdaddr_t *) ptr); -+ link_key_request(index, (bdaddr_t *) ptr); - break; - - case EVT_LINK_KEY_NOTIFY: -- link_key_notify(dev, &di->bdaddr, ptr); -+ link_key_notify(index, ptr); - break; - - case EVT_RETURN_LINK_KEYS: -- return_link_keys(dev, &di->bdaddr, ptr); -+ return_link_keys(index, ptr); - break; - - case EVT_IO_CAPABILITY_REQUEST: -- io_capa_request(dev, &di->bdaddr, (bdaddr_t *) ptr); -+ io_capa_request(index, ptr); - break; - - case EVT_IO_CAPABILITY_RESPONSE: -- io_capa_response(dev, &di->bdaddr, ptr); -+ io_capa_response(index, ptr); - break; - - case EVT_USER_CONFIRM_REQUEST: -- user_confirm_request(dev, &di->bdaddr, ptr); -+ user_confirm_request(index, ptr); - break; - - case EVT_USER_PASSKEY_REQUEST: -- user_passkey_request(dev, &di->bdaddr, ptr); -+ user_passkey_request(index, ptr); - break; - - case EVT_USER_PASSKEY_NOTIFY: -- user_passkey_notify(dev, &di->bdaddr, ptr); -+ user_passkey_notify(index, ptr); - break; - - case EVT_REMOTE_OOB_DATA_REQUEST: -- remote_oob_data_request(dev, &di->bdaddr, ptr); -+ remote_oob_data_request(index, ptr); - break; - } - - return TRUE; - } - --static void init_hci_dev(int hdev) -+static void start_hci_dev(int index) - { -- GIOChannel *chan = io_data[hdev].channel; -- struct hci_dev_info *di; -+ GIOChannel *chan = CHANNEL(index); - struct hci_filter flt; -- read_stored_link_key_cp cp; -- int dev; - - if (chan) - return; - -- info("Starting security manager %d", hdev); -- -- if ((dev = hci_open_dev(hdev)) < 0) { -- error("Can't open device hci%d: %s (%d)", -- hdev, strerror(errno), errno); -- return; -- } -+ info("Listening for HCI events on hci%d", index); - - /* Set filter */ - hci_filter_clear(&flt); - hci_filter_set_ptype(HCI_EVENT_PKT, &flt); - hci_filter_set_event(EVT_CMD_STATUS, &flt); -@@ -1237,42 +1227,24 @@ static void init_hci_dev(int hdev) - hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); - hci_filter_set_event(EVT_CONN_REQUEST, &flt); - hci_filter_set_event(EVT_CONN_COMPLETE, &flt); - hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); - hci_filter_set_event(EVT_LE_META_EVENT, &flt); -- if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { -+ if (setsockopt(SK(index), SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { - error("Can't set filter on hci%d: %s (%d)", -- hdev, strerror(errno), errno); -- close(dev); -- return; -- } -- -- di = g_new(struct hci_dev_info, 1); -- if (hci_devinfo(hdev, di) < 0) { -- error("Can't get device info: %s (%d)", -- strerror(errno), errno); -- close(dev); -- g_free(di); -+ index, strerror(errno), errno); - return; - } - -- chan = g_io_channel_unix_new(dev); -- g_io_channel_set_close_on_unref(chan, TRUE); -- io_data[hdev].watch_id = g_io_add_watch_full(chan, G_PRIORITY_LOW, -+ chan = g_io_channel_unix_new(SK(index)); -+ WATCH_ID(index) = g_io_add_watch_full(chan, G_PRIORITY_LOW, - G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, -- io_security_event, di, (GDestroyNotify) g_free); -- io_data[hdev].channel = chan; -- io_data[hdev].pin_length = -1; -- -- if (ignore_device(di)) -- return; -+ io_security_event, GINT_TO_POINTER(index), -+ NULL); -+ CHANNEL(index) = chan; -+ PIN_LENGTH(index) = -1; - -- bacpy(&cp.bdaddr, BDADDR_ANY); -- cp.read_all = 1; -- -- hci_send_cmd(dev, OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, -- READ_STORED_LINK_KEY_CP_SIZE, (void *) &cp); - } - - /* End of HCI event callbacks */ - - static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data) -@@ -1303,10 +1275,11 @@ static void at_child_exit(void) - - static void device_devup_setup(int index) - { - struct hci_dev_info di; - uint16_t policy; -+ read_stored_link_key_cp cp; - - if (hci_devinfo(index, &di) < 0) - return; - - if (ignore_device(&di)) -@@ -1326,15 +1299,17 @@ static void device_devup_setup(int index - /* Set default link policy */ - policy = htobs(main_opts.link_policy); - hci_send_cmd(SK(index), OGF_LINK_POLICY, - OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy); - -- init_hci_dev(index); -+ bacpy(&cp.bdaddr, BDADDR_ANY); -+ cp.read_all = 1; -+ hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, -+ READ_STORED_LINK_KEY_CP_SIZE, (void *) &cp); - -- /* Return value 1 means ioctl(DEVDOWN) was performed */ -- if (manager_start_adapter(index) == 1) -- stop_hci_dev(index); -+ if (READY(index)) -+ manager_start_adapter(index); - } - - static void init_device(int index) - { - struct hci_dev_req dr; -@@ -1353,10 +1328,11 @@ static void init_device(int index) - max_dev = index; - devs = g_realloc(devs, sizeof(devs[0]) * (max_dev + 1)); - } - - init_dev_info(index, dd); -+ start_hci_dev(index); - - /* Do initialization in the separate process */ - pid = fork(); - switch (pid) { - case 0: -@@ -1433,24 +1409,27 @@ static void device_event(int event, int - device_devreg_setup(index); - break; - - case HCI_DEV_UNREG: - info("HCI dev %d unregistered", index); -- hci_close_dev(SK(index)); -- init_dev_info(index, -1); -+ stop_hci_dev(index); - manager_unregister_adapter(index); - break; - - case HCI_DEV_UP: - info("HCI dev %d up", index); -+ UP(index) = TRUE; - device_devup_setup(index); - break; - - case HCI_DEV_DOWN: - info("HCI dev %d down", index); -- manager_stop_adapter(index); -- stop_hci_dev(index); -+ UP(index) = FALSE; -+ if (READY(index)) { -+ manager_stop_adapter(index); -+ READY(index) = FALSE; -+ } - break; - } - } - - static gboolean init_known_adapters(gpointer user_data) -@@ -2140,10 +2119,12 @@ static int hciops_pincode_reply(int inde - - if (pin) { - pin_code_reply_cp pr; - size_t len = strlen(pin); - -+ PIN_LENGTH(index) = len; -+ - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, bdaddr); - memcpy(pr.pin_code, pin, len); - pr.pin_len = len; - err = hci_send_cmd(SK(index), OGF_LINK_CTL, -Index: b/plugins/mgmtops.c -=================================================================== ---- a/plugins/mgmtops.c -+++ b/plugins/mgmtops.c -@@ -66,13 +66,13 @@ static uint8_t mgmt_version = 0; - static uint16_t mgmt_revision = 0; - - static void read_version_complete(int sk, void *buf, size_t len) - { - struct mgmt_hdr hdr; -- struct mgmt_read_version_rp *rp = buf; -+ struct mgmt_rp_read_version *rp = buf; - -- if (len < MGMT_READ_VERSION_RP_SIZE) { -+ if (len < sizeof(*rp)) { - error("Too small read version complete event"); - return; - } - - mgmt_revision = btohs(bt_get_unaligned(&rp->revision)); -@@ -96,17 +96,19 @@ static void add_controller(uint16_t inde - } - - memset(&controllers[index], 0, sizeof(struct controller_info)); - - controllers[index].valid = TRUE; -+ -+ DBG("Added controller %u", index); - } - - static void read_info(int sk, uint16_t index) - { -- char buf[MGMT_HDR_SIZE + MGMT_READ_INFO_CP_SIZE]; -+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_read_info)]; - struct mgmt_hdr *hdr = (void *) buf; -- struct mgmt_read_info_cp *cp = (void *) &buf[sizeof(*hdr)]; -+ struct mgmt_cp_read_info *cp = (void *) &buf[sizeof(*hdr)]; - - memset(buf, 0, sizeof(buf)); - hdr->opcode = MGMT_OP_READ_INFO; - hdr->len = htobs(sizeof(*cp)); - -@@ -115,15 +117,61 @@ static void read_info(int sk, uint16_t i - if (write(sk, buf, sizeof(buf)) < 0) - error("Unable to send read_info command: %s (%d)", - strerror(errno), errno); - } - -+static void mgmt_index_added(int sk, void *buf, size_t len) -+{ -+ struct mgmt_ev_index_added *ev = buf; -+ uint16_t index; -+ -+ if (len < sizeof(*ev)) { -+ error("Too small index added event"); -+ return; -+ } -+ -+ index = btohs(bt_get_unaligned(&ev->index)); -+ -+ add_controller(index); -+ read_info(sk, index); -+} -+ -+static void remove_controller(uint16_t index) -+{ -+ if (index > max_index) -+ return; -+ -+ if (!controllers[index].valid) -+ return; -+ -+ manager_unregister_adapter(index); -+ -+ memset(&controllers[index], 0, sizeof(struct controller_info)); -+ -+ DBG("Removed controller %u", index); -+} -+ -+static void mgmt_index_removed(int sk, void *buf, size_t len) -+{ -+ struct mgmt_ev_index_removed *ev = buf; -+ uint16_t index; -+ -+ if (len < sizeof(*ev)) { -+ error("Too small index removed event"); -+ return; -+ } -+ -+ index = btohs(bt_get_unaligned(&ev->index)); -+ -+ remove_controller(index); -+} -+ - static void read_mode(int sk, uint16_t index) - { -- char buf[MGMT_HDR_SIZE + MGMT_READ_MODE_CP_SIZE]; -+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_read_mode)]; - struct mgmt_hdr *hdr = (void *) buf; -- struct mgmt_read_mode_cp *cp = (void *) &buf[sizeof(*hdr)]; -+ struct mgmt_cp_read_mode *cp = (void *) &buf[sizeof(*hdr)]; - - memset(buf, 0, sizeof(buf)); - hdr->opcode = MGMT_OP_READ_MODE; - hdr->len = htobs(sizeof(*cp)); - -@@ -134,46 +182,44 @@ static void read_mode(int sk, uint16_t i - strerror(errno), errno); - } - - static void read_index_list_complete(int sk, void *buf, size_t len) - { -- struct mgmt_read_index_list_rp *rp = buf; -+ struct mgmt_rp_read_index_list *rp = buf; - uint16_t num; - int i; - -- if (len < MGMT_READ_INDEX_LIST_RP_SIZE) { -+ if (len < sizeof(*rp)) { - error("Too small read index list complete event"); - return; - } - - num = btohs(bt_get_unaligned(&rp->num_controllers)); - -- if (num * sizeof(uint16_t) + MGMT_READ_INDEX_LIST_RP_SIZE != len) { -+ if (num * sizeof(uint16_t) + sizeof(*rp) != len) { - error("Incorrect packet size for index list event"); - return; - } - - for (i = 0; i < num; i++) { - uint16_t index; - - index = btohs(bt_get_unaligned(&rp->index[i])); - -- DBG("Found controller %u", index); -- - add_controller(index); - read_info(sk, index); - } - } - - static void read_info_complete(int sk, void *buf, size_t len) - { -- struct mgmt_read_info_rp *rp = buf; -+ struct mgmt_rp_read_info *rp = buf; - struct controller_info *info; - uint16_t index; - char addr[18]; - -- if (len < MGMT_READ_INFO_RP_SIZE) { -+ if (len < sizeof(*rp)) { - error("Too small read info complete event"); - return; - } - - if (rp->status != 0) { -@@ -199,17 +245,17 @@ static void read_info_complete(int sk, v - read_mode(sk, index); - } - - static void read_mode_complete(int sk, void *buf, size_t len) - { -- struct mgmt_read_mode_rp *rp = buf; -+ struct mgmt_rp_read_mode *rp = buf; - struct controller_info *info; - uint16_t index; - -- if (len < MGMT_READ_MODE_RP_SIZE) { -- error("Too small read mode complete event (%zu != %d)", -- len, MGMT_READ_MODE_RP_SIZE); -+ if (len < sizeof(*rp)) { -+ error("Too small read mode complete event (%zu != %zu)", -+ len, sizeof(*rp)); - return; - } - - if (rp->status != 0) { - error("Reading controller mode failed: %s (%u)", -@@ -226,15 +272,17 @@ static void read_mode_complete(int sk, v - info = &controllers[index]; - info->enabled = rp->enabled ? TRUE : FALSE; - info->mode = rp->mode; - - DBG("hci%u enabled %u mode %u", index, info->enabled, info->mode); -+ -+ manager_register_adapter(index, info->enabled); - } - - static void mgmt_cmd_complete(int sk, void *buf, size_t len) - { -- struct mgmt_cmd_complete_ev *ev = buf; -+ struct mgmt_ev_cmd_complete *ev = buf; - uint16_t opcode; - - DBG(""); - - if (len < sizeof(*ev)) { -@@ -263,16 +311,36 @@ static void mgmt_cmd_complete(int sk, vo - } - } - - static void mgmt_cmd_status(int sk, void *buf, size_t len) - { -- DBG(""); -+ struct mgmt_ev_cmd_status *ev = buf; -+ uint16_t opcode; -+ -+ if (len < sizeof(*ev)) { -+ error("Too small management command status event packet"); -+ return; -+ } -+ -+ opcode = btohs(bt_get_unaligned(&ev->opcode)); -+ -+ DBG("status %u opcode %u", ev->status, opcode); - } - - static void mgmt_controller_error(int sk, void *buf, size_t len) - { -- DBG(""); -+ struct mgmt_ev_controller_error *ev = buf; -+ uint16_t index; -+ -+ if (len < sizeof(*ev)) { -+ error("Too small management controller error event packet"); -+ return; -+ } -+ -+ index = btohs(bt_get_unaligned(&ev->index)); -+ -+ DBG("index %u error_code %u", index, ev->error_code); - } - - static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data) - { - char buf[MGMT_BUF_SIZE]; -@@ -323,10 +391,16 @@ static gboolean mgmt_event(GIOChannel *i - mgmt_cmd_status(sk, buf + MGMT_HDR_SIZE, len); - break; - case MGMT_EV_CONTROLLER_ERROR: - mgmt_controller_error(sk, buf + MGMT_HDR_SIZE, len); - break; -+ case MGMT_EV_INDEX_ADDED: -+ mgmt_index_added(sk, buf + MGMT_HDR_SIZE, len); -+ break; -+ case MGMT_EV_INDEX_REMOVED: -+ mgmt_index_removed(sk, buf + MGMT_HDR_SIZE, len); -+ break; - default: - error("Unknown Management opcode %u", opcode); - break; - } - -Index: b/src/agent.c -=================================================================== ---- a/src/agent.c -+++ b/src/agent.c -@@ -409,12 +409,10 @@ static void pincode_reply(DBusPendingCal - cb(agent, &err, NULL, req->user_data); - dbus_error_free(&err); - goto done; - } - -- set_pin_length(&sba, len); -- - cb(agent, NULL, pin, req->user_data); - - done: - if (message) - dbus_message_unref(message); -Index: b/src/event.c -=================================================================== ---- a/src/event.c -+++ b/src/event.c -@@ -114,19 +114,18 @@ static void pincode_cb(struct agent *age - err = btd_adapter_pincode_reply(adapter, &dba, pincode); - if (err < 0) - goto fail; - - adapter_get_address(adapter, &sba); -- set_pin_length(&sba, strlen(pincode)); - - return; - - fail: - error("Sending PIN code reply failed: %s (%d)", strerror(-err), -err); - } - --int btd_event_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci) -+int btd_event_request_pin(bdaddr_t *sba, struct hci_conn_info *ci) - { - struct btd_adapter *adapter; - struct btd_device *device; - - if (!get_adapter_and_device(sba, &ci->bdaddr, &adapter, &device, TRUE)) -Index: b/src/event.h -=================================================================== ---- a/src/event.h -+++ b/src/event.h -@@ -20,11 +20,11 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - --int btd_event_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci); -+int btd_event_request_pin(bdaddr_t *sba, struct hci_conn_info *ci); - void btd_event_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi, uint8_t *data); - void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean legacy); - void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class); - void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char *name); - void btd_event_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, bdaddr_t *peer); -Index: b/src/hcid.h -=================================================================== ---- a/src/hcid.h -+++ b/src/hcid.h -@@ -75,12 +75,10 @@ enum { - extern struct main_opts main_opts; - - void btd_start_exit_timer(void); - void btd_stop_exit_timer(void); - --void set_pin_length(bdaddr_t *sba, int length); -- - gboolean plugin_init(GKeyFile *config, const char *enable, - const char *disable); - void plugin_cleanup(void); - - void rfkill_init(void); diff --git a/bluez-4.78.tar.bz2 b/bluez-4.78.tar.bz2 deleted file mode 100644 index 2f84789..0000000 --- a/bluez-4.78.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea716f8f12a1ef70f01e31a0693df2cd04113931635a0cb861676e37d605edb9 -size 885309 diff --git a/bluez-4.79.tar.bz2 b/bluez-4.79.tar.bz2 new file mode 100644 index 0000000..7a6a7e9 --- /dev/null +++ b/bluez-4.79.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8b284fdbbcb4bf827c3dafc0f4a494ab7687059717b67b8e96436f29e55c55e +size 885026 diff --git a/bluez-gstreamer.changes b/bluez-gstreamer.changes index 16e8779..e056f76 100644 --- a/bluez-gstreamer.changes +++ b/bluez-gstreamer.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Nov 9 21:36:56 UTC 2010 - seife@opensuse.org + +- update to bluez-4.79: + - Fix issue with adapter initialization race condition. + - Update new Bluetooth Management interface support. + ------------------------------------------------------------------- Mon Nov 8 09:32:16 UTC 2010 - seife@opensuse.org diff --git a/bluez-gstreamer.spec b/bluez-gstreamer.spec index 4203715..a5a4941 100644 --- a/bluez-gstreamer.spec +++ b/bluez-gstreamer.spec @@ -28,7 +28,7 @@ BuildRequires: glib2-devel libnl-devel libusb-devel BuildRequires: alsa-devel libsndfile-devel pkg-config udev BuildRequires: gstreamer-0_10-devel gstreamer-0_10-plugins-base-devel Url: http://www.bluez.org -Version: 4.78 +Version: 4.79 Release: 1 Summary: Bluetooth Sound Support Group: Productivity/Multimedia/Sound/Utilities @@ -40,7 +40,6 @@ Source3: bluetooth.sysconfig Source4: bluetooth.sh Source6: README.SUSE Patch1: bluez-4.75-udev-use-helperscript.diff -Patch99: bluez-4.78-cc758c498ed98de11e890e56d4500ca85587bc07.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build Requires: libbluetooth3 = %{version} Provides: bluez-audio:%_libdir/gstreamer-0.10/libgstbluetooth.so @@ -65,7 +64,6 @@ Authors: %prep %setup -n bluez-%{version} -q %patch1 -p1 -%patch99 -p1 cp %{S:6} . %{?suse_update_config:%{suse_update_config -f . }} diff --git a/bluez.changes b/bluez.changes index 16e8779..e056f76 100644 --- a/bluez.changes +++ b/bluez.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Nov 9 21:36:56 UTC 2010 - seife@opensuse.org + +- update to bluez-4.79: + - Fix issue with adapter initialization race condition. + - Update new Bluetooth Management interface support. + ------------------------------------------------------------------- Mon Nov 8 09:32:16 UTC 2010 - seife@opensuse.org diff --git a/bluez.spec b/bluez.spec index 0e5a436..51adf5e 100644 --- a/bluez.spec +++ b/bluez.spec @@ -27,7 +27,7 @@ BuildRequires: libcap-ng-devel BuildRequires: glib2-devel libnl-devel libusb-devel BuildRequires: alsa-devel libsndfile-devel pkg-config udev Url: http://www.bluez.org -Version: 4.78 +Version: 4.79 Release: 1 Summary: Bluetooth Stack for Linux Group: Hardware/Mobile @@ -42,7 +42,6 @@ Source6: README.SUSE Source7: bluetooth.modprobe Patch1: bluez-4.75-udev-use-helperscript.diff Patch2: 001-remove-rule-dell-mouse.patch -Patch99: bluez-4.78-cc758c498ed98de11e890e56d4500ca85587bc07.diff # needed until next upstream release --seife BuildRoot: %{_tmppath}/%{name}-%{version}-build Provides: bluez-utils = 3.36 @@ -182,7 +181,6 @@ Authors: %setup -q %patch1 -p1 %patch2 -p1 -%patch99 -p1 cp %{S:6} . %{?suse_update_config:%{suse_update_config -f . }} mkdir dbus-apis