From dfc20857eb381b464b8fd6efdaac59e4a15f5d6d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 11 Feb 2006 11:11:21 +0000 Subject: Add basic device functions --- hcid/device.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 hcid/device.c (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c new file mode 100644 index 00000000..71d97dbd --- /dev/null +++ b/hcid/device.c @@ -0,0 +1,267 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2006 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "oui.h" + +#define MAX_DEVICES 16 + +struct hci_peer { + struct timeval lastseen; + struct timeval lastused; + + bdaddr_t bdaddr; + uint32_t class; + int8_t rssi; + uint8_t data[240]; + uint8_t name[248]; + + uint8_t pscan_rep_mode; + uint8_t pscan_period_mode; + uint8_t pscan_mode; + uint16_t clock_offset; + + struct hci_peer *next; +}; + +struct hci_conn { + bdaddr_t bdaddr; + uint16_t handle; + + struct hci_conn *next; +}; + +struct hci_dev { + bdaddr_t bdaddr; + uint8_t features[8]; + uint8_t lmp_ver; + uint16_t lmp_subver; + uint16_t manufacturer; + + struct hci_peer *peers; + struct hci_conn *conns; +}; + +static struct hci_dev devices[MAX_DEVICES]; + +#define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; } + +static void info(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + + vsyslog(LOG_INFO, format, ap); + + va_end(ap); +} + +static void err(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + + vsyslog(LOG_ERR, format, ap); + + va_end(ap); +} + +void init_devices(void) +{ + int i; + + for (i = 0; i < MAX_DEVICES; i++) + memset(devices + i, 0, sizeof(struct hci_dev)); +} + +int add_device(uint16_t dev_id) +{ + struct hci_dev *dev; + struct hci_dev_info di; + + ASSERT_DEV_ID; + + dev = &devices[dev_id]; + + if (hci_devinfo(dev_id, &di) < 0) + return -errno; + + bacpy(&dev->bdaddr, &di.bdaddr); + memcpy(dev->features, di.features, 8); + + info("Device hci%d has been added", dev_id); + + return 0; +} + +int remove_device(uint16_t dev_id) +{ + struct hci_dev *dev; + + ASSERT_DEV_ID; + + dev = &devices[dev_id]; + + memset(dev, 0, sizeof(struct hci_dev)); + + info("Device hci%d has been removed", dev_id); + + return 0; +} + +int start_device(uint16_t dev_id) +{ + struct hci_dev *dev; + struct hci_version ver; + int dd; + + ASSERT_DEV_ID; + + dev = &devices[dev_id]; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + err("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + err("Can't read version info for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + dev->lmp_ver = ver.lmp_ver; + dev->lmp_subver = ver.lmp_subver; + dev->manufacturer = ver.manufacturer; + + hci_close_dev(dd); + + info("Device hci%d has been activated", dev_id); + + return 0; +} + +int stop_device(uint16_t dev_id) +{ + ASSERT_DEV_ID; + + info("Device hci%d has been disabled", dev_id); + + return 0; +} + +int get_device_address(uint16_t dev_id, char *address, size_t size) +{ + ASSERT_DEV_ID; + + if (size < 18) + return -ENOBUFS; + + return ba2str(&devices[dev_id].bdaddr, address); +} + +int get_device_version(uint16_t dev_id, char *version, size_t size) +{ + struct hci_dev *dev; + char edr[7], *tmp; + int err; + + ASSERT_DEV_ID; + + if (size < 14) + return -ENOBUFS; + + dev = &devices[dev_id]; + + if (dev->lmp_ver == 0x03 && + (dev->features[3] & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))) + sprintf(edr, " + EDR"); + else + edr[0] = '\0'; + + tmp = lmp_vertostr(dev->lmp_ver); + + if (strlen(tmp) == 0) + err = snprintf(version, size, "not assigned"); + else + err = snprintf(version, size, "Bluetooth %s%s", tmp, edr); + + bt_free(tmp); + + return err; +} + +int get_device_revision(uint16_t dev_id, char *revision, size_t size) +{ + ASSERT_DEV_ID; + + return snprintf(revision, size, "0x%02x", devices[dev_id].lmp_subver); +} + +int get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size) +{ + char *tmp; + + ASSERT_DEV_ID; + + tmp = bt_compidtostr(devices[dev_id].manufacturer); + + return snprintf(manufacturer, size, "%s", tmp); +} + +int get_device_company(uint16_t dev_id, char *company, size_t size) +{ + char *tmp, oui[9]; + int err; + + ASSERT_DEV_ID; + + ba2oui(&devices[dev_id].bdaddr, oui); + tmp = ouitocomp(oui); + + err = snprintf(company, size, "%s", tmp); + + free(tmp); + + return err; +} -- cgit From 6a3ea0f9f9aa9dd550f9f2af4a36639961846643 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 11 Feb 2006 12:14:49 +0000 Subject: Implement local device name and remote alias functions --- hcid/device.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 71d97dbd..feb9be12 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -32,12 +32,14 @@ #include #include #include +#include #include #include #include #include +#include "textfile.h" #include "oui.h" #define MAX_DEVICES 16 @@ -74,6 +76,8 @@ struct hci_dev { uint16_t lmp_subver; uint16_t manufacturer; + uint8_t name[248]; + struct hci_peer *peers; struct hci_conn *conns; }; @@ -265,3 +269,95 @@ int get_device_company(uint16_t dev_id, char *company, size_t size) return err; } + +int get_device_name(uint16_t dev_id, char *name, size_t size) +{ + char tmp[249]; + int dd; + + ASSERT_DEV_ID; + + memset(tmp, 0, sizeof(tmp)); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + err("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) { + err("Can't read name for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + hci_close_dev(dd); + + memcpy(devices[dev_id].name, tmp, 248); + + return snprintf(name, size, "%s", tmp); +} + +int set_device_name(uint16_t dev_id, const char *name) +{ + int dd; + + ASSERT_DEV_ID; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + err("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + if (hci_write_local_name(dd, name, 5000) < 0) { + err("Can't read name for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + hci_close_dev(dd); + + return 0; +} + +int get_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, char *alias, size_t size) +{ + char filename[PATH_MAX + 1], addr[18], *tmp; + int err; + + ASSERT_DEV_ID; + + ba2str(&devices[dev_id].bdaddr, addr); + snprintf(filename, PATH_MAX, "%s/%s/aliases", STORAGEDIR, addr); + + ba2str(bdaddr, addr); + + tmp = textfile_get(filename, addr); + if (!tmp) + return -ENXIO; + + err = snprintf(alias, size, "%s", tmp); + + free(tmp); + + return err; +} + +int set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias) +{ + char filename[PATH_MAX + 1], addr[18]; + + ASSERT_DEV_ID; + + ba2str(&devices[dev_id].bdaddr, addr); + snprintf(filename, PATH_MAX, "%s/%s/aliases", STORAGEDIR, addr); + + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + ba2str(bdaddr, addr); + + return textfile_put(filename, addr, alias); +} -- cgit From 8586fc0c0dc8d6fe219f7eb7a697f359827b39a0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 12 Feb 2006 06:33:18 +0000 Subject: Improve revision command and address handling --- hcid/device.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index feb9be12..c52730b4 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -196,12 +196,35 @@ int stop_device(uint16_t dev_id) int get_device_address(uint16_t dev_id, char *address, size_t size) { + struct hci_dev *dev; + int dd; + ASSERT_DEV_ID; if (size < 18) return -ENOBUFS; - return ba2str(&devices[dev_id].bdaddr, address); + dev = &devices[dev_id]; + + if (bacmp(&dev->bdaddr, BDADDR_ANY)) + return ba2str(&dev->bdaddr, address); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + err("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + if (hci_read_bd_addr(dd, &dev->bdaddr, 2000) < 0) { + err("Can't read address for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + hci_close_dev(dd); + + return ba2str(&dev->bdaddr, address); } int get_device_version(uint16_t dev_id, char *version, size_t size) @@ -235,11 +258,61 @@ int get_device_version(uint16_t dev_id, char *version, size_t size) return err; } +static int digi_revision(uint16_t dev_id, char *revision, size_t size) +{ + struct hci_request rq; + unsigned char req[] = { 0x07 }; + unsigned char buf[102]; + int dd; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + err("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x000e; + rq.cparam = req; + rq.clen = sizeof(req); + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 2000) < 0) { + err("Can't read revision for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + hci_close_dev(dd); + + return snprintf(revision, size, "%s", buf + 1); +} + int get_device_revision(uint16_t dev_id, char *revision, size_t size) { + struct hci_dev *dev; + int err; + ASSERT_DEV_ID; - return snprintf(revision, size, "0x%02x", devices[dev_id].lmp_subver); + dev = &devices[dev_id]; + + switch (dev->manufacturer) { + case 10: + err = snprintf(revision, size, "Build %d", dev->lmp_subver); + break; + case 12: + err = digi_revision(dev_id, revision, size); + break; + default: + err = snprintf(revision, size, "0x%02x", dev->lmp_subver); + break; + } + + return err; } int get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size) -- cgit From 0fe4da23f22cf74624a4576fb879d6dd500dfc5c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Feb 2006 19:46:08 +0000 Subject: Add revision information for Broadcom chips --- hcid/device.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c52730b4..25089fb4 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -72,6 +72,7 @@ struct hci_conn { struct hci_dev { bdaddr_t bdaddr; uint8_t features[8]; + uint8_t hci_rev; uint8_t lmp_ver; uint16_t lmp_subver; uint16_t manufacturer; @@ -174,6 +175,7 @@ int start_device(uint16_t dev_id) return -errno; } + dev->hci_rev = ver.hci_rev; dev->lmp_ver = ver.lmp_ver; dev->lmp_subver = ver.lmp_subver; dev->manufacturer = ver.manufacturer; @@ -307,6 +309,11 @@ int get_device_revision(uint16_t dev_id, char *revision, size_t size) case 12: err = digi_revision(dev_id, revision, size); break; + case 15: + err = snprintf(revision, size, "%d.%d / %d", + dev->hci_rev & 0xff, + dev->lmp_subver >> 8, dev->lmp_subver & 0xff); + break; default: err = snprintf(revision, size, "0x%02x", dev->lmp_subver); break; -- cgit From 0d7408aa899f84210d0e6418ee528636292276bc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Feb 2006 20:16:57 +0000 Subject: The HCI revision is a 16-bit value --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 25089fb4..ec53a362 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -72,9 +72,9 @@ struct hci_conn { struct hci_dev { bdaddr_t bdaddr; uint8_t features[8]; - uint8_t hci_rev; uint8_t lmp_ver; uint16_t lmp_subver; + uint16_t hci_rev; uint16_t manufacturer; uint8_t name[248]; -- cgit From 129147b47b9df4895888c6a674f8d15dc35e9a16 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Feb 2006 02:35:39 +0000 Subject: Add skeleton for encryption key size function --- hcid/device.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index ec53a362..f81ac693 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -441,3 +441,21 @@ int set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias) return textfile_put(filename, addr, alias); } + +int get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) +{ + struct hci_dev *dev; + int size; + + ASSERT_DEV_ID; + + dev = &devices[dev_id]; + + switch (dev->manufacturer) { + default: + size = -ENOENT; + break; + } + + return size; +} -- cgit From 26e7f9195005deda91eea83f368c0d53ec95856c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 9 Mar 2006 20:10:25 +0000 Subject: More use of the generic logging functions --- hcid/device.c | 45 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f81ac693..b67f87a7 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -39,6 +38,8 @@ #include #include +#include "hcid.h" + #include "textfile.h" #include "oui.h" @@ -87,28 +88,6 @@ static struct hci_dev devices[MAX_DEVICES]; #define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; } -static void info(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - vsyslog(LOG_INFO, format, ap); - - va_end(ap); -} - -static void err(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - vsyslog(LOG_ERR, format, ap); - - va_end(ap); -} - void init_devices(void) { int i; @@ -164,13 +143,13 @@ int start_device(uint16_t dev_id) dd = hci_open_dev(dev_id); if (dd < 0) { - err("Can't open device hci%d", + error("Can't open device hci%d", dev_id, strerror(errno), errno); return -errno; } if (hci_read_local_version(dd, &ver, 1000) < 0) { - err("Can't read version info for hci%d: %s (%d)", + error("Can't read version info for hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } @@ -213,13 +192,13 @@ int get_device_address(uint16_t dev_id, char *address, size_t size) dd = hci_open_dev(dev_id); if (dd < 0) { - err("Can't open device hci%d", + error("Can't open device hci%d", dev_id, strerror(errno), errno); return -errno; } if (hci_read_bd_addr(dd, &dev->bdaddr, 2000) < 0) { - err("Can't read address for hci%d: %s (%d)", + error("Can't read address for hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } @@ -269,7 +248,7 @@ static int digi_revision(uint16_t dev_id, char *revision, size_t size) dd = hci_open_dev(dev_id); if (dd < 0) { - err("Can't open device hci%d", + error("Can't open device hci%d", dev_id, strerror(errno), errno); return -errno; } @@ -283,7 +262,7 @@ static int digi_revision(uint16_t dev_id, char *revision, size_t size) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 2000) < 0) { - err("Can't read revision for hci%d: %s (%d)", + error("Can't read revision for hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } @@ -361,13 +340,13 @@ int get_device_name(uint16_t dev_id, char *name, size_t size) dd = hci_open_dev(dev_id); if (dd < 0) { - err("Can't open device hci%d", + error("Can't open device hci%d", dev_id, strerror(errno), errno); return -errno; } if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) { - err("Can't read name for hci%d: %s (%d)", + error("Can't read name for hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } @@ -387,13 +366,13 @@ int set_device_name(uint16_t dev_id, const char *name) dd = hci_open_dev(dev_id); if (dd < 0) { - err("Can't open device hci%d", + error("Can't open device hci%d", dev_id, strerror(errno), errno); return -errno; } if (hci_write_local_name(dd, name, 5000) < 0) { - err("Can't read name for hci%d: %s (%d)", + error("Can't read name for hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } -- cgit From b1609cb6ebaa241102257152e8eb8f248726035f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 17 Jun 2006 07:50:12 +0000 Subject: Remove inquiry mode setting --- hcid/device.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index b67f87a7..987fa0c0 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -131,10 +131,26 @@ int remove_device(uint16_t dev_id) return 0; } +static inline uint8_t get_inquiry_mode(struct hci_dev *dev) +{ + if (dev->manufacturer == 15 && + dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) + return 1; + + if (dev->features[6] & LMP_EXT_INQ) + return 2; + + if (dev->features[3] & LMP_RSSI_INQ) + return 1; + + return 0; +} + int start_device(uint16_t dev_id) { struct hci_dev *dev; struct hci_version ver; + uint8_t features[8], inqmode; int dd; ASSERT_DEV_ID; @@ -159,6 +175,22 @@ int start_device(uint16_t dev_id) dev->lmp_subver = ver.lmp_subver; dev->manufacturer = ver.manufacturer; + if (hci_read_local_features(dd, features, 1000) < 0) { + error("Can't read features for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + memcpy(dev->features, features, 8); + + inqmode = get_inquiry_mode(dev); + + if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { + error("Can't write inquiry mode for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + hci_close_dev(dd); info("Device hci%d has been activated", dev_id); -- cgit From 57eb59510dc89b134cc35bdac9949bceab7da1d6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 17 Jun 2006 11:26:02 +0000 Subject: Ignore devices in raw mode --- hcid/device.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 987fa0c0..01262f0c 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -71,6 +71,8 @@ struct hci_conn { }; struct hci_dev { + int ignore; + bdaddr_t bdaddr; uint8_t features[8]; uint8_t lmp_ver; @@ -105,8 +107,15 @@ int add_device(uint16_t dev_id) dev = &devices[dev_id]; - if (hci_devinfo(dev_id, &di) < 0) + if (hci_devinfo(dev_id, &di) < 0) { + dev->ignore = 1; return -errno; + } + + if (hci_test_bit(HCI_RAW, &di.flags)) { + info("Device hci%d is using raw mode", dev_id); + dev->ignore = 1; + } bacpy(&dev->bdaddr, &di.bdaddr); memcpy(dev->features, di.features, 8); @@ -157,6 +166,9 @@ int start_device(uint16_t dev_id) dev = &devices[dev_id]; + if (dev->ignore) + return 0; + dd = hci_open_dev(dev_id); if (dd < 0) { error("Can't open device hci%d", -- cgit From 19fb70a42ac27051f8fe1adc2502943dd56c5f0d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Jun 2006 12:57:04 +0000 Subject: Add another Inquiry with RSSI quirk --- hcid/device.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 01262f0c..65c45bab 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -142,16 +142,20 @@ int remove_device(uint16_t dev_id) static inline uint8_t get_inquiry_mode(struct hci_dev *dev) { - if (dev->manufacturer == 15 && - dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) - return 1; - if (dev->features[6] & LMP_EXT_INQ) return 2; if (dev->features[3] & LMP_RSSI_INQ) return 1; + if (dev->manufacturer == 15 && + dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) + return 1; + + if (dev->manufacturer == 31 && + dev->hci_rev == 0x2005 && dev->lmp_subver == 0x1805) + return 1; + return 0; } -- cgit From 943b02e163e169795a010c36a3b3343cc5092a96 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jun 2006 07:33:36 +0000 Subject: Include sys/param.h for PATH_MAX when cross-compiling --- hcid/device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 65c45bab..3c0d1384 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include -- cgit From 431ac89881eaed4c44f2204736ba5debe2d29a33 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 4 Jul 2006 13:36:44 +0000 Subject: Add Inquiry Result with RSSI support for another Broadcom dongle --- hcid/device.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 3c0d1384..c515b2bc 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -149,9 +149,12 @@ static inline uint8_t get_inquiry_mode(struct hci_dev *dev) if (dev->features[3] & LMP_RSSI_INQ) return 1; - if (dev->manufacturer == 15 && - dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) - return 1; + if (dev->manufacturer == 15) { + if (dev->hci_rev == 0x03 && dev->lmp_subver == 0x6963) + return 1; + if (dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) + return 1; + } if (dev->manufacturer == 31 && dev->hci_rev == 0x2005 && dev->lmp_subver == 0x1805) -- cgit From b98c93ed852d29557fe71de5262357b704f85592 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Jul 2006 22:52:04 +0000 Subject: Add Inquiry Result with RSSI support for Kensington dongle --- hcid/device.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c515b2bc..7407e6d7 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -154,6 +154,8 @@ static inline uint8_t get_inquiry_mode(struct hci_dev *dev) return 1; if (dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963) return 1; + if (dev->hci_rev == 0x00 && dev->lmp_subver == 0x6965) + return 1; } if (dev->manufacturer == 31 && -- cgit From 17152022a5844275a6f3e3e71ef5b32dc2c0ec04 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jul 2006 13:42:09 +0000 Subject: Make use of create_name() --- hcid/device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 7407e6d7..59760e68 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -444,7 +444,7 @@ int get_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, char *alias, size_ ASSERT_DEV_ID; ba2str(&devices[dev_id].bdaddr, addr); - snprintf(filename, PATH_MAX, "%s/%s/aliases", STORAGEDIR, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases"); ba2str(bdaddr, addr); @@ -466,7 +466,7 @@ int set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias) ASSERT_DEV_ID; ba2str(&devices[dev_id].bdaddr, addr); - snprintf(filename, PATH_MAX, "%s/%s/aliases", STORAGEDIR, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases"); create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -- cgit From 276a7aeaed518f61b0ec85f9658c62829d99a925 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jul 2006 01:36:38 +0000 Subject: Don't change inquiry mode for Bluetooth 1.1 adapters --- hcid/device.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 59760e68..a9ea8fc6 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -189,6 +189,7 @@ int start_device(uint16_t dev_id) if (hci_read_local_version(dd, &ver, 1000) < 0) { error("Can't read version info for hci%d: %s (%d)", dev_id, strerror(errno), errno); + hci_close_dev(dd); return -errno; } @@ -200,19 +201,24 @@ int start_device(uint16_t dev_id) if (hci_read_local_features(dd, features, 1000) < 0) { error("Can't read features for hci%d: %s (%d)", dev_id, strerror(errno), errno); + hci_close_dev(dd); return -errno; } memcpy(dev->features, features, 8); inqmode = get_inquiry_mode(dev); + if (inqmode < 1) + goto done; if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { error("Can't write inquiry mode for hci%d: %s (%d)", dev_id, strerror(errno), errno); + hci_close_dev(dd); return -errno; } +done: hci_close_dev(dd); info("Device hci%d has been activated", dev_id); -- cgit From 3dec6f11d625a351bae0aada4160f3d2de429cdd Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 18 Aug 2006 18:29:40 +0000 Subject: Fixed SetMode when the adapter is DOWN --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index a9ea8fc6..5c3518dd 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -432,7 +432,7 @@ int set_device_name(uint16_t dev_id, const char *name) } if (hci_write_local_name(dd, name, 5000) < 0) { - error("Can't read name for hci%d: %s (%d)", + error("Can't write name for hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } -- cgit From 14c1a4ad4c1fd5b86d3664707d76801013caa741 Mon Sep 17 00:00:00 2001 From: Ulisses Furquim Date: Fri, 18 Aug 2006 22:19:04 +0000 Subject: Fixed adding/initializing devices --- hcid/device.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 5c3518dd..7beb4fe8 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -99,6 +99,28 @@ void init_devices(void) memset(devices + i, 0, sizeof(struct hci_dev)); } +static int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) +{ + int dd; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + error("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) { + error("Can't read address for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + hci_close_dev(dd); + + return 0; +} + int add_device(uint16_t dev_id) { struct hci_dev *dev; @@ -118,7 +140,13 @@ int add_device(uint16_t dev_id) dev->ignore = 1; } - bacpy(&dev->bdaddr, &di.bdaddr); + 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; + } memcpy(dev->features, di.features, 8); info("Device hci%d has been added", dev_id); @@ -238,7 +266,6 @@ int stop_device(uint16_t dev_id) int get_device_address(uint16_t dev_id, char *address, size_t size) { struct hci_dev *dev; - int dd; ASSERT_DEV_ID; @@ -247,24 +274,6 @@ int get_device_address(uint16_t dev_id, char *address, size_t size) dev = &devices[dev_id]; - if (bacmp(&dev->bdaddr, BDADDR_ANY)) - return ba2str(&dev->bdaddr, address); - - dd = hci_open_dev(dev_id); - if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; - } - - if (hci_read_bd_addr(dd, &dev->bdaddr, 2000) < 0) { - error("Can't read address for hci%d: %s (%d)", - dev_id, strerror(errno), errno); - return -errno; - } - - hci_close_dev(dd); - return ba2str(&dev->bdaddr, address); } -- cgit From 49852c0b4fe1ef1dae5d11e7ff01b70c12464e40 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 18 Aug 2006 22:32:10 +0000 Subject: Fix accessing free'd memory --- hcid/device.c | 49 ++++++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 29 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 7beb4fe8..5c3518dd 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -99,28 +99,6 @@ void init_devices(void) memset(devices + i, 0, sizeof(struct hci_dev)); } -static int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) -{ - int dd; - - dd = hci_open_dev(dev_id); - if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; - } - - if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) { - error("Can't read address for hci%d: %s (%d)", - dev_id, strerror(errno), errno); - return -errno; - } - - hci_close_dev(dd); - - return 0; -} - int add_device(uint16_t dev_id) { struct hci_dev *dev; @@ -140,13 +118,7 @@ int add_device(uint16_t dev_id) dev->ignore = 1; } - 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; - } + bacpy(&dev->bdaddr, &di.bdaddr); memcpy(dev->features, di.features, 8); info("Device hci%d has been added", dev_id); @@ -266,6 +238,7 @@ int stop_device(uint16_t dev_id) int get_device_address(uint16_t dev_id, char *address, size_t size) { struct hci_dev *dev; + int dd; ASSERT_DEV_ID; @@ -274,6 +247,24 @@ int get_device_address(uint16_t dev_id, char *address, size_t size) dev = &devices[dev_id]; + if (bacmp(&dev->bdaddr, BDADDR_ANY)) + return ba2str(&dev->bdaddr, address); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + error("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + if (hci_read_bd_addr(dd, &dev->bdaddr, 2000) < 0) { + error("Can't read address for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + return -errno; + } + + hci_close_dev(dd); + return ba2str(&dev->bdaddr, address); } -- cgit From ca6e6c5a32dda535b9f76f9b0f8433f71f977efa Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 22 Aug 2006 13:26:49 +0000 Subject: fix adding and setting up devices --- hcid/device.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 5c3518dd..883d6feb 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -99,6 +99,29 @@ void init_devices(void) memset(devices + i, 0, sizeof(struct hci_dev)); } +static int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) +{ + int dd; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + error("Can't open device hci%d", + dev_id, strerror(errno), errno); + return -errno; + } + + if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) { + error("Can't read address for hci%d: %s (%d)", + dev_id, strerror(errno), errno); + hci_close_dev(dd); + return -errno; + } + + hci_close_dev(dd); + + return 0; +} + int add_device(uint16_t dev_id) { struct hci_dev *dev; @@ -118,7 +141,13 @@ int add_device(uint16_t dev_id) dev->ignore = 1; } - bacpy(&dev->bdaddr, &di.bdaddr); + 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; + } memcpy(dev->features, di.features, 8); info("Device hci%d has been added", dev_id); @@ -238,7 +267,6 @@ int stop_device(uint16_t dev_id) int get_device_address(uint16_t dev_id, char *address, size_t size) { struct hci_dev *dev; - int dd; ASSERT_DEV_ID; @@ -247,24 +275,6 @@ int get_device_address(uint16_t dev_id, char *address, size_t size) dev = &devices[dev_id]; - if (bacmp(&dev->bdaddr, BDADDR_ANY)) - return ba2str(&dev->bdaddr, address); - - dd = hci_open_dev(dev_id); - if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; - } - - if (hci_read_bd_addr(dd, &dev->bdaddr, 2000) < 0) { - error("Can't read address for hci%d: %s (%d)", - dev_id, strerror(errno), errno); - return -errno; - } - - hci_close_dev(dd); - return ba2str(&dev->bdaddr, address); } -- cgit From fdba3b26687425c6523f728f7e79d5f7a76af367 Mon Sep 17 00:00:00 2001 From: Ulisses Furquim Date: Tue, 5 Sep 2006 20:59:27 +0000 Subject: Store errno so it does not get changed before we use it --- hcid/device.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 883d6feb..2831fcc7 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -111,10 +111,11 @@ static int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) } 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); hci_close_dev(dd); - return -errno; + return -err; } hci_close_dev(dd); @@ -216,10 +217,11 @@ int start_device(uint16_t dev_id) } if (hci_read_local_version(dd, &ver, 1000) < 0) { + int err = errno; error("Can't read version info for hci%d: %s (%d)", dev_id, strerror(errno), errno); hci_close_dev(dd); - return -errno; + return -err; } dev->hci_rev = ver.hci_rev; @@ -228,10 +230,11 @@ int start_device(uint16_t dev_id) dev->manufacturer = ver.manufacturer; if (hci_read_local_features(dd, features, 1000) < 0) { + int err = errno; error("Can't read features for hci%d: %s (%d)", dev_id, strerror(errno), errno); hci_close_dev(dd); - return -errno; + return -err; } memcpy(dev->features, features, 8); @@ -241,10 +244,11 @@ int start_device(uint16_t dev_id) 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), errno); hci_close_dev(dd); - return -errno; + return -err; } done: -- cgit From 4c172501d839e5d7c3f46510432b731ea2768dbf Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 19 Sep 2006 19:31:35 +0000 Subject: close the socket before return --- hcid/device.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 2831fcc7..f92fa0c7 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -336,9 +336,11 @@ static int digi_revision(uint16_t dev_id, char *revision, size_t size) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 2000) < 0) { + int err = errno; error("Can't read revision for hci%d: %s (%d)", dev_id, strerror(errno), errno); - return -errno; + hci_close_dev(dd); + return -err; } hci_close_dev(dd); @@ -420,9 +422,11 @@ int get_device_name(uint16_t dev_id, char *name, size_t size) } if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) { + int err = errno; error("Can't read name for hci%d: %s (%d)", dev_id, strerror(errno), errno); - return -errno; + hci_close_dev(dd); + return -err; } hci_close_dev(dd); @@ -446,9 +450,11 @@ int set_device_name(uint16_t dev_id, const char *name) } if (hci_write_local_name(dd, name, 5000) < 0) { + int err = errno; error("Can't write name for hci%d: %s (%d)", dev_id, strerror(errno), errno); - return -errno; + hci_close_dev(dd); + return -err; } hci_close_dev(dd); -- cgit From abe03b24985eef4659c9d058c354f9b7df0a41f0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Sep 2006 16:18:31 +0000 Subject: Set name field for extended inquiry response --- hcid/device.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f92fa0c7..71af2d59 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -438,10 +438,13 @@ int get_device_name(uint16_t dev_id, char *name, size_t size) int set_device_name(uint16_t dev_id, const char *name) { + struct hci_dev *dev; int dd; ASSERT_DEV_ID; + dev = &devices[dev_id]; + dd = hci_open_dev(dev_id); if (dd < 0) { error("Can't open device hci%d", @@ -457,6 +460,29 @@ 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; + + 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; + } + } + hci_close_dev(dd); return 0; -- cgit From e833fda08627147d42a251d76308408e5ac6c5fd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 27 Oct 2006 13:22:50 +0000 Subject: Add inquiry with RSSI for a Silicon Wave chip --- hcid/device.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 71af2d59..73c5da75 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -179,6 +179,10 @@ static inline uint8_t get_inquiry_mode(struct hci_dev *dev) if (dev->features[3] & LMP_RSSI_INQ) return 1; + if (dev->manufacturer == 11 && + dev->hci_rev == 0x00 && dev->lmp_subver == 0x0757) + return 1; + if (dev->manufacturer == 15) { if (dev->hci_rev == 0x03 && dev->lmp_subver == 0x6963) return 1; -- cgit From 607695ed109340f4b7a5628420e0a8e8aee34f4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:48:12 +0000 Subject: Update copyright information --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 73c5da75..f2a75479 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 98329bfce1a1ce33cf2f46007196ecc63441465a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Feb 2007 19:49:49 +0000 Subject: Return correct version string for Bluetooth 2.1 --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f2a75479..b76abb9f 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -299,7 +299,7 @@ int get_device_version(uint16_t dev_id, char *version, size_t size) dev = &devices[dev_id]; - if (dev->lmp_ver == 0x03 && + if ((dev->lmp_ver == 0x03 || dev->lmp_ver == 0x04) && (dev->features[3] & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M))) sprintf(edr, " + EDR"); else -- cgit From 21a038269e8e2264b149e50355e6e18ccba1d334 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 26 Feb 2007 11:14:53 +0000 Subject: More glib memory allocation changes --- hcid/device.c | 1 - 1 file changed, 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index b76abb9f..4d2239ec 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include -- cgit From 277e0363f2839a05b80c1bc4263cfeaf9909be8c Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 23 May 2007 18:32:16 +0000 Subject: Added device class tracking --- hcid/device.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 4d2239ec..920a4dad 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -81,6 +81,7 @@ struct hci_dev { uint16_t manufacturer; uint8_t name[248]; + uint8_t class[3]; struct hci_peer *peers; struct hci_conn *conns; @@ -203,7 +204,7 @@ int start_device(uint16_t dev_id) struct hci_dev *dev; struct hci_version ver; uint8_t features[8], inqmode; - int dd; + int dd, err; ASSERT_DEV_ID; @@ -233,15 +234,23 @@ int start_device(uint16_t dev_id) dev->manufacturer = ver.manufacturer; if (hci_read_local_features(dd, features, 1000) < 0) { - int err = errno; + err = errno; error("Can't read features for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } memcpy(dev->features, features, 8); + 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); + hci_close_dev(dd); + return -err; + } + inqmode = get_inquiry_mode(dev); if (inqmode < 1) goto done; @@ -285,6 +294,18 @@ int get_device_address(uint16_t dev_id, char *address, size_t size) return ba2str(&dev->bdaddr, address); } +int get_device_class(uint16_t dev_id, uint8_t *cls) +{ + struct hci_dev *dev; + + ASSERT_DEV_ID; + + dev = &devices[dev_id]; + memcpy(cls, dev->class, 3); + + return 0; +} + int get_device_version(uint16_t dev_id, char *version, size_t size) { struct hci_dev *dev; -- cgit From 57290a1e2c13f79d353a21f7c67388ee8c142897 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 15 Jun 2007 06:28:42 +0000 Subject: Add setting of event mask --- hcid/device.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 920a4dad..db31f87a 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -204,6 +204,7 @@ 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 }; int dd, err; ASSERT_DEV_ID; @@ -263,6 +264,20 @@ int start_device(uint16_t dev_id) return -err; } + if (ver.hci_rev > 1) { + if (features[5] & LMP_SNIFF_SUBR) + events[5] |= 0x20; + + if (features[6] & LMP_EXT_INQ) + events[5] |= 0x40; + + if (features[7] & LMP_LSTO) + events[6] |= 0x80; + + hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK, + sizeof(events), events); + } + done: hci_close_dev(dd); -- cgit From a47211b0097fe3612b96246f08bf37dccd15fd61 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Jun 2007 18:47:59 +0000 Subject: Handle missing event mask bits --- hcid/device.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index db31f87a..1df19667 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -268,9 +268,15 @@ int start_device(uint16_t dev_id) if (features[5] & LMP_SNIFF_SUBR) events[5] |= 0x20; + if (features[5] & LMP_PAUSE_ENC) + events[5] |= 0x80; + if (features[6] & LMP_EXT_INQ) events[5] |= 0x40; + if (features[6] & LMP_NFLUSH_PKTS) + events[7] |= 0x01; + if (features[7] & LMP_LSTO) events[6] |= 0x80; -- cgit From 0b727924102df07d609be955800793c1f33d6952 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Aug 2007 13:46:35 +0000 Subject: Only set extended inquiry data when simple pairing is activated --- hcid/device.c | 141 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 106 insertions(+), 35 deletions(-) (limited to 'hcid/device.c') 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); -- cgit From 52a124ee19a84ca68171dbe88057d8b01b9d16d8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Aug 2007 18:28:34 +0000 Subject: Rename device helpers to adapter helpers --- hcid/device.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index b3c9b050..e7e3fbda 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -92,7 +92,7 @@ static struct hci_dev devices[MAX_DEVICES]; #define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; } -void init_devices(void) +void init_adapters(void) { int i; @@ -124,7 +124,7 @@ static int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) return 0; } -int add_device(uint16_t dev_id) +int add_adapter(uint16_t dev_id) { struct hci_dev *dev; struct hci_dev_info di; @@ -157,7 +157,7 @@ int add_device(uint16_t dev_id) return 0; } -int remove_device(uint16_t dev_id) +int remove_adapter(uint16_t dev_id) { struct hci_dev *dev; @@ -227,7 +227,7 @@ static void update_ext_inquiry_response(int dd, struct hci_dev *dev) strerror(errno), errno); } -int start_device(uint16_t dev_id) +int start_adapter(uint16_t dev_id) { struct hci_dev *dev; struct hci_version ver; @@ -357,7 +357,7 @@ done: return 0; } -int stop_device(uint16_t dev_id) +int stop_adapter(uint16_t dev_id) { ASSERT_DEV_ID; -- cgit From 86892be8d38960096f9b9c5613ba28fc9003d288 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Aug 2007 20:28:47 +0000 Subject: Add initial steps for generic device handling --- hcid/device.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index e7e3fbda..3c4f960d 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -38,11 +38,20 @@ #include #include +#include + +#include + +#include "dbus-helper.h" + #include "hcid.h" +#include "logging.h" #include "textfile.h" #include "oui.h" +#include "device.h" + #define MAX_DEVICES 16 struct hci_peer { @@ -660,3 +669,82 @@ int get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) return size; } + +static DBusConnection *connection = NULL; + +static GSList *device_list = NULL; + +gboolean device_init(DBusConnection *conn) +{ + connection = dbus_connection_ref(conn); + if (connection == NULL) + return FALSE; + + return TRUE; +} + +static void device_destroy(struct device_data *device) +{ + debug("Removing device %s", device->path); + + dbus_connection_destroy_object_path(connection, device->path); +} + +void device_cleanup(void) +{ + g_slist_foreach(device_list, (GFunc) device_destroy, NULL); + g_slist_free(device_list); + + if (connection == NULL) + return; + + dbus_connection_unref(connection); +} + +void device_foreach(GFunc func, gpointer user_data) +{ + g_slist_foreach(device_list, func, user_data); +} + +static void device_free(struct device_data *device) +{ + g_free(device->path); + g_free(device); +} + +static void device_unregister(DBusConnection *conn, void *user_data) +{ + struct device_data *device = user_data; + + device_list = g_slist_remove(device_list, device); + + device_free(device); +} + +struct device_data *device_create(const char *adapter, const char *address) +{ + struct device_data *device; + + device = g_try_malloc0(sizeof(struct device_data)); + if (device == NULL) + return NULL; + + device->path = g_strdup_printf("/device/%s_%s", adapter, address); + g_strdelimit(device->path, ":", '_'); + + debug("Creating device %s", device->path); + + if (dbus_connection_create_object_path(connection, device->path, + device, device_unregister) == FALSE) { + device_free(device); + return NULL; + } + + device_list = g_slist_append(device_list, device); + + return device; +} + +void device_remove(const char *path) +{ +} -- cgit From f205cd06dc4e9da2c1d5109e570008d7d80b8380 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Aug 2007 09:48:14 +0000 Subject: Update service classes on all adapters --- hcid/device.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 3c4f960d..983071d0 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -401,6 +401,17 @@ int get_device_class(uint16_t dev_id, uint8_t *cls) return 0; } +int set_device_class(uint16_t dev_id, uint8_t *cls) +{ + struct hci_dev *dev; + + ASSERT_DEV_ID; + dev = &devices[dev_id]; + memcpy(dev->class, cls, 3); + + return 0; +} + int get_device_version(uint16_t dev_id, char *version, size_t size) { struct hci_dev *dev; -- cgit From eb4d49890ca8a4d8f567e81fdf82b6903d30f326 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Aug 2007 01:21:33 +0000 Subject: Move the extended inquiry response creation into the SDP code --- hcid/device.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 983071d0..c80f5875 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -45,6 +45,7 @@ #include "dbus-helper.h" #include "hcid.h" +#include "sdpd.h" #include "logging.h" #include "textfile.h" @@ -218,18 +219,8 @@ static void update_ext_inquiry_response(int dd, struct hci_dev *dev) 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 (dev->ssp_mode > 0) + create_ext_inquiry_response((char *) dev->name, data); if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) error("Can't write extended inquiry response: %s (%d)", -- cgit From 0e8c93725dbdc6ce76ca48da92f9d15b2a706111 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Aug 2007 01:49:26 +0000 Subject: Update extended inquiry response when service class changes --- hcid/device.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c80f5875..ffdb2711 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -366,6 +366,32 @@ int stop_adapter(uint16_t dev_id) return 0; } +int update_adapter(uint16_t dev_id) +{ + struct hci_dev *dev; + int dd; + + ASSERT_DEV_ID; + + dev = &devices[dev_id]; + + if (dev->ignore) + return 0; + + 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_address(uint16_t dev_id, char *address, size_t size) { struct hci_dev *dev; -- cgit From c3cd59ae39ebb53e27ddd99ee48f1875bd480c1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Aug 2007 02:13:27 +0000 Subject: Set local device name on adapter setup --- hcid/device.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index ffdb2711..e95f09b3 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -335,6 +335,11 @@ setup: sizeof(events), events); } + if (read_local_name(&dev->bdaddr, name) == 0) { + memcpy(dev->name, name, 248); + hci_write_local_name(dd, name, 5000); + } + update_ext_inquiry_response(dd, dev); inqmode = get_inquiry_mode(dev); -- cgit From 3dfe93f27c455e07be72a38239f4f8335ba6a860 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 10 Sep 2007 16:14:38 +0000 Subject: Use default event mask from the specification --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index e95f09b3..350bf683 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -232,7 +232,7 @@ int start_adapter(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 }; + uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 }; char name[249]; int dd, err; -- cgit From f1659f19cfb3ef0c0c09b5f5b7e2b06d90d079ab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Oct 2007 17:49:52 +0000 Subject: Update copyright information --- hcid/device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 350bf683..7085f078 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -2,6 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * + * Copyright (C) 2006-2007 Nokia Corporation * Copyright (C) 2004-2007 Marcel Holtmann * * -- cgit From f4051e4e1bc3a5a00fc74b5b5eb7eb3794f67310 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 7 Nov 2007 13:14:54 +0000 Subject: Whitespace cleanup --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 7085f078..40cba5c1 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -316,7 +316,7 @@ setup: if (features[6] & LMP_NFLUSH_PKTS) events[7] |= 0x01; - + if (features[7] & LMP_LSTO) events[6] |= 0x80; -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 40cba5c1..c4f2bf05 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2006-2007 Nokia Corporation - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 190c8e73dc79edd6eb7485ad3663e89fb757aafa Mon Sep 17 00:00:00 2001 From: Vinicius Gomes Date: Wed, 5 Mar 2008 22:11:56 +0000 Subject: Adapts the device name to the new way. --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c4f2bf05..002b77ab 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -763,7 +763,7 @@ struct device_data *device_create(const char *adapter, const char *address) if (device == NULL) return NULL; - device->path = g_strdup_printf("/device/%s_%s", adapter, address); + device->path = g_strdup_printf("%s/dev_%s", adapter, address); g_strdelimit(device->path, ":", '_'); debug("Creating device %s", device->path); -- cgit From 2c1effee41e974f97b21aec1bdd1a232ba48056a Mon Sep 17 00:00:00 2001 From: Vinicius Gomes Date: Wed, 5 Mar 2008 22:19:25 +0000 Subject: Adding Device Interface --- hcid/device.c | 50 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 002b77ab..bf84ad2c 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -52,10 +52,13 @@ #include "textfile.h" #include "oui.h" +#include "adapter.h" #include "device.h" #define MAX_DEVICES 16 +#define DEVICE_INTERFACE "org.bluez.Device" + struct hci_peer { struct timeval lastseen; struct timeval lastused; @@ -717,7 +720,7 @@ gboolean device_init(DBusConnection *conn) return TRUE; } -static void device_destroy(struct device_data *device) +static void device_destroy(struct device *device) { debug("Removing device %s", device->path); @@ -740,7 +743,7 @@ void device_foreach(GFunc func, gpointer user_data) g_slist_foreach(device_list, func, user_data); } -static void device_free(struct device_data *device) +static void device_free(struct device *device) { g_free(device->path); g_free(device); @@ -748,22 +751,53 @@ static void device_free(struct device_data *device) static void device_unregister(DBusConnection *conn, void *user_data) { - struct device_data *device = user_data; + struct device *device = user_data; device_list = g_slist_remove(device_list, device); device_free(device); } -struct device_data *device_create(const char *adapter, const char *address) +static DBusHandlerResult disconnect(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult get_properties(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult set_property(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusMethodVTable device_methods[] = { + { "GetProperties", get_properties, "", "a{sv}" }, + { "SetProperty", set_property, "sv", "" }, + { "Disconnect", disconnect, "", "" }, + { NULL, NULL, NULL, NULL } +}; + +static DBusSignalVTable device_signals[] = { + { "PropertyChanged", "sv" }, + { "DisconnectRequested", "" }, + { NULL, NULL } +}; + +struct device *device_create(struct adapter *adapter, const char *address) { - struct device_data *device; + struct device *device; - device = g_try_malloc0(sizeof(struct device_data)); + device = g_try_malloc0(sizeof(struct device)); if (device == NULL) return NULL; - device->path = g_strdup_printf("%s/dev_%s", adapter, address); + device->path = g_strdup_printf("%s/dev_%s", adapter->address, address); g_strdelimit(device->path, ":", '_'); debug("Creating device %s", device->path); @@ -773,6 +807,8 @@ struct device_data *device_create(const char *adapter, const char *address) device_free(device); return NULL; } + dbus_connection_register_interface(connection, device->path, + DEVICE_INTERFACE, device_methods, device_signals, NULL); device_list = g_slist_append(device_list, device); -- cgit From da0e7105811dc046d13d0365404efc1189ee4a8c Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 7 Mar 2008 17:53:50 +0000 Subject: Registering device's object path --- hcid/device.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index bf84ad2c..51e6bebc 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -54,6 +54,7 @@ #include "adapter.h" #include "device.h" +#include "dbus-common.h" #define MAX_DEVICES 16 @@ -789,7 +790,8 @@ static DBusSignalVTable device_signals[] = { { NULL, NULL } }; -struct device *device_create(struct adapter *adapter, const char *address) +const char *device_create(struct adapter *adapter, + const char *address, sdp_list_t *recs) { struct device *device; @@ -797,7 +799,8 @@ struct device *device_create(struct adapter *adapter, const char *address) if (device == NULL) return NULL; - device->path = g_strdup_printf("%s/dev_%s", adapter->address, address); + device->path = g_strdup_printf("%s/hci%d/dev_%s", + BASE_PATH, adapter->dev_id, address); g_strdelimit(device->path, ":", '_'); debug("Creating device %s", device->path); @@ -807,12 +810,16 @@ struct device *device_create(struct adapter *adapter, const char *address) device_free(device); return NULL; } + dbus_connection_register_interface(connection, device->path, DEVICE_INTERFACE, device_methods, device_signals, NULL); device_list = g_slist_append(device_list, device); - return device; + device->adapter = adapter; + device->records = recs; + + return device->path; } void device_remove(const char *path) -- cgit From 5d5d89bb2dbc295443900d59d8a7172dc2f279c7 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 7 Mar 2008 22:06:50 +0000 Subject: extract the service class uuid --- hcid/device.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 51e6bebc..713fcff0 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include @@ -746,6 +748,7 @@ void device_foreach(GFunc func, gpointer user_data) static void device_free(struct device *device) { + sdp_list_free(device->uuids, (sdp_free_func_t) free); g_free(device->path); g_free(device); } @@ -791,7 +794,7 @@ static DBusSignalVTable device_signals[] = { }; const char *device_create(struct adapter *adapter, - const char *address, sdp_list_t *recs) + const char *address, sdp_list_t *uuids) { struct device *device; @@ -817,7 +820,7 @@ const char *device_create(struct adapter *adapter, device_list = g_slist_append(device_list, device); device->adapter = adapter; - device->records = recs; + device->uuids = uuids; return device->path; } -- cgit From 4e6726e8029f20be3e08b44760c56fc7a419090b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 10 Mar 2008 13:44:09 +0000 Subject: Intial device GetProperties implementation. --- hcid/device.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 713fcff0..b16a8189 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -57,6 +57,7 @@ #include "adapter.h" #include "device.h" #include "dbus-common.h" +#include "dbus-hci.h" #define MAX_DEVICES 16 @@ -749,6 +750,7 @@ void device_foreach(GFunc func, gpointer user_data) static void device_free(struct device *device) { sdp_list_free(device->uuids, (sdp_free_func_t) free); + g_free(device->address); g_free(device->path); g_free(device); } @@ -771,7 +773,96 @@ static DBusHandlerResult disconnect(DBusConnection *conn, static DBusHandlerResult get_properties(DBusConnection *conn, DBusMessage *msg, void *user_data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct device *device = user_data; + struct adapter *adapter = device->adapter; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter dict; + bdaddr_t src, dst; + char filename[PATH_MAX + 1]; + char buf[64]; + const char *ptr; + char *str; + dbus_bool_t boolean; + uint32_t class; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_iter_init_append(reply, &iter); + + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); + + /* Address */ + dbus_message_iter_append_dict_entry(&dict, "Address", DBUS_TYPE_STRING, + &device->address); + + /* Name */ + create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names"); + str = textfile_caseget(filename, device->address); + if (str) { + dbus_message_iter_append_dict_entry(&dict, "Name", + DBUS_TYPE_STRING, &str); + free(str); + } + + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + + /* Class */ + if (read_remote_class(&src, &dst, &class) == 0) { + + dbus_message_iter_append_dict_entry(&dict, "Class", + DBUS_TYPE_UINT32, &class); + } + + /* Alias */ + if (get_device_alias(adapter->dev_id, &dst, buf, sizeof(buf)) > 0) { + ptr = buf; + dbus_message_iter_append_dict_entry(&dict, "Alias", + DBUS_TYPE_STRING, &ptr); + } + + /* Paired */ + create_name(filename, PATH_MAX, STORAGEDIR, + adapter->address, "linkkeys"); + str = textfile_caseget(filename, device->address); + if (str) { + boolean = TRUE; + free(str); + } else { + boolean = FALSE; + } + + dbus_message_iter_append_dict_entry(&dict, "Paired", + DBUS_TYPE_BOOLEAN, &boolean); + + /* Trusted */ + boolean = read_trust(&src, device->address, GLOBAL_TRUST); + dbus_message_iter_append_dict_entry(&dict, "Trusted", + DBUS_TYPE_BOOLEAN, &boolean); + + /* Connected */ + if (g_slist_find_custom(adapter->active_conn, &dst, + active_conn_find_by_bdaddr)) + boolean = TRUE; + else + boolean = FALSE; + + dbus_message_iter_append_dict_entry(&dict, "Connected", + DBUS_TYPE_BOOLEAN, &boolean); + + /* TODO: UUIDs */ + + free(str); + + dbus_message_iter_close_container(&iter, &dict); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult set_property(DBusConnection *conn, @@ -819,6 +910,7 @@ const char *device_create(struct adapter *adapter, device_list = g_slist_append(device_list, device); + device->address = g_strdup(address); device->adapter = adapter; device->uuids = uuids; -- cgit From ea00a446dbacead62040dd2bd7e663774c205c04 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 10 Mar 2008 14:20:50 +0000 Subject: added new function to convert uuid to string(uuid128) --- hcid/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index b16a8189..538ce853 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -749,8 +749,8 @@ void device_foreach(GFunc func, gpointer user_data) static void device_free(struct device *device) { - sdp_list_free(device->uuids, (sdp_free_func_t) free); - g_free(device->address); + g_slist_foreach(device->uuids, (GFunc) g_free, NULL); + g_slist_free(device->uuids); g_free(device->path); g_free(device); } @@ -885,7 +885,7 @@ static DBusSignalVTable device_signals[] = { }; const char *device_create(struct adapter *adapter, - const char *address, sdp_list_t *uuids) + const char *address, GSList *uuids) { struct device *device; -- cgit From 223a14dbbbec152492e3c969c95901303f958d23 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 10 Mar 2008 14:21:54 +0000 Subject: Fix double free. --- hcid/device.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 538ce853..74cf7cd3 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -858,8 +858,6 @@ static DBusHandlerResult get_properties(DBusConnection *conn, /* TODO: UUIDs */ - free(str); - dbus_message_iter_close_container(&iter, &dict); return send_message_and_unref(conn, reply); -- cgit From f4662ad94310c08fd83e2cd9acd4ab0a03379cee Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 10 Mar 2008 18:03:27 +0000 Subject: Fix memory leak. --- hcid/device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 74cf7cd3..840f8d1f 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -751,6 +751,7 @@ static void device_free(struct device *device) { g_slist_foreach(device->uuids, (GFunc) g_free, NULL); g_slist_free(device->uuids); + g_free(device->address); g_free(device->path); g_free(device); } -- cgit From e2bd3afdf478e4c7d180026a81480b501bd356ea Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 11 Mar 2008 19:37:33 +0000 Subject: minor cleanup: replace char by gchar --- hcid/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 840f8d1f..fa1b9b7e 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -883,8 +883,8 @@ static DBusSignalVTable device_signals[] = { { NULL, NULL } }; -const char *device_create(struct adapter *adapter, - const char *address, GSList *uuids) +const gchar *device_create(struct adapter *adapter, + const gchar *address, GSList *uuids) { struct device *device; @@ -916,6 +916,6 @@ const char *device_create(struct adapter *adapter, return device->path; } -void device_remove(const char *path) +void device_remove(const gchar *path) { } -- cgit From 181a211db506940ebdc18ee8707d85da6561f79e Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 11 Mar 2008 20:14:19 +0000 Subject: CreateDevice: Check if the device already exists --- hcid/device.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index fa1b9b7e..f29e46a9 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -747,6 +747,22 @@ void device_foreach(GFunc func, gpointer user_data) g_slist_foreach(device_list, func, user_data); } +struct device *device_find(const gchar *address) +{ + GSList *l; + + if (!device_list || !address) + return NULL; + + for (l = device_list; l; l = l->next) { + struct device *device = l->data; + if (strcmp(device->address, address) == 0) + return device; + } + + return NULL; +} + static void device_free(struct device *device) { g_slist_foreach(device->uuids, (GFunc) g_free, NULL); -- cgit From 272f467beabf0af74ae2beaf3529d076c36a3ee0 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 11 Mar 2008 21:38:36 +0000 Subject: Fix invalid read when changing device name. --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f29e46a9..c7e8f509 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -645,7 +645,7 @@ int set_device_name(uint16_t dev_id, const char *name) return -err; } - memcpy(dev->name, name, 248); + strncpy((char *) dev->name, name, 248); update_ext_inquiry_response(dd, dev); -- cgit From ba93fb91ea81a35be0834ac395650e020a6b3fd3 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 11 Mar 2008 21:49:57 +0000 Subject: Added array support for dict --- hcid/device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c7e8f509..a098f873 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -873,7 +873,9 @@ static DBusHandlerResult get_properties(DBusConnection *conn, dbus_message_iter_append_dict_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &boolean); - /* TODO: UUIDs */ + /* UUIDs */ + dbus_message_iter_append_dict_entry(&dict, "UUID", + DBUS_TYPE_ARRAY, device->uuids); dbus_message_iter_close_container(&iter, &dict); -- cgit From 56afc8a3d8a5019d44c9607508b75be0c61b1930 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 11 Mar 2008 22:23:13 +0000 Subject: connection ref can't be NULL when device_destroy is called --- hcid/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index a098f873..49b3ab84 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -733,12 +733,12 @@ static void device_destroy(struct device *device) void device_cleanup(void) { - g_slist_foreach(device_list, (GFunc) device_destroy, NULL); - g_slist_free(device_list); - if (connection == NULL) return; + g_slist_foreach(device_list, (GFunc) device_destroy, NULL); + g_slist_free(device_list); + dbus_connection_unref(connection); } -- cgit From 75add5651e5dbc49c9c144acceac7e2c32d9bd16 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 12 Mar 2008 15:07:07 +0000 Subject: Added RemoveDevice --- hcid/device.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 49b3ab84..3f4e5ba4 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -934,6 +934,21 @@ const gchar *device_create(struct adapter *adapter, return device->path; } +static gint device_path_cmp(const struct device *device, const char *path) +{ + return strcmp(device->path, path); +} + void device_remove(const gchar *path) { + GSList *l; + + l = g_slist_find_custom(device_list, path, + (GCompareFunc) device_path_cmp); + if (!l) + return; + + dbus_connection_destroy_object_path(connection, path); + + device_list = g_slist_remove(device_list, l->data); } -- cgit From 6bfa88d706cc57a0c975c980dabec5d8ed67dcc0 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 12 Mar 2008 21:37:20 +0000 Subject: Keep a list of device's structure pointers instead of paths --- hcid/device.c | 72 ++++++----------------------------------------------------- 1 file changed, 7 insertions(+), 65 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 3f4e5ba4..5e129ab5 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -713,10 +713,9 @@ int get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) static DBusConnection *connection = NULL; -static GSList *device_list = NULL; - gboolean device_init(DBusConnection *conn) { + /* FIXME: It's not necessary keep a connection reference */ connection = dbus_connection_ref(conn); if (connection == NULL) return FALSE; @@ -724,45 +723,6 @@ gboolean device_init(DBusConnection *conn) return TRUE; } -static void device_destroy(struct device *device) -{ - debug("Removing device %s", device->path); - - dbus_connection_destroy_object_path(connection, device->path); -} - -void device_cleanup(void) -{ - if (connection == NULL) - return; - - g_slist_foreach(device_list, (GFunc) device_destroy, NULL); - g_slist_free(device_list); - - dbus_connection_unref(connection); -} - -void device_foreach(GFunc func, gpointer user_data) -{ - g_slist_foreach(device_list, func, user_data); -} - -struct device *device_find(const gchar *address) -{ - GSList *l; - - if (!device_list || !address) - return NULL; - - for (l = device_list; l; l = l->next) { - struct device *device = l->data; - if (strcmp(device->address, address) == 0) - return device; - } - - return NULL; -} - static void device_free(struct device *device) { g_slist_foreach(device->uuids, (GFunc) g_free, NULL); @@ -774,11 +734,7 @@ static void device_free(struct device *device) static void device_unregister(DBusConnection *conn, void *user_data) { - struct device *device = user_data; - - device_list = g_slist_remove(device_list, device); - - device_free(device); + device_free(user_data); } static DBusHandlerResult disconnect(DBusConnection *conn, @@ -901,7 +857,7 @@ static DBusSignalVTable device_signals[] = { { NULL, NULL } }; -const gchar *device_create(struct adapter *adapter, +struct device *device_create(struct adapter *adapter, const gchar *address, GSList *uuids) { struct device *device; @@ -925,30 +881,16 @@ const gchar *device_create(struct adapter *adapter, dbus_connection_register_interface(connection, device->path, DEVICE_INTERFACE, device_methods, device_signals, NULL); - device_list = g_slist_append(device_list, device); - device->address = g_strdup(address); device->adapter = adapter; device->uuids = uuids; - return device->path; + return device; } -static gint device_path_cmp(const struct device *device, const char *path) +void device_destroy(struct device *device) { - return strcmp(device->path, path); -} + debug("Removing device %s", device->path); -void device_remove(const gchar *path) -{ - GSList *l; - - l = g_slist_find_custom(device_list, path, - (GCompareFunc) device_path_cmp); - if (!l) - return; - - dbus_connection_destroy_object_path(connection, path); - - device_list = g_slist_remove(device_list, l->data); + dbus_connection_destroy_object_path(connection, device->path); } -- cgit From 81cfb0fc353b88658aec4c1ee0eb6cc5f851df41 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 13 Mar 2008 12:34:10 +0000 Subject: cleanup: removed device's static D-Bus connection reference --- hcid/device.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 5e129ab5..0f1ab4a4 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -711,18 +711,6 @@ int get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) return size; } -static DBusConnection *connection = NULL; - -gboolean device_init(DBusConnection *conn) -{ - /* FIXME: It's not necessary keep a connection reference */ - connection = dbus_connection_ref(conn); - if (connection == NULL) - return FALSE; - - return TRUE; -} - static void device_free(struct device *device) { g_slist_foreach(device->uuids, (GFunc) g_free, NULL); @@ -857,8 +845,8 @@ static DBusSignalVTable device_signals[] = { { NULL, NULL } }; -struct device *device_create(struct adapter *adapter, - const gchar *address, GSList *uuids) +struct device *device_create(DBusConnection *conn, struct adapter *adapter, + const gchar *address, GSList *uuids) { struct device *device; @@ -872,13 +860,13 @@ struct device *device_create(struct adapter *adapter, debug("Creating device %s", device->path); - if (dbus_connection_create_object_path(connection, device->path, + if (dbus_connection_create_object_path(conn, device->path, device, device_unregister) == FALSE) { device_free(device); return NULL; } - dbus_connection_register_interface(connection, device->path, + dbus_connection_register_interface(conn, device->path, DEVICE_INTERFACE, device_methods, device_signals, NULL); device->address = g_strdup(address); @@ -888,9 +876,9 @@ struct device *device_create(struct adapter *adapter, return device; } -void device_destroy(struct device *device) +void device_destroy(struct device *device, DBusConnection *conn) { debug("Removing device %s", device->path); - dbus_connection_destroy_object_path(connection, device->path); + dbus_connection_destroy_object_path(conn, device->path); } -- cgit From 7fe6ac58638e86d11494f5a785bcf1d074ca2c37 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 13 Mar 2008 17:32:49 +0000 Subject: Add device SetProperty implementation and mark it and GetProperties experimental. --- hcid/device.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 0f1ab4a4..94e657eb 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -58,6 +58,7 @@ #include "device.h" #include "dbus-common.h" #include "dbus-hci.h" +#include "error.h" #define MAX_DEVICES 16 @@ -747,6 +748,9 @@ static DBusHandlerResult get_properties(DBusConnection *conn, dbus_bool_t boolean; uint32_t class; + if (!hcid_dbus_use_experimental()) + return error_unknown_method(conn, msg); + reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -826,10 +830,97 @@ static DBusHandlerResult get_properties(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, + const char *alias, void *data) +{ + struct device *device = data; + struct adapter *adapter = device->adapter; + DBusMessage *reply; + bdaddr_t bdaddr; + int ecode; + + str2ba(device->address, &bdaddr); + + ecode = set_device_alias(adapter->dev_id, &bdaddr, alias); + if (ecode < 0) + return error_failed_errno(conn, msg, -ecode); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg), + DEVICE_INTERFACE, "Alias", + DBUS_TYPE_STRING, &alias); + + return send_message_and_unref(conn, reply); +} + +static DBusHandlerResult set_trust(DBusConnection *conn, DBusMessage *msg, + dbus_bool_t value, void *data) +{ + struct device *device = data; + struct adapter *adapter = device->adapter; + DBusMessage *reply; + bdaddr_t local; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + str2ba(adapter->address, &local); + + write_trust(&local, device->address, GLOBAL_TRUST, value); + + dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg), + DEVICE_INTERFACE, "Trusted", + DBUS_TYPE_BOOLEAN, &value); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult set_property(DBusConnection *conn, - DBusMessage *msg, void *user_data) + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + DBusMessageIter iter; + DBusMessageIter sub; + const char *property; + + if (!hcid_dbus_use_experimental()) + return error_unknown_method(conn, msg); + + if (!dbus_message_iter_init(msg, &iter)) + return error_invalid_arguments(conn, msg, NULL); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return error_invalid_arguments(conn, msg, NULL); + + dbus_message_iter_get_basic(&iter, &property); + dbus_message_iter_next(&iter); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) + return error_invalid_arguments(conn, msg, NULL); + dbus_message_iter_recurse(&iter, &sub); + + if (g_str_equal("Trusted", property)) { + dbus_bool_t value; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) + return error_invalid_arguments(conn, msg, NULL); + dbus_message_iter_get_basic(&sub, &value); + + return set_trust(conn, msg, value, data); + } else if (g_str_equal("Alias", property)) { + char *alias; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) + return error_invalid_arguments(conn, msg, NULL); + dbus_message_iter_get_basic(&sub, &alias); + + return set_alias(conn, msg, alias, data); + } + + return error_invalid_arguments(conn, msg, NULL); } static DBusMethodVTable device_methods[] = { -- cgit From 8afa46e246f1598ebfac26725606823cee2dd0ec Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 13 Mar 2008 20:40:46 +0000 Subject: Fix Alias device property to behave according the documentation and UUIDs typo. --- hcid/device.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 94e657eb..308b15b1 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -694,6 +694,22 @@ int set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias) return textfile_put(filename, addr, alias); } +int remove_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr) +{ + char filename[PATH_MAX + 1], addr[18]; + + ASSERT_DEV_ID; + + ba2str(&devices[dev_id].bdaddr, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "aliases"); + + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + ba2str(bdaddr, addr); + + return textfile_del(filename, addr); +} + int get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) { struct hci_dev *dev; @@ -744,7 +760,7 @@ static DBusHandlerResult get_properties(DBusConnection *conn, char filename[PATH_MAX + 1]; char buf[64]; const char *ptr; - char *str; + char *str, *name; dbus_bool_t boolean; uint32_t class; @@ -769,10 +785,9 @@ static DBusHandlerResult get_properties(DBusConnection *conn, /* Name */ create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names"); str = textfile_caseget(filename, device->address); - if (str) { + if (name) { dbus_message_iter_append_dict_entry(&dict, "Name", - DBUS_TYPE_STRING, &str); - free(str); + DBUS_TYPE_STRING, &name); } str2ba(adapter->address, &src); @@ -780,7 +795,6 @@ static DBusHandlerResult get_properties(DBusConnection *conn, /* Class */ if (read_remote_class(&src, &dst, &class) == 0) { - dbus_message_iter_append_dict_entry(&dict, "Class", DBUS_TYPE_UINT32, &class); } @@ -790,6 +804,10 @@ static DBusHandlerResult get_properties(DBusConnection *conn, ptr = buf; dbus_message_iter_append_dict_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr); + } else if (name) { + dbus_message_iter_append_dict_entry(&dict, "Alias", + DBUS_TYPE_STRING, &name); + free(name); } /* Paired */ @@ -822,7 +840,7 @@ static DBusHandlerResult get_properties(DBusConnection *conn, DBUS_TYPE_BOOLEAN, &boolean); /* UUIDs */ - dbus_message_iter_append_dict_entry(&dict, "UUID", + dbus_message_iter_append_dict_entry(&dict, "UUIDs", DBUS_TYPE_ARRAY, device->uuids); dbus_message_iter_close_container(&iter, &dict); @@ -838,10 +856,21 @@ static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, DBusMessage *reply; bdaddr_t bdaddr; int ecode; + char *str, filename[PATH_MAX + 1]; str2ba(device->address, &bdaddr); - ecode = set_device_alias(adapter->dev_id, &bdaddr, alias); + /* Remove alias if empty string */ + if (g_str_equal(alias, "")) { + create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, + "names"); + str = textfile_caseget(filename, device->address); + ecode = remove_device_alias(adapter->dev_id, &bdaddr); + } else { + str = g_strdup(alias); + ecode = set_device_alias(adapter->dev_id, &bdaddr, alias); + } + if (ecode < 0) return error_failed_errno(conn, msg, -ecode); @@ -851,7 +880,9 @@ static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg), DEVICE_INTERFACE, "Alias", - DBUS_TYPE_STRING, &alias); + DBUS_TYPE_STRING, &str); + + free(str); return send_message_and_unref(conn, reply); } -- cgit From ec31aec6424bd90c822e18600763a196b72b0e9c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 13 Mar 2008 20:44:30 +0000 Subject: Fix device GetProperties. --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 308b15b1..c0f0ddbc 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -784,7 +784,7 @@ static DBusHandlerResult get_properties(DBusConnection *conn, /* Name */ create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names"); - str = textfile_caseget(filename, device->address); + name = textfile_caseget(filename, device->address); if (name) { dbus_message_iter_append_dict_entry(&dict, "Name", DBUS_TYPE_STRING, &name); -- cgit From ff296428a08dee619db1cc702146faefa91087fa Mon Sep 17 00:00:00 2001 From: Cidorvan Leite Date: Thu, 13 Mar 2008 22:06:43 +0000 Subject: Created devices from linkkeys --- hcid/device.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c0f0ddbc..2b331361 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1004,3 +1004,8 @@ void device_destroy(struct device *device, DBusConnection *conn) dbus_connection_destroy_object_path(conn, device->path); } + +gint device_address_cmp(struct device *device, const gchar *address) +{ + return strcasecmp(device->address, address); +} -- cgit From 4bab9b442ec3e2e06157014c5d27641c79434e2a Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 14 Mar 2008 20:50:22 +0000 Subject: added new adapter/device D-Bus path --- hcid/device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 2b331361..24ba6e51 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -976,8 +976,8 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, if (device == NULL) return NULL; - device->path = g_strdup_printf("%s/hci%d/dev_%s", - BASE_PATH, adapter->dev_id, address); + device->path = g_strdup_printf("/hci%d/dev_%s", + adapter->dev_id, address); g_strdelimit(device->path, ":", '_'); debug("Creating device %s", device->path); -- cgit From 31e4b89ccb965ef5d955c8e99147f5f69f539899 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 15 Mar 2008 00:46:41 +0000 Subject: Remove some unneeded experimental checks --- hcid/device.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 24ba6e51..7d48eb25 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -764,9 +764,6 @@ static DBusHandlerResult get_properties(DBusConnection *conn, dbus_bool_t boolean; uint32_t class; - if (!hcid_dbus_use_experimental()) - return error_unknown_method(conn, msg); - reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -917,9 +914,6 @@ static DBusHandlerResult set_property(DBusConnection *conn, DBusMessageIter sub; const char *property; - if (!hcid_dbus_use_experimental()) - return error_unknown_method(conn, msg); - if (!dbus_message_iter_init(msg, &iter)) return error_invalid_arguments(conn, msg, NULL); -- cgit From b29381cae56e509c87cfc6ce12ea34d19dec6f55 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 20 Mar 2008 15:00:51 +0000 Subject: Emit device PropertyChanged properly and fix adapter signals to be emmitted in old and new path when necessary. --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 7d48eb25..6d99fb45 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -994,7 +994,7 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, void device_destroy(struct device *device, DBusConnection *conn) { - debug("Removing device %s", device->path); + debug("Removing device %s", device->path); dbus_connection_destroy_object_path(conn, device->path); } -- cgit From 00b75a22689575b4c5d630222d54c96656df9971 Mon Sep 17 00:00:00 2001 From: Vinicius Gomes Date: Thu, 20 Mar 2008 15:10:58 +0000 Subject: device: adding device_remove function --- hcid/device.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 6d99fb45..c16a6708 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -992,6 +992,12 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, return device; } +void device_remove(DBusConnection *conn, struct device *device) +{ + device_destroy(device, conn); + device_free(device); +} + void device_destroy(struct device *device, DBusConnection *conn) { debug("Removing device %s", device->path); -- cgit From 74fdac28eafca963c8081ea39dcf057459cf491a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 20 Mar 2008 20:46:56 +0000 Subject: Add Adapter property to device GetProperties. --- hcid/device.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c16a6708..f5929861 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -757,10 +757,10 @@ static DBusHandlerResult get_properties(DBusConnection *conn, DBusMessageIter iter; DBusMessageIter dict; bdaddr_t src, dst; - char filename[PATH_MAX + 1]; + char filename[PATH_MAX + 1], path[MAX_PATH_LENGTH]; char buf[64]; const char *ptr; - char *str, *name; + char *str, *name, *ppath; dbus_bool_t boolean; uint32_t class; @@ -840,6 +840,12 @@ static DBusHandlerResult get_properties(DBusConnection *conn, dbus_message_iter_append_dict_entry(&dict, "UUIDs", DBUS_TYPE_ARRAY, device->uuids); + /* Adapter */ + snprintf(path, sizeof(path), "/hci%d", adapter->dev_id); + ppath = path; + dbus_message_iter_append_dict_entry(&dict, "Adapter", + DBUS_TYPE_STRING, &ppath); + dbus_message_iter_close_container(&iter, &dict); return send_message_and_unref(conn, reply); -- cgit From 769c4b021665a26c9a6c20457ef9b7ded54c8ad6 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 24 Mar 2008 18:04:12 +0000 Subject: Fix dbus_message_iter_append_variant to use dbus string array format (char **) instead GSList. --- hcid/device.c | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f5929861..d5d2606f 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -748,6 +748,30 @@ static DBusHandlerResult disconnect(DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +static gboolean device_is_paired(struct device *device) +{ + struct adapter *adapter = device->adapter; + char filename[PATH_MAX + 1], *str; + gboolean ret; + + create_name(filename, PATH_MAX, STORAGEDIR, + adapter->address, "linkkeys"); + str = textfile_caseget(filename, device->address); + ret = str ? TRUE : FALSE; + g_free(str); + + return ret; +} + +static char *device_get_name(struct device *device) +{ + struct adapter *adapter = device->adapter; + char filename[PATH_MAX + 1]; + + create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names"); + return textfile_caseget(filename, device->address); +} + static DBusHandlerResult get_properties(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -757,12 +781,14 @@ static DBusHandlerResult get_properties(DBusConnection *conn, DBusMessageIter iter; DBusMessageIter dict; bdaddr_t src, dst; - char filename[PATH_MAX + 1], path[MAX_PATH_LENGTH]; + char path[MAX_PATH_LENGTH]; char buf[64]; const char *ptr; - char *str, *name, *ppath; + char *name, *ppath, **uuids; dbus_bool_t boolean; uint32_t class; + int i; + GSList *l; reply = dbus_message_new_method_return(msg); if (!reply) @@ -780,8 +806,7 @@ static DBusHandlerResult get_properties(DBusConnection *conn, &device->address); /* Name */ - create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names"); - name = textfile_caseget(filename, device->address); + name = device_get_name(device); if (name) { dbus_message_iter_append_dict_entry(&dict, "Name", DBUS_TYPE_STRING, &name); @@ -808,16 +833,7 @@ static DBusHandlerResult get_properties(DBusConnection *conn, } /* Paired */ - create_name(filename, PATH_MAX, STORAGEDIR, - adapter->address, "linkkeys"); - str = textfile_caseget(filename, device->address); - if (str) { - boolean = TRUE; - free(str); - } else { - boolean = FALSE; - } - + boolean = device_is_paired(device); dbus_message_iter_append_dict_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean); @@ -837,8 +853,12 @@ static DBusHandlerResult get_properties(DBusConnection *conn, DBUS_TYPE_BOOLEAN, &boolean); /* UUIDs */ + uuids = g_new0(char *, g_slist_length(device->uuids) + 1); + for (i = 0, l = device->uuids; l; l = l->next, i++) + uuids[i] = l->data; dbus_message_iter_append_dict_entry(&dict, "UUIDs", - DBUS_TYPE_ARRAY, device->uuids); + DBUS_TYPE_ARRAY, &uuids); + g_free(uuids); /* Adapter */ snprintf(path, sizeof(path), "/hci%d", adapter->dev_id); -- cgit From cbace5633e81298844f4223ca1ca1c5d767dde5b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 24 Mar 2008 20:58:54 +0000 Subject: Emit old device signals when a property is changed. --- hcid/device.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index d5d2606f..b1f53351 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -879,7 +879,7 @@ static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, DBusMessage *reply; bdaddr_t bdaddr; int ecode; - char *str, filename[PATH_MAX + 1]; + char *str, filename[PATH_MAX + 1], path[MAX_PATH_LENGTH]; str2ba(device->address, &bdaddr); @@ -901,11 +901,19 @@ static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; + snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id); + + dbus_connection_emit_signal(conn, path, + ADAPTER_INTERFACE, "RemoteAliasChanged", + DBUS_TYPE_STRING, &device->address, + DBUS_TYPE_STRING, &str, + DBUS_TYPE_INVALID); + dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg), DEVICE_INTERFACE, "Alias", DBUS_TYPE_STRING, &str); - free(str); + g_free(str); return send_message_and_unref(conn, reply); } @@ -917,6 +925,7 @@ static DBusHandlerResult set_trust(DBusConnection *conn, DBusMessage *msg, struct adapter *adapter = device->adapter; DBusMessage *reply; bdaddr_t local; + char path[MAX_PATH_LENGTH]; reply = dbus_message_new_method_return(msg); if (!reply) @@ -926,6 +935,13 @@ static DBusHandlerResult set_trust(DBusConnection *conn, DBusMessage *msg, write_trust(&local, device->address, GLOBAL_TRUST, value); + snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id); + + dbus_connection_emit_signal(conn, path, + ADAPTER_INTERFACE, "TrustAdded", + DBUS_TYPE_STRING, &device->address, + DBUS_TYPE_INVALID); + dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg), DEVICE_INTERFACE, "Trusted", DBUS_TYPE_BOOLEAN, &value); -- cgit From 40d6167dd9cec68fc24b331692a8f7f3ec63f95a Mon Sep 17 00:00:00 2001 From: Vinicius Gomes Date: Fri, 28 Mar 2008 21:23:23 +0000 Subject: device: fixing the TrustRemoved signal, when setting the Trusted attribute via Property. --- hcid/device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index b1f53351..b0532712 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -938,7 +938,8 @@ static DBusHandlerResult set_trust(DBusConnection *conn, DBusMessage *msg, snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id); dbus_connection_emit_signal(conn, path, - ADAPTER_INTERFACE, "TrustAdded", + ADAPTER_INTERFACE, + value ? "TrustAdded" : "TrustRemoved", DBUS_TYPE_STRING, &device->address, DBUS_TYPE_INVALID); -- cgit From 3d9966f38f1d6ca12c9e9e2eace5181ba04844b4 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 8 Apr 2008 22:35:49 +0000 Subject: Fix CreatePairedDevice and CreateDevice behavior. --- hcid/device.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 7 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index b0532712..32567851 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -59,11 +59,18 @@ #include "dbus-common.h" #include "dbus-hci.h" #include "error.h" +#include "glib-helper.h" #define MAX_DEVICES 16 #define DEVICE_INTERFACE "org.bluez.Device" +struct browse_req { + DBusConnection *conn; + DBusMessage *msg; + struct device *device; +}; + struct hci_peer { struct timeval lastseen; struct timeval lastused; @@ -1035,13 +1042,7 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, return device; } -void device_remove(DBusConnection *conn, struct device *device) -{ - device_destroy(device, conn); - device_free(device); -} - -void device_destroy(struct device *device, DBusConnection *conn) +void device_remove(struct device *device, DBusConnection *conn) { debug("Removing device %s", device->path); @@ -1052,3 +1053,95 @@ gint device_address_cmp(struct device *device, const gchar *address) { return strcasecmp(device->address, address); } + +static void browse_cb(gpointer user_data, sdp_list_t *recs, int err) +{ + sdp_list_t *seq, *next, *svcclass; + struct browse_req *req = user_data; + struct device *device = req->device; + struct adapter *adapter = device->adapter; + bdaddr_t src, dst; + char **uuids; + int i; + GSList *l; + DBusMessage *reply; + + if (err < 0) + return; + + for (seq = recs; seq; seq = next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + + if (!rec) + break; + + svcclass = NULL; + if (sdp_get_service_classes(rec, &svcclass) == 0) { + /* Extract the first element and skip the remainning */ + gchar *uuid_str = bt_uuid2string(svcclass->data); + if (uuid_str) { + if (!g_slist_find_custom(device->uuids, uuid_str, + (GCompareFunc) strcmp)) + device->uuids = g_slist_insert_sorted(device->uuids, + uuid_str, (GCompareFunc) strcmp); + else + g_free(uuid_str); + } + sdp_list_free(svcclass, free); + } + + next = seq->next; + } + + sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); + + /* Store the device's profiles in the filesystem */ + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + if (device->uuids) { + gchar *str = bt_list2string(device->uuids); + write_device_profiles(&src, &dst, str); + g_free(str); + } else + write_device_profiles(&src, &dst, ""); + + uuids = g_new0(char *, g_slist_length(device->uuids) + 1); + for (i = 0, l = device->uuids; l; l = l->next, i++) + uuids[i] = l->data; + + dbus_connection_emit_property_changed(req->conn, device->path, + DEVICE_INTERFACE, "UUIDs", + DBUS_TYPE_ARRAY, &uuids); + g_free(uuids); + + /* Reply create device request */ + reply = dbus_message_new_method_return(req->msg); + if (!reply) + return; + + dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, + DBUS_TYPE_INVALID); + + send_message_and_unref(req->conn, reply); + + dbus_message_unref(req->msg); + dbus_connection_unref(req->conn); + g_free(req); +} + +int device_browse(struct device *device, DBusConnection *conn, + DBusMessage *msg) +{ + struct adapter *adapter = device->adapter; + struct browse_req *req; + bdaddr_t src, dst; + + req = g_new0(struct browse_req, 1); + req->conn = dbus_connection_ref(conn); + req->msg = dbus_message_ref(msg); + req->device = device; + + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + return bt_discover_services(&src, &dst, browse_cb, req, NULL); +} -- cgit From 8d8f45c98ddabe1ffb5b2b4f93fa3983027ba740 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 9 Apr 2008 22:20:29 +0000 Subject: Fix DeviceCreated/DeviceRemoved signal being emitted for temporary devices. --- hcid/device.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 32567851..1a0840e5 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1114,6 +1114,11 @@ static void browse_cb(gpointer user_data, sdp_list_t *recs, int err) DBUS_TYPE_ARRAY, &uuids); g_free(uuids); + dbus_connection_emit_signal(req->conn, dbus_message_get_path(req->msg), + ADAPTER_INTERFACE, "DeviceCreated", + DBUS_TYPE_OBJECT_PATH, &device->path, + DBUS_TYPE_INVALID); + /* Reply create device request */ reply = dbus_message_new_method_return(req->msg); if (!reply) -- cgit From fb27732e05fb7b69c3b784ed8a6aaed2d9d939ae Mon Sep 17 00:00:00 2001 From: Cidorvan Leite Date: Thu, 10 Apr 2008 22:36:58 +0000 Subject: Added local agent in CreatePairedDevice --- hcid/device.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 1a0840e5..1e80b51e 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -60,6 +60,7 @@ #include "dbus-hci.h" #include "error.h" #include "glib-helper.h" +#include "agent.h" #define MAX_DEVICES 16 @@ -737,6 +738,8 @@ int get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) static void device_free(struct device *device) { + if (device->agent) + agent_destroy(device->agent, FALSE); g_slist_foreach(device->uuids, (GFunc) g_free, NULL); g_slist_free(device->uuids); g_free(device->address); -- cgit From 7b67507336f98dda5523902806dd2e33684fab6b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 14 Apr 2008 18:22:50 +0000 Subject: Fix bug that happen when sdp discovery fails no reply is send. --- hcid/device.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 1e80b51e..4f9dcdf9 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1070,7 +1070,7 @@ static void browse_cb(gpointer user_data, sdp_list_t *recs, int err) DBusMessage *reply; if (err < 0) - return; + goto proceed; for (seq = recs; seq; seq = next) { sdp_record_t *rec = (sdp_record_t *) seq->data; @@ -1117,6 +1117,7 @@ static void browse_cb(gpointer user_data, sdp_list_t *recs, int err) DBUS_TYPE_ARRAY, &uuids); g_free(uuids); +proceed: dbus_connection_emit_signal(req->conn, dbus_message_get_path(req->msg), ADAPTER_INTERFACE, "DeviceCreated", DBUS_TYPE_OBJECT_PATH, &device->path, @@ -1125,13 +1126,14 @@ static void browse_cb(gpointer user_data, sdp_list_t *recs, int err) /* Reply create device request */ reply = dbus_message_new_method_return(req->msg); if (!reply) - return; + goto fail; dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, DBUS_TYPE_INVALID); send_message_and_unref(req->conn, reply); +fail: dbus_message_unref(req->msg); dbus_connection_unref(req->conn); g_free(req); -- cgit From 601e16bf2f6677cf1a7d3fd12dcb127923e216b4 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 24 Apr 2008 14:58:05 +0000 Subject: Fix discover services callback function. --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 4f9dcdf9..09cd7450 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1057,7 +1057,7 @@ gint device_address_cmp(struct device *device, const gchar *address) return strcasecmp(device->address, address); } -static void browse_cb(gpointer user_data, sdp_list_t *recs, int err) +static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) { sdp_list_t *seq, *next, *svcclass; struct browse_req *req = user_data; -- cgit From fa7d18bdf518a3ea6cb379a1b765547c58155166 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 25 Apr 2008 13:06:37 +0000 Subject: Fix bugs on debug messages and fix Adapter property to be DBUS_TYPE_OBJECT_PATH. --- hcid/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 09cd7450..a1cd7d37 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -133,7 +133,7 @@ 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", + error("Can't open device hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } @@ -491,7 +491,7 @@ static int digi_revision(uint16_t dev_id, char *revision, size_t size) dd = hci_open_dev(dev_id); if (dd < 0) { - error("Can't open device hci%d", + error("Can't open device hci%d: %s (%d)", dev_id, strerror(errno), errno); return -errno; } @@ -874,7 +874,7 @@ static DBusHandlerResult get_properties(DBusConnection *conn, snprintf(path, sizeof(path), "/hci%d", adapter->dev_id); ppath = path; dbus_message_iter_append_dict_entry(&dict, "Adapter", - DBUS_TYPE_STRING, &ppath); + DBUS_TYPE_OBJECT_PATH, &ppath); dbus_message_iter_close_container(&iter, &dict); -- cgit From ecbcc749831ab86da7ed8d15c36f1bd1fb380be8 Mon Sep 17 00:00:00 2001 From: Cidorvan Leite Date: Wed, 7 May 2008 15:02:14 +0000 Subject: MAC address converted to upper case when creating an object path --- hcid/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index a1cd7d37..da3c560e 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1017,15 +1017,18 @@ static DBusSignalVTable device_signals[] = { struct device *device_create(DBusConnection *conn, struct adapter *adapter, const gchar *address, GSList *uuids) { + gchar *address_up; struct device *device; device = g_try_malloc0(sizeof(struct device)); if (device == NULL) return NULL; + address_up = g_ascii_strup(address, -1); device->path = g_strdup_printf("/hci%d/dev_%s", - adapter->dev_id, address); + adapter->dev_id, address_up); g_strdelimit(device->path, ":", '_'); + g_free(address_up); debug("Creating device %s", device->path); -- cgit From dc1d11fbfd62e265ca9cea65b5e999c7f9d6cfc3 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 7 May 2008 18:28:42 +0000 Subject: fixed format string --- hcid/device.c | 77 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 35 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index da3c560e..56a70ec2 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -129,19 +129,20 @@ void init_adapters(void) static int device_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr) { - int dd; + int dd, err; dd = hci_open_dev(dev_id); if (dd < 0) { + err = errno; error("Can't open device hci%d: %s (%d)", - dev_id, strerror(errno), errno); - return -errno; + dev_id, strerror(err), err); + return -err; } if (hci_read_bd_addr(dd, bdaddr, 2000) < 0) { - int err = errno; + err = errno; error("Can't read address for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } @@ -262,15 +263,16 @@ int start_adapter(uint16_t dev_id) dd = hci_open_dev(dev_id); if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; + err = errno; + error("Can't open device hci%d: %s (%d)", + dev_id, strerror(err), err); + return -err; } if (hci_read_local_version(dd, &ver, 1000) < 0) { - int err = errno; + err = errno; error("Can't read version info for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } @@ -364,9 +366,9 @@ setup: goto done; if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { - int err = errno; + err = errno; error("Can't write inquiry mode for hci%d: %s (%d)", - dev_id, strerror(errno), err); + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } @@ -402,9 +404,10 @@ int update_adapter(uint16_t dev_id) dd = hci_open_dev(dev_id); if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; + int err = errno; + error("Can't open device hci%d: %s (%d)", + dev_id, strerror(err), err); + return -err; } update_ext_inquiry_response(dd, dev); @@ -487,13 +490,14 @@ static int digi_revision(uint16_t dev_id, char *revision, size_t size) struct hci_request rq; unsigned char req[] = { 0x07 }; unsigned char buf[102]; - int dd; + int dd, err; dd = hci_open_dev(dev_id); if (dd < 0) { + err = errno; error("Can't open device hci%d: %s (%d)", - dev_id, strerror(errno), errno); - return -errno; + dev_id, strerror(err), err); + return -err; } memset(&rq, 0, sizeof(rq)); @@ -505,9 +509,9 @@ static int digi_revision(uint16_t dev_id, char *revision, size_t size) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 2000) < 0) { - int err = errno; + err = errno; error("Can't read revision for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } @@ -587,9 +591,10 @@ int set_simple_pairing_mode(uint16_t dev_id, uint8_t mode) dd = hci_open_dev(dev_id); if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; + int err = errno; + error("Can't open device hci%d: %s (%d)", + dev_id, strerror(err), err); + return -err; } update_ext_inquiry_response(dd, dev); @@ -602,7 +607,7 @@ int set_simple_pairing_mode(uint16_t dev_id, uint8_t mode) int get_device_name(uint16_t dev_id, char *name, size_t size) { char tmp[249]; - int dd; + int dd, err; ASSERT_DEV_ID; @@ -610,15 +615,16 @@ int get_device_name(uint16_t dev_id, char *name, size_t size) dd = hci_open_dev(dev_id); if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; + err = errno; + error("Can't open device hci%d: %s (%d)", + dev_id, strerror(err), err); + return -err; } if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) { - int err = errno; + err = errno; error("Can't read name for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } @@ -633,7 +639,7 @@ int get_device_name(uint16_t dev_id, char *name, size_t size) int set_device_name(uint16_t dev_id, const char *name) { struct hci_dev *dev; - int dd; + int dd, err; ASSERT_DEV_ID; @@ -641,15 +647,16 @@ int set_device_name(uint16_t dev_id, const char *name) dd = hci_open_dev(dev_id); if (dd < 0) { - error("Can't open device hci%d", - dev_id, strerror(errno), errno); - return -errno; + err = errno; + error("Can't open device hci%d: %s (%d)", + dev_id, strerror(err), err); + return -err; } if (hci_write_local_name(dd, name, 5000) < 0) { - int err = errno; + err = errno; error("Can't write name for hci%d: %s (%d)", - dev_id, strerror(errno), errno); + dev_id, strerror(err), err); hci_close_dev(dd); return -err; } -- cgit From 15ea15b3a752f0487bc50d0ea04925f1b9d33dcb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 May 2008 22:19:14 +0000 Subject: Move D-Bus object and interface helpers into libgdbus --- hcid/device.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 56a70ec2..850ce1af 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -42,10 +42,8 @@ #include #include - #include - -#include "dbus-helper.h" +#include #include "hcid.h" #include "sdpd.h" -- cgit From 24cce397c3479e95f3e525da9285234fbafd2984 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 May 2008 13:11:05 +0000 Subject: Add first skeletion of device driver integration --- hcid/device.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 850ce1af..f8550b4a 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1163,3 +1163,23 @@ int device_browse(struct device *device, DBusConnection *conn, str2ba(device->address, &dst); return bt_discover_services(&src, &dst, browse_cb, req, NULL); } + +static GSList *drivers = NULL; + +int btd_register_device_driver(struct btd_device_driver *driver) +{ + const char **uuid; + + drivers = g_slist_append(drivers, driver); + + for (uuid = driver->uuids; *uuid; uuid++) { + debug("name %s uuid %s", driver->name, *uuid); + } + + return 0; +} + +void btd_unregister_device_driver(struct btd_device_driver *driver) +{ + drivers = g_slist_remove(drivers, driver); +} -- cgit From de29b2ff1d8531fd0583e49e4b8840198681ffe8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2008 07:39:11 +0000 Subject: Handle the service UUID mapping via device driver --- hcid/device.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f8550b4a..ec0429af 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -56,6 +56,7 @@ #include "device.h" #include "dbus-common.h" #include "dbus-hci.h" +#include "dbus-service.h" #include "error.h" #include "glib-helper.h" #include "agent.h" @@ -1176,10 +1177,14 @@ int btd_register_device_driver(struct btd_device_driver *driver) debug("name %s uuid %s", driver->name, *uuid); } + register_service(driver->name, driver->uuids); + return 0; } void btd_unregister_device_driver(struct btd_device_driver *driver) { + unregister_service(driver->name); + drivers = g_slist_remove(drivers, driver); } -- cgit From e2731d4c2e3ef7d1677a73aca5fa58f044075980 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 3 Jun 2008 14:34:14 +0000 Subject: Converted Device interface to use new GDBusMethodTable --- hcid/device.c | 86 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 46 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index ec0429af..dc3e1c20 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -742,8 +742,10 @@ int get_encryption_key_size(uint16_t dev_id, const bdaddr_t *baddr) return size; } -static void device_free(struct device *device) +static void device_free(gpointer user_data) { + struct device *device = user_data; + if (device->agent) agent_destroy(device->agent, FALSE); g_slist_foreach(device->uuids, (GFunc) g_free, NULL); @@ -753,15 +755,10 @@ static void device_free(struct device *device) g_free(device); } -static void device_unregister(DBusConnection *conn, void *user_data) -{ - device_free(user_data); -} - -static DBusHandlerResult disconnect(DBusConnection *conn, - DBusMessage *msg, void *user_data) +static DBusMessage *disconnect(DBusConnection *conn, + DBusMessage *msg, void *user_data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + return dbus_message_new_method_return(msg); } static gboolean device_is_paired(struct device *device) @@ -788,8 +785,8 @@ static char *device_get_name(struct device *device) return textfile_caseget(filename, device->address); } -static DBusHandlerResult get_properties(DBusConnection *conn, - DBusMessage *msg, void *user_data) +static DBusMessage *get_properties(DBusConnection *conn, + DBusMessage *msg, void *user_data) { struct device *device = user_data; struct adapter *adapter = device->adapter; @@ -808,7 +805,7 @@ static DBusHandlerResult get_properties(DBusConnection *conn, reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; dbus_message_iter_init_append(reply, &iter); @@ -884,15 +881,14 @@ static DBusHandlerResult get_properties(DBusConnection *conn, dbus_message_iter_close_container(&iter, &dict); - return send_message_and_unref(conn, reply); + return reply; } -static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg, const char *alias, void *data) { struct device *device = data; struct adapter *adapter = device->adapter; - DBusMessage *reply; bdaddr_t bdaddr; int ecode; char *str, filename[PATH_MAX + 1], path[MAX_PATH_LENGTH]; @@ -911,11 +907,9 @@ static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, } if (ecode < 0) - return error_failed_errno(conn, msg, -ecode); - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return g_dbus_create_error(msg, + ERROR_INTERFACE ".Failed", + strerror(-ecode)); snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id); @@ -931,22 +925,17 @@ static DBusHandlerResult set_alias(DBusConnection *conn, DBusMessage *msg, g_free(str); - return send_message_and_unref(conn, reply); + return dbus_message_new_method_return(msg); } -static DBusHandlerResult set_trust(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg, dbus_bool_t value, void *data) { struct device *device = data; struct adapter *adapter = device->adapter; - DBusMessage *reply; bdaddr_t local; char path[MAX_PATH_LENGTH]; - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - str2ba(adapter->address, &local); write_trust(&local, device->address, GLOBAL_TRUST, value); @@ -963,34 +952,41 @@ static DBusHandlerResult set_trust(DBusConnection *conn, DBusMessage *msg, DEVICE_INTERFACE, "Trusted", DBUS_TYPE_BOOLEAN, &value); - return send_message_and_unref(conn, reply); + return dbus_message_new_method_return(msg); } -static DBusHandlerResult set_property(DBusConnection *conn, - DBusMessage *msg, void *data) +static inline DBusMessage *invalid_args(DBusMessage *msg) +{ + return g_dbus_create_error(msg, + ERROR_INTERFACE ".InvalidArguments", + "Invalid arguments in method call"); +} + +static DBusMessage *set_property(DBusConnection *conn, + DBusMessage *msg, void *data) { DBusMessageIter iter; DBusMessageIter sub; const char *property; if (!dbus_message_iter_init(msg, &iter)) - return error_invalid_arguments(conn, msg, NULL); + return invalid_args(msg); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) - return error_invalid_arguments(conn, msg, NULL); + return invalid_args(msg); dbus_message_iter_get_basic(&iter, &property); dbus_message_iter_next(&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) - return error_invalid_arguments(conn, msg, NULL); + return invalid_args(msg); dbus_message_iter_recurse(&iter, &sub); if (g_str_equal("Trusted", property)) { dbus_bool_t value; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) - return error_invalid_arguments(conn, msg, NULL); + return invalid_args(msg); dbus_message_iter_get_basic(&sub, &value); return set_trust(conn, msg, value, data); @@ -998,23 +994,23 @@ static DBusHandlerResult set_property(DBusConnection *conn, char *alias; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) - return error_invalid_arguments(conn, msg, NULL); + return invalid_args(msg); dbus_message_iter_get_basic(&sub, &alias); return set_alias(conn, msg, alias, data); } - return error_invalid_arguments(conn, msg, NULL); + return invalid_args(msg); } -static DBusMethodVTable device_methods[] = { - { "GetProperties", get_properties, "", "a{sv}" }, - { "SetProperty", set_property, "sv", "" }, - { "Disconnect", disconnect, "", "" }, +static GDBusMethodTable device_methods[] = { + { "GetProperties", "", "a{sv}", get_properties }, + { "SetProperty", "sv", "", set_property }, + { "Disconnect", "", "", disconnect }, { NULL, NULL, NULL, NULL } }; -static DBusSignalVTable device_signals[] = { +static GDBusSignalTable device_signals[] = { { "PropertyChanged", "sv" }, { "DisconnectRequested", "" }, { NULL, NULL } @@ -1038,15 +1034,13 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, debug("Creating device %s", device->path); - if (dbus_connection_create_object_path(conn, device->path, - device, device_unregister) == FALSE) { + if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE, + device_methods, device_signals, NULL, + device, device_free) == FALSE) { device_free(device); return NULL; } - dbus_connection_register_interface(conn, device->path, - DEVICE_INTERFACE, device_methods, device_signals, NULL); - device->address = g_strdup(address); device->adapter = adapter; device->uuids = uuids; -- cgit From 4bf06e9d9eaea15b4e0f251571877da985901bf4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jun 2008 15:52:51 +0000 Subject: Replace destroy function with proper unregister call --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index dc3e1c20..88f412c6 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1052,7 +1052,7 @@ void device_remove(struct device *device, DBusConnection *conn) { debug("Removing device %s", device->path); - dbus_connection_destroy_object_path(conn, device->path); + g_dbus_unregister_interface(conn, device->path, DEVICE_INTERFACE); } gint device_address_cmp(struct device *device, const gchar *address) -- cgit From 0472470e5059e702f0e7e69ee0155dfea11baa25 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jun 2008 10:02:39 +0000 Subject: Fix one last reference to sending helper --- hcid/device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 88f412c6..1c507329 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1134,7 +1134,9 @@ proceed: dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, DBUS_TYPE_INVALID); - send_message_and_unref(req->conn, reply); + dbus_connection_send(req->conn, reply, NULL); + + dbus_message_unref(reply); fail: dbus_message_unref(req->msg); -- cgit From 8955dc1ce35be8c0ef70b0faa8846c2bf4b6de9f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jun 2008 13:35:07 +0000 Subject: More cleanups and less casting --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 1c507329..423f35a6 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1048,7 +1048,7 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, return device; } -void device_remove(struct device *device, DBusConnection *conn) +void device_remove(DBusConnection *conn, struct device *device) { debug("Removing device %s", device->path); -- cgit From f62f8d892b5d5cc5aedef83779671c1ed54a35da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jun 2008 14:17:47 +0000 Subject: Fix path reference usage after freeing device object --- hcid/device.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 423f35a6..f24b98b1 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -748,8 +748,10 @@ static void device_free(gpointer user_data) if (device->agent) agent_destroy(device->agent, FALSE); + g_slist_foreach(device->uuids, (GFunc) g_free, NULL); g_slist_free(device->uuids); + g_free(device->address); g_free(device->path); g_free(device); @@ -1050,9 +1052,13 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, void device_remove(DBusConnection *conn, struct device *device) { - debug("Removing device %s", device->path); + gchar *path = g_strdup(device->path); + + debug("Removing device %s", path); + + g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); - g_dbus_unregister_interface(conn, device->path, DEVICE_INTERFACE); + g_free(path); } gint device_address_cmp(struct device *device, const gchar *address) -- cgit From d69e08eb0d567b61106ca37e0546402f4ae0c34e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jun 2008 14:19:19 +0000 Subject: Check for alternative UUIDs if public browse group fails --- hcid/device.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f24b98b1..9a814047 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -69,6 +69,7 @@ struct browse_req { DBusConnection *conn; DBusMessage *msg; struct device *device; + int search_uuid; }; struct hci_peer { @@ -118,6 +119,14 @@ static struct hci_dev devices[MAX_DEVICES]; #define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; } +static uint16_t uuid_list[] = { + PUBLIC_BROWSE_GROUP, + GENERIC_AUDIO_SVCLASS_ID, + ADVANCED_AUDIO_SVCLASS_ID, + AV_REMOTE_SVCLASS_ID, + 0 +}; + void init_adapters(void) { int i; @@ -1077,6 +1086,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) int i; GSList *l; DBusMessage *reply; + uuid_t uuid; if (err < 0) goto proceed; @@ -1126,6 +1136,16 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) DBUS_TYPE_ARRAY, &uuids); g_free(uuids); + /* Public browsing was succesful */ + if (!req->search_uuid && recs) + goto proceed; + + if (uuid_list[++req->search_uuid]) { + sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]); + bt_search_service(&src, &dst, &uuid, browse_cb, user_data, NULL); + return; + } + proceed: dbus_connection_emit_signal(req->conn, dbus_message_get_path(req->msg), ADAPTER_INTERFACE, "DeviceCreated", @@ -1156,6 +1176,7 @@ int device_browse(struct device *device, DBusConnection *conn, struct adapter *adapter = device->adapter; struct browse_req *req; bdaddr_t src, dst; + uuid_t uuid; req = g_new0(struct browse_req, 1); req->conn = dbus_connection_ref(conn); @@ -1164,7 +1185,9 @@ int device_browse(struct device *device, DBusConnection *conn, str2ba(adapter->address, &src); str2ba(device->address, &dst); - return bt_discover_services(&src, &dst, browse_cb, req, NULL); + sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]); + + return bt_search_service(&src, &dst, &uuid, browse_cb, req, NULL); } static GSList *drivers = NULL; -- cgit From f80a7215275b229a597cf8d2bbc7e4e208af522c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 7 Jun 2008 19:30:24 +0000 Subject: Use g_dbus_emit_signal for sending D-Bus signals --- hcid/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 9a814047..8cd0c131 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -924,7 +924,7 @@ static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg, snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id); - dbus_connection_emit_signal(conn, path, + g_dbus_emit_signal(conn, path, ADAPTER_INTERFACE, "RemoteAliasChanged", DBUS_TYPE_STRING, &device->address, DBUS_TYPE_STRING, &str, @@ -953,7 +953,7 @@ static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg, snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id); - dbus_connection_emit_signal(conn, path, + g_dbus_emit_signal(conn, path, ADAPTER_INTERFACE, value ? "TrustAdded" : "TrustRemoved", DBUS_TYPE_STRING, &device->address, @@ -1147,7 +1147,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) } proceed: - dbus_connection_emit_signal(req->conn, dbus_message_get_path(req->msg), + g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg), ADAPTER_INTERFACE, "DeviceCreated", DBUS_TYPE_OBJECT_PATH, &device->path, DBUS_TYPE_INVALID); -- cgit From 94c199911b1dc1395a8025647f0686f58e6bf4f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 16:52:11 +0000 Subject: Add the missing device API calls --- hcid/device.c | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 8cd0c131..65ed8ab4 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -766,12 +766,6 @@ static void device_free(gpointer user_data) g_free(device); } -static DBusMessage *disconnect(DBusConnection *conn, - DBusMessage *msg, void *user_data) -{ - return dbus_message_new_method_return(msg); -} - static gboolean device_is_paired(struct device *device) { struct adapter *adapter = device->adapter; @@ -1014,17 +1008,50 @@ static DBusMessage *set_property(DBusConnection *conn, return invalid_args(msg); } +static DBusMessage *discover_services(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + const char *pattern; + + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID) == FALSE) + return NULL; + + /* FIXME start service discovery */ + + return NULL; +} + +static DBusMessage *cancel_discover(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + /* FIXME cancel discovery */ + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *disconnect(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + /* FIXME disconnect device */ + + return dbus_message_new_method_return(msg); +} + static GDBusMethodTable device_methods[] = { { "GetProperties", "", "a{sv}", get_properties }, { "SetProperty", "sv", "", set_property }, + { "DiscoverServices", "s", "a{sv}", discover_services, + G_DBUS_METHOD_FLAG_ASYNC}, + { "CancelDiscovery", "", "", cancel_discover }, { "Disconnect", "", "", disconnect }, - { NULL, NULL, NULL, NULL } + { } }; static GDBusSignalTable device_signals[] = { - { "PropertyChanged", "sv" }, - { "DisconnectRequested", "" }, - { NULL, NULL } + { "PropertyChanged", "sv" }, + { "DisconnectRequested", "" }, + { } }; struct device *device_create(DBusConnection *conn, struct adapter *adapter, -- cgit From f4eb9e2dea643f41e261bb9e2bff33fc03bd9ecc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 17:18:24 +0000 Subject: Add first attempt for driver probing --- hcid/device.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 65ed8ab4..fee2a4e8 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -119,6 +119,8 @@ static struct hci_dev devices[MAX_DEVICES]; #define ASSERT_DEV_ID { if (dev_id >= MAX_DEVICES) return -ERANGE; } +static GSList *drivers = NULL; + static uint16_t uuid_list[] = { PUBLIC_BROWSE_GROUP, GENERIC_AUDIO_SVCLASS_ID, @@ -1102,6 +1104,37 @@ gint device_address_cmp(struct device *device, const gchar *address) return strcasecmp(device->address, address); } +static void probe_matching_drivers(struct device *device) +{ + GSList *drv_list; + const char **drv_uuid; + struct btd_device_driver *driver; + int err; + + debug("Probe drivers for %s", device->path); + + for (drv_list = drivers; drv_list; drv_list = drv_list->next) { + driver = (struct btd_device_driver *) drv_list->data; + gboolean do_probe = FALSE; + + for (drv_uuid = driver->uuids; *drv_uuid; drv_uuid++) { + GSList *match = g_slist_find_custom(device->uuids, + *drv_uuid, (GCompareFunc) strcasecmp); + if (match) { + do_probe = TRUE; + break; + } + } + + if (do_probe == TRUE) { + err = driver->probe(device->path); + if (err < 0) + error("probe failed for driver %s", + driver->name); + } + } +} + static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) { sdp_list_t *seq, *next, *svcclass; @@ -1165,7 +1198,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) /* Public browsing was succesful */ if (!req->search_uuid && recs) - goto proceed; + goto probe; if (uuid_list[++req->search_uuid]) { sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]); @@ -1173,6 +1206,9 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) return; } +probe: + probe_matching_drivers(device); + proceed: g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg), ADAPTER_INTERFACE, "DeviceCreated", @@ -1217,8 +1253,6 @@ int device_browse(struct device *device, DBusConnection *conn, return bt_search_service(&src, &dst, &uuid, browse_cb, req, NULL); } -static GSList *drivers = NULL; - int btd_register_device_driver(struct btd_device_driver *driver) { const char **uuid; -- cgit From 6061f1a889c90d4d408ca12b63b2db6235c73bae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 20:38:09 +0000 Subject: Keep track of attached drivers --- hcid/device.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index fee2a4e8..7213cbf2 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1090,10 +1090,18 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, void device_remove(DBusConnection *conn, struct device *device) { + GSList *list; + struct btd_device_driver *driver; gchar *path = g_strdup(device->path); debug("Removing device %s", path); + for (list = device->drivers; list; list = list->next) { + driver = (struct btd_device_driver *) list->data; + + driver->remove(device->path); + } + g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); g_free(path); @@ -1106,31 +1114,36 @@ gint device_address_cmp(struct device *device, const gchar *address) static void probe_matching_drivers(struct device *device) { - GSList *drv_list; - const char **drv_uuid; + GSList *list; + const char **uuid; struct btd_device_driver *driver; int err; debug("Probe drivers for %s", device->path); - for (drv_list = drivers; drv_list; drv_list = drv_list->next) { - driver = (struct btd_device_driver *) drv_list->data; + for (list = drivers; list; list = list->next) { + driver = (struct btd_device_driver *) list->data; gboolean do_probe = FALSE; - for (drv_uuid = driver->uuids; *drv_uuid; drv_uuid++) { + for (uuid = driver->uuids; *uuid; uuid++) { GSList *match = g_slist_find_custom(device->uuids, - *drv_uuid, (GCompareFunc) strcasecmp); + *uuid, (GCompareFunc) strcasecmp); if (match) { do_probe = TRUE; break; } } - if (do_probe == TRUE) { + if (do_probe == TRUE && !g_slist_find_custom(device->drivers, + driver->name, (GCompareFunc) strcmp)) { + err = driver->probe(device->path); if (err < 0) error("probe failed for driver %s", driver->name); + else + device->drivers = g_slist_append(device->drivers, + driver); } } } -- cgit From 32033cb14df0294a742e9e8c6b5ffa8aa26c2cc1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 20:49:54 +0000 Subject: Make sure to probe drivers on startup --- hcid/device.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 7213cbf2..3264a8f6 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1112,7 +1112,7 @@ gint device_address_cmp(struct device *device, const gchar *address) return strcasecmp(device->address, address); } -static void probe_matching_drivers(struct device *device) +void device_probe_drivers(struct device *device) { GSList *list; const char **uuid; @@ -1136,7 +1136,6 @@ static void probe_matching_drivers(struct device *device) if (do_probe == TRUE && !g_slist_find_custom(device->drivers, driver->name, (GCompareFunc) strcmp)) { - err = driver->probe(device->path); if (err < 0) error("probe failed for driver %s", @@ -1219,8 +1218,8 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) return; } -probe: - probe_matching_drivers(device); +probe: + device_probe_drivers(device); proceed: g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg), -- cgit From f22b20c3d40bd7571944af6a4946f756dc39f812 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 21:26:20 +0000 Subject: Add HID profile to list of alternate UUIDs to browse --- hcid/device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 3264a8f6..e01bf7d2 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -123,6 +123,7 @@ static GSList *drivers = NULL; static uint16_t uuid_list[] = { PUBLIC_BROWSE_GROUP, + HID_SVCLASS_ID, GENERIC_AUDIO_SVCLASS_ID, ADVANCED_AUDIO_SVCLASS_ID, AV_REMOTE_SVCLASS_ID, -- cgit From 5243ac4fd278b0176ece84cbcec537a92a9c7290 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 22:57:11 +0000 Subject: Update probe/remove callback and implement serial API --- hcid/device.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index e01bf7d2..b040df91 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1086,6 +1086,10 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, device->adapter = adapter; device->uuids = uuids; + device->dev.path = device->path; + str2ba(device->address, &device->dev.dst); + str2ba(adapter->address, &device->dev.src); + return device; } @@ -1100,7 +1104,7 @@ void device_remove(DBusConnection *conn, struct device *device) for (list = device->drivers; list; list = list->next) { driver = (struct btd_device_driver *) list->data; - driver->remove(device->path); + driver->remove(&device->dev); } g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); @@ -1137,7 +1141,7 @@ void device_probe_drivers(struct device *device) if (do_probe == TRUE && !g_slist_find_custom(device->drivers, driver->name, (GCompareFunc) strcmp)) { - err = driver->probe(device->path); + err = driver->probe(&device->dev); if (err < 0) error("probe failed for driver %s", driver->name); -- cgit From a2529a9b417959a52f5d501cba4bcaf32caf6964 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 00:14:05 +0000 Subject: First attempt at Device.DiscoverServices() implementation --- hcid/device.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index b040df91..ef29f368 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -70,6 +70,7 @@ struct browse_req { DBusMessage *msg; struct device *device; int search_uuid; + gboolean update; }; struct hci_peer { @@ -1014,13 +1015,14 @@ static DBusMessage *set_property(DBusConnection *conn, static DBusMessage *discover_services(DBusConnection *conn, DBusMessage *msg, void *user_data) { + struct device *device = user_data; const char *pattern; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID) == FALSE) return NULL; - /* FIXME start service discovery */ + device_browse(device, conn, msg, TRUE); return NULL; } @@ -1227,6 +1229,12 @@ probe: device_probe_drivers(device); proceed: + if (req->update == TRUE) { + /* FIXME return handle/record dictonary */ + g_dbus_send_reply(req->conn, req->msg, DBUS_TYPE_INVALID); + goto fail; + } + g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg), ADAPTER_INTERFACE, "DeviceCreated", DBUS_TYPE_OBJECT_PATH, &device->path, @@ -1238,7 +1246,7 @@ proceed: goto fail; dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, - DBUS_TYPE_INVALID); + DBUS_TYPE_INVALID); dbus_connection_send(req->conn, reply, NULL); @@ -1251,7 +1259,7 @@ fail: } int device_browse(struct device *device, DBusConnection *conn, - DBusMessage *msg) + DBusMessage *msg, gboolean update) { struct adapter *adapter = device->adapter; struct browse_req *req; @@ -1262,6 +1270,7 @@ int device_browse(struct device *device, DBusConnection *conn, req->conn = dbus_connection_ref(conn); req->msg = dbus_message_ref(msg); req->device = device; + req->update = update; str2ba(adapter->address, &src); str2ba(device->address, &dst); -- cgit From fad3b8ad7a07de0c96c34b9d624ec174c2754817 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 11:38:44 +0000 Subject: Fix duplicate driver probing --- hcid/device.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index ef29f368..15bb41a1 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1142,14 +1142,16 @@ void device_probe_drivers(struct device *device) } if (do_probe == TRUE && !g_slist_find_custom(device->drivers, - driver->name, (GCompareFunc) strcmp)) { + driver, (GCompareFunc) strcmp)) { err = driver->probe(&device->dev); - if (err < 0) + if (err < 0) { error("probe failed for driver %s", driver->name); - else - device->drivers = g_slist_append(device->drivers, - driver); + continue; + } + + device->drivers = g_slist_append(device->drivers, + driver); } } } -- cgit From e0d13d6da4b527ee02838af6b9dd7d53615e4896 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 13:00:12 +0000 Subject: At minimum return an empty dictionary --- hcid/device.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 15bb41a1..36d0d8fd 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1046,7 +1046,7 @@ static DBusMessage *disconnect(DBusConnection *conn, static GDBusMethodTable device_methods[] = { { "GetProperties", "", "a{sv}", get_properties }, { "SetProperty", "sv", "", set_property }, - { "DiscoverServices", "s", "a{sv}", discover_services, + { "DiscoverServices", "s", "a{us}", discover_services, G_DBUS_METHOD_FLAG_ASYNC}, { "CancelDiscovery", "", "", cancel_discover }, { "Disconnect", "", "", disconnect }, @@ -1232,8 +1232,25 @@ probe: proceed: if (req->update == TRUE) { - /* FIXME return handle/record dictonary */ - g_dbus_send_reply(req->conn, req->msg, DBUS_TYPE_INVALID); + DBusMessageIter iter, dict; + + reply = dbus_message_new_method_return(req->msg); + if (!reply) + goto fail; + + dbus_message_iter_init_append(reply, &iter); + + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); + + /* FIXME add handle/record pairs */ + + dbus_message_iter_close_container(&iter, &dict); + + dbus_connection_send(req->conn, reply, NULL); + dbus_message_unref(reply); goto fail; } @@ -1251,7 +1268,6 @@ proceed: DBUS_TYPE_INVALID); dbus_connection_send(req->conn, reply, NULL); - dbus_message_unref(reply); fail: -- cgit From bbe56de7715cf62e37026711a6eb3f1c5be6d1cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 13:21:48 +0000 Subject: Fill the discovery record with record handles --- hcid/device.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 36d0d8fd..95efe3af 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1156,6 +1156,21 @@ void device_probe_drivers(struct device *device) } } +static void iter_append_record(DBusMessageIter *dict, uint32_t handle, + const char *record) +{ + DBusMessageIter entry; + + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, + NULL, &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record); + + dbus_message_iter_close_container(dict, &entry); +} + static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) { sdp_list_t *seq, *next, *svcclass; @@ -1196,8 +1211,6 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) next = seq->next; } - sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); - /* Store the device's profiles in the filesystem */ str2ba(adapter->address, &src); str2ba(device->address, &dst); @@ -1245,7 +1258,18 @@ proceed: DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - /* FIXME add handle/record pairs */ + for (seq = recs; seq; seq = next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + const char *val = ""; + + if (!rec) + break; + + /* FIXME add the real record string */ + iter_append_record(&dict, rec->handle, val); + + next = seq->next; + } dbus_message_iter_close_container(&iter, &dict); @@ -1271,6 +1295,9 @@ proceed: dbus_message_unref(reply); fail: + if (recs != NULL) + sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); + dbus_message_unref(req->msg); dbus_connection_unref(req->conn); g_free(req); -- cgit From 6be25e8bc36656d6fd8ba61c8552f9596043eca6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 16:29:21 +0000 Subject: Detect Simple Pairing support and enable it --- hcid/device.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 95efe3af..57986f88 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -325,6 +326,11 @@ int start_adapter(uint16_t dev_id) if (!(features[6] & LMP_SIMPLE_PAIR)) goto setup; + if (hcid_dbus_use_experimental()) { + if (ioctl(dd, HCIGETAUTHINFO, NULL) < 0 && errno != EINVAL) + hci_write_simple_pairing_mode(dd, 0x01, 2000); + } + 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)", @@ -377,7 +383,7 @@ setup: if (inqmode < 1) goto done; - if (hci_write_inquiry_mode(dd, inqmode, 1000) < 0) { + if (hci_write_inquiry_mode(dd, inqmode, 2000) < 0) { err = errno; error("Can't write inquiry mode for hci%d: %s (%d)", dev_id, strerror(err), err); -- cgit From 3d3cdef8da6b3e1b14c3cdccda8c099cbad4f3ae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 17:01:55 +0000 Subject: Append full record to discover service results --- hcid/device.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 57986f88..9dc7f4e9 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -61,6 +61,8 @@ #include "error.h" #include "glib-helper.h" #include "agent.h" +#include "dbus-sdp.h" +#include "sdp-xml.h" #define MAX_DEVICES 16 @@ -1266,13 +1268,21 @@ proceed: for (seq = recs; seq; seq = next) { sdp_record_t *rec = (sdp_record_t *) seq->data; - const char *val = ""; + sdp_buf_t result; if (!rec) break; - /* FIXME add the real record string */ - iter_append_record(&dict, rec->handle, val); + memset(&result, 0, sizeof(sdp_buf_t)); + + convert_sdp_record_to_xml(rec, &result, + append_and_grow_string); + + if (result.data) { + const char *val = result.data; + iter_append_record(&dict, rec->handle, val); + free(result.data); + } next = seq->next; } -- cgit From e83bab25294f23250d8d84b6e2e323fa7f38d0ca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Jun 2008 19:07:36 +0000 Subject: Fix signedness issue --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 9dc7f4e9..76bb90d1 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1279,7 +1279,7 @@ proceed: append_and_grow_string); if (result.data) { - const char *val = result.data; + const char *val = (char *) result.data; iter_append_record(&dict, rec->handle, val); free(result.data); } -- cgit From 5d49d848060b0809a25acb9a20b176600f52e66d Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 9 Jun 2008 22:06:09 +0000 Subject: Added device Disconnect --- hcid/device.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 76bb90d1..500a401c 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +65,8 @@ #include "dbus-sdp.h" #include "sdp-xml.h" -#define MAX_DEVICES 16 +#define MAX_DEVICES 16 +#define DISCONNECT_TIMER 2 #define DEVICE_INTERFACE "org.bluez.Device" @@ -773,6 +775,9 @@ static void device_free(gpointer user_data) g_slist_foreach(device->uuids, (GFunc) g_free, NULL); g_slist_free(device->uuids); + if (device->disconn_timer) + g_source_remove(device->disconn_timer); + g_free(device->address); g_free(device->path); g_free(device); @@ -1043,10 +1048,62 @@ static DBusMessage *cancel_discover(DBusConnection *conn, return dbus_message_new_method_return(msg); } +static gboolean disconnect_timeout(gpointer user_data) +{ + struct device *device = user_data; + struct active_conn_info *ci; + GSList *l; + disconnect_cp cp; + bdaddr_t bda; + int dd; + + device->disconn_timer = 0; + + str2ba(device->address, &bda); + l = g_slist_find_custom(device->adapter->active_conn, + &bda, active_conn_find_by_bdaddr); + if (!l) + return FALSE; + + ci = l->data; + dd = hci_open_dev(device->adapter->dev_id); + if (dd < 0) + goto fail; + + memset(&cp, 0, sizeof(cp)); + cp.handle = htobs(ci->handle); + cp.reason = HCI_OE_USER_ENDED_CONNECTION; + + hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, + DISCONNECT_CP_SIZE, &cp); + + close(dd); + +fail: + return FALSE; +} + static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg, void *user_data) { - /* FIXME disconnect device */ + struct device *device = user_data; + GSList *l; + bdaddr_t bda; + + str2ba(device->address, &bda); + l = g_slist_find_custom(device->adapter->active_conn, + &bda, active_conn_find_by_bdaddr); + if (!l) + return g_dbus_create_error(msg, + ERROR_INTERFACE ".NotConnected", + "Device is not connected"); + + g_dbus_emit_signal(conn, device->path, + DEVICE_INTERFACE, "DisconnectRequested", + DBUS_TYPE_INVALID); + + device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER, + disconnect_timeout, device); return dbus_message_new_method_return(msg); } -- cgit From a6f07d2bf12942854072c37c3c42d7447921beee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 10 Jun 2008 22:24:46 +0000 Subject: Use the pattern parameter in DiscoverServices() --- hcid/device.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 500a401c..a9a937c6 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -76,6 +76,7 @@ struct browse_req { struct device *device; int search_uuid; gboolean update; + gboolean browse; }; struct hci_peer { @@ -1030,12 +1031,22 @@ static DBusMessage *discover_services(DBusConnection *conn, { struct device *device = user_data; const char *pattern; + uint16_t search; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID) == FALSE) return NULL; - device_browse(device, conn, msg, TRUE); + if (strlen(pattern) == 0) { + device_browse(device, conn, msg, TRUE, 0); + return NULL; + } + + search = sdp_str2svclass(pattern); + if (!search) + return invalid_args(msg); + + device_browse(device, conn, msg, TRUE, search); return NULL; } @@ -1295,8 +1306,8 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) DBUS_TYPE_ARRAY, &uuids); g_free(uuids); - /* Public browsing was succesful */ - if (!req->search_uuid && recs) + /* Public browsing successful or Single record requested */ + if (req->browse == FALSE || (!req->search_uuid && recs)) goto probe; if (uuid_list[++req->search_uuid]) { @@ -1377,7 +1388,7 @@ fail: } int device_browse(struct device *device, DBusConnection *conn, - DBusMessage *msg, gboolean update) + DBusMessage *msg, gboolean update, uint16_t search) { struct adapter *adapter = device->adapter; struct browse_req *req; @@ -1392,7 +1403,14 @@ int device_browse(struct device *device, DBusConnection *conn, str2ba(adapter->address, &src); str2ba(device->address, &dst); - sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]); + + if (search) { + sdp_uuid16_create(&uuid, search); + req->browse = FALSE; + } else { + sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]); + req->browse = TRUE; + } return bt_search_service(&src, &dst, &uuid, browse_cb, req, NULL); } -- cgit From 19b4c8b0e51a20a1b95ede34b092ebc56e1183ae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jun 2008 14:26:54 +0000 Subject: Allow to cancel a service discovery --- hcid/device.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index a9a937c6..5c7584f2 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1054,7 +1054,14 @@ static DBusMessage *discover_services(DBusConnection *conn, static DBusMessage *cancel_discover(DBusConnection *conn, DBusMessage *msg, void *user_data) { - /* FIXME cancel discovery */ + struct device *device = user_data; + struct adapter *adapter = device->adapter; + bdaddr_t src,dst; + + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + + bt_cancel_discovery(&src, &dst); return dbus_message_new_method_return(msg); } -- cgit From e0863545e6239ac338fa7fbe9647a5748a60b436 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jun 2008 14:51:53 +0000 Subject: Fix driver structure declaration in the probe function --- hcid/device.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 5c7584f2..db21096d 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1206,13 +1206,12 @@ void device_probe_drivers(struct device *device) { GSList *list; const char **uuid; - struct btd_device_driver *driver; int err; debug("Probe drivers for %s", device->path); for (list = drivers; list; list = list->next) { - driver = (struct btd_device_driver *) list->data; + struct btd_device_driver *driver = list->data; gboolean do_probe = FALSE; for (uuid = driver->uuids; *uuid; uuid++) { -- cgit From 1e4c95e09bf53e50ad033febae0d6383517508b4 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jun 2008 15:35:41 +0000 Subject: Fix minor whitespace issues --- hcid/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index db21096d..f0e57e91 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1056,7 +1056,7 @@ static DBusMessage *cancel_discover(DBusConnection *conn, { struct device *device = user_data; struct adapter *adapter = device->adapter; - bdaddr_t src,dst; + bdaddr_t src, dst; str2ba(adapter->address, &src); str2ba(device->address, &dst); -- cgit From 289e29c6c4a073569c7e7aa3c8fc51ed5c46993f Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Jun 2008 16:56:38 +0000 Subject: Fix bt_cancel_discovery to only succeed when there is a discover to cancel. --- hcid/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f0e57e91..6b9ccac9 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1061,7 +1061,10 @@ static DBusMessage *cancel_discover(DBusConnection *conn, str2ba(adapter->address, &src); str2ba(device->address, &dst); - bt_cancel_discovery(&src, &dst); + if (bt_cancel_discovery(&src, &dst) < 0) + return g_dbus_create_error(msg, + ERROR_INTERFACE ".Failed", + "No pending discover"); return dbus_message_new_method_return(msg); } -- cgit From 342293a80657406a02003452e3a23d097dd9c73e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Jun 2008 21:18:33 +0000 Subject: Only allow discover requestor to cancel it. --- hcid/device.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 9 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 6b9ccac9..6c40cf88 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1026,29 +1026,64 @@ static DBusMessage *set_property(DBusConnection *conn, return invalid_args(msg); } +static void discover_services_req_exit(void *user_data) +{ + struct device *device = user_data; + struct adapter *adapter = device->adapter; + bdaddr_t src, dst; + + debug("DiscoverDevices requestor exited"); + + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + + bt_cancel_discovery(&src, &dst); +} + static DBusMessage *discover_services(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct device *device = user_data; const char *pattern; uint16_t search; + int err; + + if (device->discov_active) + return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", + "Discover in progress"); if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID) == FALSE) - return NULL; + goto fail; if (strlen(pattern) == 0) { - device_browse(device, conn, msg, TRUE, 0); - return NULL; - } + err = device_browse(device, conn, msg, TRUE, 0); + if (err < 0) + goto fail; + } else { - search = sdp_str2svclass(pattern); - if (!search) - return invalid_args(msg); + search = sdp_str2svclass(pattern); + if (!search) + return invalid_args(msg); - device_browse(device, conn, msg, TRUE, search); + err = device_browse(device, conn, msg, TRUE, search); + if (err < 0) + goto fail; + } + device->discov_active = 1; + device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); + /* track the request owner to cancel it automatically if the owner + * exits */ + device->discov_listener = g_dbus_add_disconnect_watch(conn, + dbus_message_get_sender(msg), + discover_services_req_exit, + device, NULL); return NULL; + +fail: + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Discovery Failed"); } static DBusMessage *cancel_discover(DBusConnection *conn, @@ -1058,7 +1093,19 @@ static DBusMessage *cancel_discover(DBusConnection *conn, struct adapter *adapter = device->adapter; bdaddr_t src, dst; - str2ba(adapter->address, &src); + if (!device->discov_active) + return g_dbus_create_error(msg, + ERROR_INTERFACE ".Failed", + "No pending discovery"); + + /* only the discover requestor can cancel the inquiry process */ + if (!device->discov_requestor || + strcmp(device->discov_requestor, dbus_message_get_sender(msg))) + return g_dbus_create_error(msg, + ERROR_INTERFACE ".NotAuthorized", + "Not Authorized"); + + str2ba(adapter->address, &src); str2ba(device->address, &dst); if (bt_cancel_discovery(&src, &dst) < 0) @@ -1269,6 +1316,15 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) DBusMessage *reply; uuid_t uuid; + device->discov_active = 0; + + if (device->discov_requestor) { + g_dbus_remove_watch(req->conn, device->discov_listener); + device->discov_listener = 0; + g_free(device->discov_requestor); + device->discov_requestor = NULL; + } + if (err < 0) goto proceed; -- cgit From 2efdbe3a944fb2c8c6e0f581b899140b4ef84bcb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 18 Jun 2008 14:16:59 +0000 Subject: Fix DiscoverDevice to wait untils the browse finishes to release the name listener. --- hcid/device.c | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 6c40cf88..7049a223 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1316,15 +1316,6 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) DBusMessage *reply; uuid_t uuid; - device->discov_active = 0; - - if (device->discov_requestor) { - g_dbus_remove_watch(req->conn, device->discov_listener); - device->discov_listener = 0; - g_free(device->discov_requestor); - device->discov_requestor = NULL; - } - if (err < 0) goto proceed; @@ -1352,24 +1343,8 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) next = seq->next; } - /* Store the device's profiles in the filesystem */ str2ba(adapter->address, &src); str2ba(device->address, &dst); - if (device->uuids) { - gchar *str = bt_list2string(device->uuids); - write_device_profiles(&src, &dst, str); - g_free(str); - } else - write_device_profiles(&src, &dst, ""); - - uuids = g_new0(char *, g_slist_length(device->uuids) + 1); - for (i = 0, l = device->uuids; l; l = l->next, i++) - uuids[i] = l->data; - - dbus_connection_emit_property_changed(req->conn, device->path, - DEVICE_INTERFACE, "UUIDs", - DBUS_TYPE_ARRAY, &uuids); - g_free(uuids); /* Public browsing successful or Single record requested */ if (req->browse == FALSE || (!req->search_uuid && recs)) @@ -1382,6 +1357,26 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) } probe: + /* Store the device's profiles in the filesystem */ + if (device->uuids) { + gchar *str = bt_list2string(device->uuids); + write_device_profiles(&src, &dst, str); + g_free(str); + + uuids = g_new0(char *, g_slist_length(device->uuids) + 1); + for (i = 0, l = device->uuids; l; l = l->next, i++) + uuids[i] = l->data; + + dbus_connection_emit_property_changed(req->conn, device->path, + DEVICE_INTERFACE, "UUIDs", + DBUS_TYPE_ARRAY, &uuids); + + g_free(uuids); + + } else + write_device_profiles(&src, &dst, ""); + + /* Probe matching drivers */ device_probe_drivers(device); proceed: @@ -1444,6 +1439,15 @@ proceed: dbus_message_unref(reply); fail: + device->discov_active = 0; + + if (device->discov_requestor) { + g_dbus_remove_watch(req->conn, device->discov_listener); + device->discov_listener = 0; + g_free(device->discov_requestor); + device->discov_requestor = NULL; + } + if (recs != NULL) sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); -- cgit From dde6ea8284f922181318ee84fd58144e06ee39b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Jun 2008 15:58:32 +0000 Subject: Fix driver comparison --- hcid/device.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 7049a223..6736bb54 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1252,6 +1252,13 @@ gint device_address_cmp(struct device *device, const gchar *address) return strcasecmp(device->address, address); } +static int cmp_by_name(const void *data, const void *user_data) +{ + const struct btd_device_driver *dev_driver = data, *driver = user_data; + + return (strcmp(dev_driver->name, driver->name)); +} + void device_probe_drivers(struct device *device) { GSList *list; @@ -1274,7 +1281,8 @@ void device_probe_drivers(struct device *device) } if (do_probe == TRUE && !g_slist_find_custom(device->drivers, - driver, (GCompareFunc) strcmp)) { + driver, (GCompareFunc) cmp_by_name)) { + err = driver->probe(&device->dev); if (err < 0) { error("probe failed for driver %s", -- cgit From 95e5960735be4066d43f77d91ebe78771cd76a43 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 18 Jun 2008 22:28:07 +0000 Subject: Make RemoveDevice to return when the device is busy discovering services. --- hcid/device.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 6736bb54..c0e64564 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1071,14 +1071,6 @@ static DBusMessage *discover_services(DBusConnection *conn, goto fail; } - device->discov_active = 1; - device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); - /* track the request owner to cancel it automatically if the owner - * exits */ - device->discov_listener = g_dbus_add_disconnect_watch(conn, - dbus_message_get_sender(msg), - discover_services_req_exit, - device, NULL); return NULL; fail: @@ -1489,6 +1481,15 @@ int device_browse(struct device *device, DBusConnection *conn, req->browse = TRUE; } + device->discov_active = 1; + device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); + /* track the request owner to cancel it automatically if the owner + * exits */ + device->discov_listener = g_dbus_add_disconnect_watch(conn, + dbus_message_get_sender(msg), + discover_services_req_exit, + device, NULL); + return bt_search_service(&src, &dst, &uuid, browse_cb, req, NULL); } -- cgit From 1e8fbfbfa6fbcf88a668f77e5601bbc505eb483f Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 25 Jun 2008 19:38:03 +0000 Subject: Cleanup device_browse code. --- hcid/device.c | 100 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 48 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index c0e64564..8ef46aad 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -75,7 +75,6 @@ struct browse_req { DBusMessage *msg; struct device *device; int search_uuid; - gboolean update; gboolean browse; }; @@ -1057,7 +1056,7 @@ static DBusMessage *discover_services(DBusConnection *conn, goto fail; if (strlen(pattern) == 0) { - err = device_browse(device, conn, msg, TRUE, 0); + err = device_browse(device, conn, msg, 0); if (err < 0) goto fail; } else { @@ -1066,7 +1065,7 @@ static DBusMessage *discover_services(DBusConnection *conn, if (!search) return invalid_args(msg); - err = device_browse(device, conn, msg, TRUE, search); + err = device_browse(device, conn, msg, search); if (err < 0) goto fail; } @@ -1303,6 +1302,48 @@ static void iter_append_record(DBusMessageIter *dict, uint32_t handle, dbus_message_iter_close_container(dict, &entry); } +static void discover_device_reply(struct browse_req *req, sdp_list_t *recs) +{ + DBusMessage *reply; + DBusMessageIter iter, dict; + sdp_list_t *seq; + + reply = dbus_message_new_method_return(req->msg); + if (!reply) + return; + + dbus_message_iter_init_append(reply, &iter); + + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); + + for (seq = recs; seq; seq = seq->next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + sdp_buf_t result; + + if (!rec) + break; + + memset(&result, 0, sizeof(sdp_buf_t)); + + convert_sdp_record_to_xml(rec, &result, + append_and_grow_string); + + if (result.data) { + const char *val = (char *) result.data; + iter_append_record(&dict, rec->handle, val); + free(result.data); + } + } + + dbus_message_iter_close_container(&iter, &dict); + + dbus_connection_send(req->conn, reply, NULL); + dbus_message_unref(reply); +} + static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) { sdp_list_t *seq, *next, *svcclass; @@ -1313,8 +1354,8 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) char **uuids; int i; GSList *l; - DBusMessage *reply; uuid_t uuid; + DBusMessage *reply; if (err < 0) goto proceed; @@ -1380,46 +1421,10 @@ probe: device_probe_drivers(device); proceed: - if (req->update == TRUE) { - DBusMessageIter iter, dict; - - reply = dbus_message_new_method_return(req->msg); - if (!reply) - goto fail; - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING - DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - - for (seq = recs; seq; seq = next) { - sdp_record_t *rec = (sdp_record_t *) seq->data; - sdp_buf_t result; - - if (!rec) - break; - - memset(&result, 0, sizeof(sdp_buf_t)); - - convert_sdp_record_to_xml(rec, &result, - append_and_grow_string); - - if (result.data) { - const char *val = (char *) result.data; - iter_append_record(&dict, rec->handle, val); - free(result.data); - } - - next = seq->next; - } - - dbus_message_iter_close_container(&iter, &dict); - - dbus_connection_send(req->conn, reply, NULL); - dbus_message_unref(reply); - goto fail; + if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, + "DiscoverServices")) { + discover_device_reply(req, recs); + goto cleanup; } g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg), @@ -1430,7 +1435,7 @@ proceed: /* Reply create device request */ reply = dbus_message_new_method_return(req->msg); if (!reply) - goto fail; + goto cleanup; dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, DBUS_TYPE_INVALID); @@ -1438,7 +1443,7 @@ proceed: dbus_connection_send(req->conn, reply, NULL); dbus_message_unref(reply); -fail: +cleanup: device->discov_active = 0; if (device->discov_requestor) { @@ -1457,7 +1462,7 @@ fail: } int device_browse(struct device *device, DBusConnection *conn, - DBusMessage *msg, gboolean update, uint16_t search) + DBusMessage *msg, uint16_t search) { struct adapter *adapter = device->adapter; struct browse_req *req; @@ -1468,7 +1473,6 @@ int device_browse(struct device *device, DBusConnection *conn, req->conn = dbus_connection_ref(conn); req->msg = dbus_message_ref(msg); req->device = device; - req->update = update; str2ba(adapter->address, &src); str2ba(device->address, &dst); -- cgit From 36dedff329b5ced8979a2161075e6a9d38c58785 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 26 Jun 2008 14:44:01 +0000 Subject: Fix probing and removing drivers when discovering services. --- hcid/device.c | 174 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 128 insertions(+), 46 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 8ef46aad..43ccd4e8 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -74,6 +74,8 @@ struct browse_req { DBusConnection *conn; DBusMessage *msg; struct device *device; + GSList *uuids_added; + GSList *uuids_removed; int search_uuid; gboolean browse; }; @@ -1184,7 +1186,7 @@ static GDBusSignalTable device_signals[] = { }; struct device *device_create(DBusConnection *conn, struct adapter *adapter, - const gchar *address, GSList *uuids) + const gchar *address) { gchar *address_up; struct device *device; @@ -1210,7 +1212,6 @@ struct device *device_create(DBusConnection *conn, struct adapter *adapter, device->address = g_strdup(address); device->adapter = adapter; - device->uuids = uuids; device->dev.path = device->path; str2ba(device->address, &device->dev.dst); @@ -1250,7 +1251,7 @@ static int cmp_by_name(const void *data, const void *user_data) return (strcmp(dev_driver->name, driver->name)); } -void device_probe_drivers(struct device *device) +void device_probe_drivers(struct device *device, GSList *uuids) { GSList *list; const char **uuid; @@ -1263,8 +1264,8 @@ void device_probe_drivers(struct device *device) gboolean do_probe = FALSE; for (uuid = driver->uuids; *uuid; uuid++) { - GSList *match = g_slist_find_custom(device->uuids, - *uuid, (GCompareFunc) strcasecmp); + GSList *match = g_slist_find_custom(uuids, *uuid, + (GCompareFunc) strcasecmp); if (match) { do_probe = TRUE; break; @@ -1285,6 +1286,37 @@ void device_probe_drivers(struct device *device) driver); } } + + for (list = uuids; list; list = list->next) + device->uuids = g_slist_insert_sorted(device->uuids, + list->data, (GCompareFunc) strcmp); +} + +void device_remove_drivers(struct device *device, GSList *uuids) +{ + GSList *list; + + debug("Remove drivers for %s", device->path); + + for (list = device->drivers; list; list = list->next) { + struct btd_device_driver *driver = list->data; + const char **uuid; + + for (uuid = driver->uuids; *uuid; uuid++) { + GSList *match = g_slist_find_custom(uuids, *uuid, + (GCompareFunc) strcasecmp); + + if (!match) + continue; + + driver->remove(&device->dev); + device->drivers = g_slist_remove(device->drivers, + driver); + } + } + + for (list = uuids; list; list = list->next) + device->uuids = g_slist_remove(device->uuids, list->data); } static void iter_append_record(DBusMessageIter *dict, uint32_t handle, @@ -1344,81 +1376,124 @@ static void discover_device_reply(struct browse_req *req, sdp_list_t *recs) dbus_message_unref(reply); } -static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) +static void services_changed(struct browse_req *req) { - sdp_list_t *seq, *next, *svcclass; - struct browse_req *req = user_data; struct device *device = req->device; - struct adapter *adapter = device->adapter; - bdaddr_t src, dst; char **uuids; - int i; GSList *l; - uuid_t uuid; - DBusMessage *reply; + int i; - if (err < 0) - goto proceed; + uuids = g_new0(char *, g_slist_length(device->uuids) + 1); + for (i = 0, l = device->uuids; l; l = l->next, i++) + uuids[i] = l->data; + + dbus_connection_emit_property_changed(req->conn, device->path, + DEVICE_INTERFACE, "UUIDs", + DBUS_TYPE_ARRAY, &uuids); + + g_free(uuids); +} + +static void update_services(struct browse_req *req, sdp_list_t *recs) +{ + struct device *device = req->device; + sdp_list_t *seq; - for (seq = recs; seq; seq = next) { + for (seq = recs; seq; seq = seq->next) { sdp_record_t *rec = (sdp_record_t *) seq->data; + sdp_list_t *svcclass = NULL; + gchar *uuid_str; + GSList *l; if (!rec) break; - svcclass = NULL; - if (sdp_get_service_classes(rec, &svcclass) == 0) { - /* Extract the first element and skip the remainning */ - gchar *uuid_str = bt_uuid2string(svcclass->data); - if (uuid_str) { - if (!g_slist_find_custom(device->uuids, uuid_str, - (GCompareFunc) strcmp)) - device->uuids = g_slist_insert_sorted(device->uuids, - uuid_str, (GCompareFunc) strcmp); - else - g_free(uuid_str); - } - sdp_list_free(svcclass, free); + if (sdp_get_service_classes(rec, &svcclass) < 0) + continue; + + /* Extract the first element and skip the remainning */ + uuid_str = bt_uuid2string(svcclass->data); + if (!uuid_str) + continue; + + l = g_slist_find_custom(device->uuids, uuid_str, + (GCompareFunc) strcmp); + if (!l) + req->uuids_added = g_slist_append(req->uuids_added, + uuid_str); + else { + req->uuids_removed = g_slist_remove(req->uuids_removed, + l->data); + g_free(uuid_str); } - next = seq->next; + sdp_list_free(svcclass, free); } +} + +static void store(struct device *device) +{ + struct adapter *adapter = device->adapter; + bdaddr_t src, dst; + char *str; str2ba(adapter->address, &src); str2ba(device->address, &dst); + if (!device->uuids) { + write_device_profiles(&src, &dst, ""); + return; + } + + str = bt_list2string(device->uuids); + write_device_profiles(&src, &dst, str); + g_free(str); +} + +static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) +{ + struct browse_req *req = user_data; + struct device *device = req->device; + struct adapter *adapter = device->adapter; + bdaddr_t src, dst; + uuid_t uuid; + DBusMessage *reply; + + if (err < 0) + goto proceed; + + update_services(req, recs); + /* Public browsing successful or Single record requested */ if (req->browse == FALSE || (!req->search_uuid && recs)) goto probe; if (uuid_list[++req->search_uuid]) { sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]); + str2ba(adapter->address, &src); + str2ba(device->address, &dst); bt_search_service(&src, &dst, &uuid, browse_cb, user_data, NULL); return; } probe: - /* Store the device's profiles in the filesystem */ - if (device->uuids) { - gchar *str = bt_list2string(device->uuids); - write_device_profiles(&src, &dst, str); - g_free(str); - uuids = g_new0(char *, g_slist_length(device->uuids) + 1); - for (i = 0, l = device->uuids; l; l = l->next, i++) - uuids[i] = l->data; + if (!req->uuids_added && !req->uuids_removed) + goto proceed; - dbus_connection_emit_property_changed(req->conn, device->path, - DEVICE_INTERFACE, "UUIDs", - DBUS_TYPE_ARRAY, &uuids); + /* Probe matching drivers for services added */ + if (req->uuids_added) + device_probe_drivers(device, req->uuids_added); - g_free(uuids); + /* Remove drivers for services removed */ + if (req->uuids_removed) + device_remove_drivers(device, req->uuids_removed); - } else - write_device_profiles(&src, &dst, ""); + /* Store the device's profiles in the filesystem */ + store(device); - /* Probe matching drivers */ - device_probe_drivers(device); + /* Propagate services changes */ + services_changed(req); proceed: if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, @@ -1458,6 +1533,8 @@ cleanup: dbus_message_unref(req->msg); dbus_connection_unref(req->conn); + g_slist_free(req->uuids_added); + g_slist_free(req->uuids_removed); g_free(req); } @@ -1468,12 +1545,17 @@ int device_browse(struct device *device, DBusConnection *conn, struct browse_req *req; bdaddr_t src, dst; uuid_t uuid; + GSList *l; req = g_new0(struct browse_req, 1); req->conn = dbus_connection_ref(conn); req->msg = dbus_message_ref(msg); req->device = device; + for (l = device->uuids; l; l = l->next) + req->uuids_removed = g_slist_append(req->uuids_removed, + l->data); + str2ba(adapter->address, &src); str2ba(device->address, &dst); -- cgit From 3005856580174bb25cd0510115bed9499b1f1bdc Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 30 Jun 2008 14:05:38 +0000 Subject: Accept friendly names for discover services --- hcid/device.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 43ccd4e8..706dcc1d 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1062,8 +1062,7 @@ static DBusMessage *discover_services(DBusConnection *conn, if (err < 0) goto fail; } else { - - search = sdp_str2svclass(pattern); + search = bt_string2class(pattern); if (!search) return invalid_args(msg); -- cgit From 040728e5019fce4eba5790939329fae0aa9104ff Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 30 Jun 2008 17:26:18 +0000 Subject: Added uuid128 support for device DiscoverServices --- hcid/device.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index 706dcc1d..f94c610c 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1058,15 +1058,16 @@ static DBusMessage *discover_services(DBusConnection *conn, goto fail; if (strlen(pattern) == 0) { - err = device_browse(device, conn, msg, 0); + err = device_browse(device, conn, msg, NULL); if (err < 0) goto fail; } else { - search = bt_string2class(pattern); - if (!search) + uuid_t uuid; + + if (bt_string2uuid(&uuid, pattern) < 0) return invalid_args(msg); - err = device_browse(device, conn, msg, search); + err = device_browse(device, conn, msg, &uuid); if (err < 0) goto fail; } @@ -1538,7 +1539,7 @@ cleanup: } int device_browse(struct device *device, DBusConnection *conn, - DBusMessage *msg, uint16_t search) + DBusMessage *msg, uuid_t *search) { struct adapter *adapter = device->adapter; struct browse_req *req; @@ -1559,7 +1560,7 @@ int device_browse(struct device *device, DBusConnection *conn, str2ba(device->address, &dst); if (search) { - sdp_uuid16_create(&uuid, search); + memcpy(&uuid, search, sizeof(uuid_t)); req->browse = FALSE; } else { sdp_uuid16_create(&uuid, uuid_list[req->search_uuid]); @@ -1568,8 +1569,8 @@ int device_browse(struct device *device, DBusConnection *conn, device->discov_active = 1; device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); - /* track the request owner to cancel it automatically if the owner - * exits */ + /* Track the request owner to cancel it + * automatically if the owner exits */ device->discov_listener = g_dbus_add_disconnect_watch(conn, dbus_message_get_sender(msg), discover_services_req_exit, -- cgit From 3e69851dcae4862a296b563f887ed99faff5f286 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 30 Jun 2008 17:28:43 +0000 Subject: Removed unused variable --- hcid/device.c | 1 - 1 file changed, 1 deletion(-) (limited to 'hcid/device.c') diff --git a/hcid/device.c b/hcid/device.c index f94c610c..66ab2dd7 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1046,7 +1046,6 @@ static DBusMessage *discover_services(DBusConnection *conn, { struct device *device = user_data; const char *pattern; - uint16_t search; int err; if (device->discov_active) -- cgit