diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2012-03-03 00:29:08 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-03-03 00:29:08 +0200 |
commit | 7cfcd11a958f785dcb7bd053b19972df7ef10336 (patch) | |
tree | cec5a42df3e3ddf1f96c720004d9e44008f5b7b4 /plugins | |
parent | a5783264f7975b4e8f1d012bc033a10ee6e5b19c (diff) | |
download | bluez-7cfcd11a958f785dcb7bd053b19972df7ef10336.tar.gz bluez-7cfcd11a958f785dcb7bd053b19972df7ef10336.tar.xz bluez-7cfcd11a958f785dcb7bd053b19972df7ef10336.zip |
core: Remove name and class setting from btd_adapter_start()
Especially for mgmtops it's important that these values are pushed down
in the stack *before* powering on, so btd_adapter_start() is the wrong
place. Instead, adapter functions are added to hciops/mgmtops can fetch
these values at the right point during adapter init and push them down
in the stack (to the kernel).
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/hciops.c | 205 | ||||
-rw-r--r-- | plugins/mgmtops.c | 117 |
2 files changed, 171 insertions, 151 deletions
diff --git a/plugins/hciops.c b/plugins/hciops.c index 00b90061..3d68796f 100644 --- a/plugins/hciops.c +++ b/plugins/hciops.c @@ -647,13 +647,111 @@ static int hciops_stop_inquiry(int index) return 0; } +static void update_ext_inquiry_response(int index) +{ + struct dev_info *dev = &devs[index]; + write_ext_inquiry_response_cp cp; + + DBG("hci%d", index); + + if (!(dev->features[6] & LMP_EXT_INQ)) + return; + + if (dev->ssp_mode == 0) + return; + + if (dev->cache_enable) + return; + + memset(&cp, 0, sizeof(cp)); + + eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product, + dev->did_version, dev->uuids, cp.data); + + if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0) + return; + + memcpy(dev->eir, cp.data, sizeof(cp.data)); + + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, + OCF_WRITE_EXT_INQUIRY_RESPONSE, + WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0) + error("Unable to write EIR data: %s (%d)", + strerror(errno), errno); +} + +static int hciops_set_name(int index, const char *name) +{ + struct dev_info *dev = &devs[index]; + change_local_name_cp cp; + + DBG("hci%d, name %s", index, name); + + memset(&cp, 0, sizeof(cp)); + strncpy((char *) cp.name, name, sizeof(cp.name)); + + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, + CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0) + return -errno; + + memcpy(dev->name, cp.name, 248); + update_ext_inquiry_response(index); + + return 0; +} + +static int write_class(int index, uint32_t class) +{ + struct dev_info *dev = &devs[index]; + write_class_of_dev_cp cp; + + DBG("hci%d class 0x%06x", index, class); + + memcpy(cp.dev_class, &class, 3); + + if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, + WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0) + return -errno; + + dev->pending_cod = class; + + return 0; +} + +static int hciops_set_dev_class(int index, uint8_t major, uint8_t minor) +{ + struct dev_info *dev = &devs[index]; + int err; + + DBG("hci%d major %u minor %u", index, major, minor); + + /* Update only the major and minor class bits keeping remaining bits + * intact*/ + dev->wanted_cod &= 0xffe000; + dev->wanted_cod |= ((major & 0x1f) << 8) | minor; + + if (dev->wanted_cod == dev->current_cod || + dev->cache_enable || dev->pending_cod) + return 0; + + DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod); + + err = write_class(index, dev->wanted_cod); + if (err < 0) + error("Adapter class update failed: %s (%d)", + strerror(-err), -err); + + return err; +} + static gboolean init_adapter(int index) { struct dev_info *dev = &devs[index]; struct btd_adapter *adapter = NULL; gboolean existing_adapter = dev->registered; - uint8_t mode, on_mode; + uint8_t mode, on_mode, major, minor; gboolean pairable, discoverable; + const char *name; if (!dev->registered) { adapter = btd_manager_register_adapter(index, TRUE); @@ -679,6 +777,14 @@ static gboolean init_adapter(int index) } start_adapter(index); + + name = btd_adapter_get_name(adapter); + if (name) + hciops_set_name(index, name); + + btd_adapter_get_class(adapter, &major, &minor); + hciops_set_dev_class(index, major, minor); + btd_adapter_start(adapter); discoverable = (mode == MODE_DISCOVERABLE); @@ -1495,39 +1601,6 @@ static void read_local_features_complete(int index, init_adapter(index); } -static void update_ext_inquiry_response(int index) -{ - struct dev_info *dev = &devs[index]; - write_ext_inquiry_response_cp cp; - - DBG("hci%d", index); - - if (!(dev->features[6] & LMP_EXT_INQ)) - return; - - if (dev->ssp_mode == 0) - return; - - if (dev->cache_enable) - return; - - memset(&cp, 0, sizeof(cp)); - - eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product, - dev->did_version, dev->uuids, cp.data); - - if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0) - return; - - memcpy(dev->eir, cp.data, sizeof(cp.data)); - - if (hci_send_cmd(dev->sk, OGF_HOST_CTL, - OCF_WRITE_EXT_INQUIRY_RESPONSE, - WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0) - error("Unable to write EIR data: %s (%d)", - strerror(errno), errno); -} - static void update_name(int index, const char *name) { struct btd_adapter *adapter; @@ -1666,24 +1739,6 @@ static void read_scan_complete(int index, uint8_t status, void *ptr) adapter_mode_changed(adapter, rp->enable); } -static int write_class(int index, uint32_t class) -{ - struct dev_info *dev = &devs[index]; - write_class_of_dev_cp cp; - - DBG("hci%d class 0x%06x", index, class); - - memcpy(cp.dev_class, &class, 3); - - if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, - WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0) - return -errno; - - dev->pending_cod = class; - - return 0; -} - /* Limited Discoverable bit mask in CoD */ #define LIMITED_BIT 0x002000 @@ -3034,32 +3089,6 @@ static int hciops_set_powered(int index, gboolean powered) return err; } -static int hciops_set_dev_class(int index, uint8_t major, uint8_t minor) -{ - struct dev_info *dev = &devs[index]; - int err; - - DBG("hci%d major %u minor %u", index, major, minor); - - /* Update only the major and minor class bits keeping remaining bits - * intact*/ - dev->wanted_cod &= 0xffe000; - dev->wanted_cod |= ((major & 0x1f) << 8) | minor; - - if (dev->wanted_cod == dev->current_cod || - dev->cache_enable || dev->pending_cod) - return 0; - - DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod); - - err = write_class(index, dev->wanted_cod); - if (err < 0) - error("Adapter class update failed: %s (%d)", - strerror(-err), -err); - - return err; -} - static int start_inquiry(int index, uint8_t length) { struct dev_info *dev = &devs[index]; @@ -3157,26 +3186,6 @@ static int hciops_stop_scanning(int index) return le_set_scan_enable(index, 0); } -static int hciops_set_name(int index, const char *name) -{ - struct dev_info *dev = &devs[index]; - change_local_name_cp cp; - - DBG("hci%d, name %s", index, name); - - memset(&cp, 0, sizeof(cp)); - strncpy((char *) cp.name, name, sizeof(cp.name)); - - if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, - CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0) - return -errno; - - memcpy(dev->name, cp.name, 248); - update_ext_inquiry_response(index); - - return 0; -} - static int cancel_resolve_name(int index) { struct dev_info *info = &devs[index]; diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c index 0b5a9408..975f17eb 100644 --- a/plugins/mgmtops.c +++ b/plugins/mgmtops.c @@ -971,12 +971,64 @@ static int mgmt_set_powered(int index, gboolean powered) return mgmt_set_mode(index, MGMT_OP_SET_POWERED, powered); } +static int mgmt_set_name(int index, const char *name) +{ + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)]; + + DBG("index %d, name %s", index, name); + + memset(buf, 0, sizeof(buf)); + hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME); + hdr->len = htobs(sizeof(*cp)); + hdr->index = htobs(index); + + strncpy((char *) cp->name, name, sizeof(cp->name) - 1); + + if (write(mgmt_sock, buf, sizeof(buf)) < 0) + return -errno; + + return 0; +} + +static int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor) +{ + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)]; + struct controller_info *info = &controllers[index]; + + DBG("index %d major %u minor %u", index, major, minor); + + if (info->pending_uuid) { + info->major = major; + info->minor = minor; + info->pending_class = TRUE; + return 0; + } + + memset(buf, 0, sizeof(buf)); + hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS); + hdr->len = htobs(sizeof(*cp)); + hdr->index = htobs(index); + + cp->major = major; + cp->minor = minor; + + if (write(mgmt_sock, buf, sizeof(buf)) < 0) + return -errno; + + return 0; +} + static void read_info_complete(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_rp_read_info *rp = buf; struct controller_info *info; struct btd_adapter *adapter; - uint8_t mode; + const char *name; + uint8_t mode, major, minor; char addr[18]; if (len < sizeof(*rp)) { @@ -1021,7 +1073,17 @@ static void read_info_complete(int sk, uint16_t index, void *buf, size_t len) update_settings(adapter, info->current_settings); - adapter_name_changed(adapter, (char *) rp->name); + name = btd_adapter_get_name(adapter); + + error("mgmtops setting name %s", name); + + if (name) + mgmt_set_name(index, name); + else + adapter_name_changed(adapter, (char *) rp->name); + + btd_adapter_get_class(adapter, &major, &minor); + mgmt_set_dev_class(index, major, minor); btd_adapter_get_mode(adapter, &mode, NULL, NULL); if (mode == MODE_OFF && mgmt_powered(info->current_settings)) { @@ -1203,36 +1265,6 @@ static void read_local_oob_data_failed(int sk, uint16_t index) oob_read_local_data_complete(adapter, NULL, NULL); } -static int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor) -{ - char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)]; - struct mgmt_hdr *hdr = (void *) buf; - struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)]; - struct controller_info *info = &controllers[index]; - - DBG("index %d major %u minor %u", index, major, minor); - - if (info->pending_uuid) { - info->major = major; - info->minor = minor; - info->pending_class = TRUE; - return 0; - } - - memset(buf, 0, sizeof(buf)); - hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS); - hdr->len = htobs(sizeof(*cp)); - hdr->index = htobs(index); - - cp->major = major; - cp->minor = minor; - - if (write(mgmt_sock, buf, sizeof(buf)) < 0) - return -errno; - - return 0; -} - static void mgmt_add_uuid_complete(int sk, uint16_t index, void *buf, size_t len) { @@ -1902,27 +1934,6 @@ static int mgmt_stop_discovery(int index) return 0; } -static int mgmt_set_name(int index, const char *name) -{ - char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)]; - struct mgmt_hdr *hdr = (void *) buf; - struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)]; - - DBG("index %d, name %s", index, name); - - memset(buf, 0, sizeof(buf)); - hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME); - hdr->len = htobs(sizeof(*cp)); - hdr->index = htobs(index); - - strncpy((char *) cp->name, name, sizeof(cp->name) - 1); - - if (write(mgmt_sock, buf, sizeof(buf)) < 0) - return -errno; - - return 0; -} - static int mgmt_set_fast_connectable(int index, gboolean enable) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_mode)]; |