diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2007-08-08 13:46:35 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2007-08-08 13:46:35 +0000 |
commit | 0b727924102df07d609be955800793c1f33d6952 (patch) | |
tree | e79afd394fdc20cb54a0b184ba9f44c1bbdbaf26 /hcid/device.c | |
parent | f074ab20467dbacbfb209c333ef16b5897ba9537 (diff) |
Only set extended inquiry data when simple pairing is activated
Diffstat (limited to 'hcid/device.c')
-rw-r--r-- | hcid/device.c | 141 |
1 files changed, 106 insertions, 35 deletions
diff --git a/hcid/device.c b/hcid/device.c index 1df19667..b3c9b050 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -80,6 +80,7 @@ struct hci_dev { uint16_t hci_rev; uint16_t manufacturer; + uint8_t ssp_mode; uint8_t name[248]; uint8_t class[3]; @@ -106,14 +107,14 @@ static int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) dd = hci_open_dev(dev_id); if (dd < 0) { error("Can't open device hci%d", - dev_id, strerror(errno), errno); + dev_id, strerror(errno), errno); return -errno; } if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) { int err = errno; error("Can't read address for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + dev_id, strerror(errno), errno); hci_close_dev(dd); return -err; } @@ -145,9 +146,9 @@ int add_device(uint16_t dev_id) if (bacmp(&di.bdaddr, BDADDR_ANY)) bacpy(&dev->bdaddr, &di.bdaddr); else { - int ret = device_read_bdaddr(dev_id, &dev->bdaddr); - if (ret < 0) - return ret; + int err = device_read_bdaddr(dev_id, &dev->bdaddr); + if (err < 0) + return err; } memcpy(dev->features, di.features, 8); @@ -199,12 +200,40 @@ static inline uint8_t get_inquiry_mode(struct hci_dev *dev) return 0; } +static void update_ext_inquiry_response(int dd, struct hci_dev *dev) +{ + uint8_t fec = 0, data[240]; + + if (!(dev->features[6] & LMP_EXT_INQ)) + return; + + memset(data, 0, sizeof(data)); + + if (dev->ssp_mode > 0) { + int len; + + len = strlen((char *) dev->name); + if (len > 48) { + len = 48; + data[1] = 0x08; + } else + data[1] = 0x09; + data[0] = len + 1; + memcpy(data + 2, dev->name, len); + } + + if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) + error("Can't write extended inquiry response: %s (%d)", + strerror(errno), errno); +} + int start_device(uint16_t dev_id) { struct hci_dev *dev; struct hci_version ver; uint8_t features[8], inqmode; uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00 }; + char name[249]; int dd, err; ASSERT_DEV_ID; @@ -246,24 +275,34 @@ int start_device(uint16_t dev_id) if (hci_read_class_of_dev(dd, dev->class, 1000) < 0) { err = errno; - error("Can't read class of device on hci%d: %s(%d)", - dev_id, strerror(err), err); + error("Can't read class of device on hci%d: %s (%d)", + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } - inqmode = get_inquiry_mode(dev); - if (inqmode < 1) - goto done; + if (hci_read_local_name(dd, sizeof(name), name, 2000) < 0) { + err = errno; + error("Can't read local name on hci%d: %s (%d)", + dev_id, strerror(err), err); + hci_close_dev(dd); + return -err; + } - if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { - int err = errno; - error("Can't write inquiry mode for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + memcpy(dev->name, name, 248); + + if (!(features[6] & LMP_SIMPLE_PAIR)) + goto setup; + + if (hci_read_simple_pairing_mode(dd, &dev->ssp_mode, 1000) < 0) { + err = errno; + error("Can't read simple pairing mode on hci%d: %s (%d)", + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } +setup: if (ver.hci_rev > 1) { if (features[5] & LMP_SNIFF_SUBR) events[5] |= 0x20; @@ -280,10 +319,36 @@ int start_device(uint16_t dev_id) if (features[7] & LMP_LSTO) events[6] |= 0x80; + if (features[6] & LMP_SIMPLE_PAIR) { + events[6] |= 0x01; /* IO Capability Request */ + events[6] |= 0x02; /* IO Capability Response */ + events[6] |= 0x04; /* User Confirmation Request */ + events[6] |= 0x08; /* User Passkey Request */ + events[6] |= 0x10; /* Remote OOB Data Request */ + events[6] |= 0x20; /* Simple Pairing Complete */ + events[7] |= 0x04; /* User Passkey Notification */ + events[7] |= 0x08; /* Keypress Notification */ + events[7] |= 0x10; /* Remote Host Supported Features Notification */ + } + hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK, sizeof(events), events); } + update_ext_inquiry_response(dd, dev); + + inqmode = get_inquiry_mode(dev); + if (inqmode < 1) + goto done; + + if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { + int err = errno; + error("Can't write inquiry mode for hci%d: %s (%d)", + dev_id, strerror(errno), err); + hci_close_dev(dd); + return -err; + } + done: hci_close_dev(dd); @@ -450,6 +515,31 @@ int get_device_company(uint16_t dev_id, char *company, size_t size) return err; } +int set_simple_pairing_mode(uint16_t dev_id, uint8_t mode) +{ + struct hci_dev *dev; + int dd; + + ASSERT_DEV_ID; + + dev = &devices[dev_id]; + + dev->ssp_mode = mode; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + error("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + update_ext_inquiry_response(dd, dev); + + hci_close_dev(dd); + + return 0; +} + int get_device_name(uint16_t dev_id, char *name, size_t size) { char tmp[249]; @@ -505,28 +595,9 @@ int set_device_name(uint16_t dev_id, const char *name) return -err; } - if (dev->features[6] & LMP_EXT_INQ) { - uint8_t fec = 0, data[240]; - int len; + memcpy(dev->name, name, 248); - memset(data, 0, sizeof(data)); - len = strlen(name); - if (len > 48) { - len = 48; - data[1] = 0x08; - } else - data[1] = 0x09; - data[0] = len + 1; - memcpy(data + 2, name, len); - - if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { - int err = errno; - error("Can't write extended inquiry response for hci%d: %s (%d)", - dev_id, strerror(errno), errno); - hci_close_dev(dd); - return -err; - } - } + update_ext_inquiry_response(dd, dev); hci_close_dev(dd); |