summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2006-06-07 14:54:00 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2006-06-07 14:54:00 +0000
commit43ebdb300ce2bf9051d777311eb22e4e57d496c9 (patch)
tree8edce1ddd5caba883ce73034b47c955953daa061
parent253d30d4f95eb6d896531a5bfb570e7d1bb1ca0c (diff)
Removed extra DiscoveryCompleted signal on GetRemoteName deferred
-rw-r--r--hcid/dbus-adapter.c10
-rw-r--r--hcid/dbus.c176
-rw-r--r--hcid/dbus.h10
3 files changed, 100 insertions, 96 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index a5f7147c..62280f24 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -1248,16 +1248,14 @@ static DBusHandlerResult handle_dev_get_remote_name_req(DBusConnection *conn, DB
/* put the request name in the queue to resolve name */
str2ba(peer_addr, &peer_bdaddr);
- disc_device_append(&dbus_data->disc_devices, &peer_bdaddr, NAME_PENDING);
+ disc_device_append(&dbus_data->disc_devices, &peer_bdaddr, NAME_PENDING, RESOLVE_NAME);
/*
* if there is a discover process running, just queue the request.
* Otherwise, send the HCI cmd to get the remote name
*/
- if (dbus_data->discover_state == STATE_IDLE) {
- if (!disc_device_req_name(dbus_data))
- dbus_data->discover_state = STATE_RESOLVING_NAMES;
- }
+ if (dbus_data->discover_state == STATE_IDLE)
+ disc_device_req_name(dbus_data);
return error_request_deferred(conn, msg);
}
@@ -2070,7 +2068,7 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D
if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0)
dbus_data->discover_type = WITHOUT_NAME_RESOLVING;
else
- dbus_data->discover_type = RESOLVE_NAMES;
+ dbus_data->discover_type = RESOLVE_NAME;
dbus_data->requestor_name = strdup(dbus_message_get_sender(msg));
diff --git a/hcid/dbus.c b/hcid/dbus.c
index e57cccbd..93bf23fa 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -91,47 +91,58 @@ static void active_conn_info_free(void *data, void *user_data)
free(dev);
}
-static int disc_device_find_by_bdaddr(const void *data, const void *user_data)
+static int disc_device_find(const struct discovered_dev_info *d1, const struct discovered_dev_info *d2)
{
- const struct discovered_dev_info *dev = data;
- const bdaddr_t *bdaddr = user_data;
+ int ret;
- return bacmp(&dev->bdaddr, bdaddr);
-}
+ if (bacmp(&d2->bdaddr, BDADDR_ANY)) {
+ ret = bacmp(&d1->bdaddr, &d2->bdaddr);
+ if (ret)
+ return ret;
+ }
-static int disc_device_find_by_name_status(const void *data, const void *user_data)
-{
- const struct discovered_dev_info *dev = data;
- const name_status_t *name_status = user_data;
+ /* if not any */
+ if (d2->name_status) {
+ ret = (d1->name_status - d2->name_status);
+ if (ret)
+ return ret;
+ }
- if (dev->name_status == *name_status)
- return 0;
+ if (d2->discover_type)
+ return (d1->discover_type - d2->discover_type);
- return -1;
+ return 0;
}
-int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status)
+int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status, int discover_type)
{
- struct discovered_dev_info *dev = NULL;
+ struct discovered_dev_info *dev = NULL, match;
struct slist *l;
- /* ignore repeated entries */
- l = slist_find(*list, bdaddr, disc_device_find_by_bdaddr);
+ memset(&match, 0, sizeof(struct discovered_dev_info));
+ bacpy(&match.bdaddr, bdaddr);
+ match.name_status = NAME_ANY;
+ /* ignore repeated entries */
+ l = slist_find(*list, &match, (cmp_func_t)disc_device_find);
if (l) {
/* device found, update the attributes */
dev = l->data;
dev->name_status = name_status;
- return -1;
+ /* get remote name received while discovering */
+ if (dev->discover_type != RESOLVE_NAME)
+ dev->discover_type = discover_type;
+ return -EALREADY;
}
dev = malloc(sizeof(*dev));
if (!dev)
- return -1;
+ return -ENOMEM;
memset(dev, 0, sizeof(*dev));
bacpy(&dev->bdaddr, bdaddr);
dev->name_status = name_status;
+ dev->discover_type = discover_type;
*list = slist_append(*list, dev);
@@ -140,11 +151,14 @@ int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name
static int disc_device_remove(struct slist **list, bdaddr_t *bdaddr)
{
- struct discovered_dev_info *dev;
+ struct discovered_dev_info *dev, match;
struct slist *l;
int ret_val = -1;
- l = slist_find(*list, bdaddr, disc_device_find_by_bdaddr);
+ memset(&match, 0, sizeof(struct discovered_dev_info));
+ bacpy(&match.bdaddr, bdaddr);
+
+ l = slist_find(*list, &match, (cmp_func_t)disc_device_find);
if (l) {
dev = l->data;
@@ -341,6 +355,7 @@ static int register_dbus_path(const char *path, uint16_t dev_id,
data->dev_id = dev_id;
data->mode = SCAN_DISABLED;
data->discoverable_timeout = get_discoverable_timeout(dev_id);
+ data->discover_type = WITHOUT_NAME_RESOLVING; /* default discover type */
if (fallback) {
if (!dbus_connection_register_fallback(connection, path, pvtable, data)) {
@@ -751,29 +766,32 @@ int disc_device_req_name(struct hci_dbus_data *dbus_data)
evt_cmd_status rp;
remote_name_req_cp cp;
bdaddr_t tmp;
- struct discovered_dev_info *dev;
+ struct discovered_dev_info *dev, match;
DBusMessage *message = NULL;
struct slist *l = NULL;
char *peer_addr = NULL;
- int dd, req_sent, ret_val = 0;
- name_status_t name_status = NAME_PENDING;
+ int dd, req_sent, ret_val = -ENODATA;
- /*get the next remote address */
+ /* get the next remote address */
if (!dbus_data->disc_devices)
- return -1;
+ return ret_val;
- l = slist_find(dbus_data->disc_devices, &name_status, disc_device_find_by_name_status);
+ memset(&match, 0, sizeof(struct discovered_dev_info));
+ bacpy(&match.bdaddr, BDADDR_ANY);
+ match.name_status = NAME_PENDING;
+ match.discover_type = RESOLVE_NAME;
+ l = slist_find(dbus_data->disc_devices, &match, (cmp_func_t)disc_device_find);
if (!l)
- return -1;
+ return ret_val;
dev = l->data;
if (!dev)
- return -1;
+ return ret_val;
dd = hci_open_dev(dbus_data->dev_id);
if (dd < 0)
- return -1;
+ return -errno;
memset(&rq, 0, sizeof(rq));
rq.ogf = OGF_LINK_CTL;
@@ -822,18 +840,18 @@ int disc_device_req_name(struct hci_dbus_data *dbus_data)
free(dev);
/* get the next element */
- l = slist_find(dbus_data->disc_devices, &name_status, disc_device_find_by_name_status);
+ l = slist_find(dbus_data->disc_devices, &match, (cmp_func_t)disc_device_find);
- if (!l) {
- /* no more devices: exit */
- ret_val = -1;
+ /* no more devices: exit */
+ if (!l)
goto failed;
- }
dev = l->data;
}
} while (!req_sent);
+ ret_val = 0;
+
failed:
hci_close_dev(dd);
@@ -859,44 +877,37 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);
- if (dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) {
-
- if (pdata->discover_type == RESOLVE_NAMES) {
- if (!disc_device_req_name(pdata)) {
- pdata->discover_state = STATE_RESOLVING_NAMES;
- goto failed; /* skip - there is name to resolve */
- }
- }
- pdata->discover_state = STATE_IDLE;
+ if (!dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) {
+ error("Getting %s path data failed!", path);
+ goto failed;
+ }
- /* free discovered devices list */
- slist_foreach(pdata->disc_devices, disc_device_info_free, NULL);
- slist_free(pdata->disc_devices);
- pdata->disc_devices = NULL;
+ /* reset the discover type to be able to handle D-Bus and non D-Bus requests */
+ pdata->discover_type = WITHOUT_NAME_RESOLVING;
- if (pdata->requestor_name) {
- free(pdata->requestor_name);
- pdata->requestor_name = NULL;
- }
+ if (!disc_device_req_name(pdata)) {
+ pdata->discover_state = STATE_RESOLVING_NAMES;
+ goto failed; /* skip - there is name to resolve */
}
- message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
- "DiscoveryCompleted");
- if (message == NULL) {
- error("Can't allocate D-Bus message");
- goto failed;
- }
+ pdata->discover_state = STATE_IDLE;
- if (dbus_connection_send(connection, message, NULL) == FALSE) {
- error("Can't send D-Bus inquiry complete message");
- goto failed;
+ /* free discovered devices list */
+ slist_foreach(pdata->disc_devices, disc_device_info_free, NULL);
+ slist_free(pdata->disc_devices);
+ pdata->disc_devices = NULL;
+
+ if (pdata->requestor_name) {
+ free(pdata->requestor_name);
+ pdata->requestor_name = NULL;
}
- dbus_connection_flush(connection);
+ /* Send discovery completed signal if there isn't name to resolve */
+ message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
+ "DiscoveryCompleted");
+ send_reply_and_unref(connection, message);
failed:
- if (message)
- dbus_message_unref(message);
bt_free(local_addr);
}
@@ -915,7 +926,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
char path[MAX_PATH_LENGTH];
struct hci_dbus_data *pdata = NULL;
struct slist *l = NULL;
- struct discovered_dev_info *dev;
+ struct discovered_dev_info match;
char *local_addr, *peer_addr, *name = NULL;
const char *major_ptr, *minor_ptr;
struct slist *service_classes;
@@ -971,23 +982,18 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
slist_free(service_classes);
- if (dbus_connection_send(connection, signal_device, NULL) == FALSE) {
- error("Can't send D-Bus remote device found signal");
- goto failed;
- }
+ send_reply_and_unref(connection, signal_device);
- /* send the remote name signal */
- l = slist_find(pdata->disc_devices, peer, disc_device_find_by_bdaddr);
-
- if (l) {
- dev = l->data;
- if (dev->name_status == NAME_SENT)
- goto failed; /* don't sent the name again */
- }
+ memset(&match, 0, sizeof(struct discovered_dev_info));
+ bacpy(&match.bdaddr, peer);
+ match.name_status = NAME_SENT;
+ /* if found: don't sent the name again */
+ l = slist_find(pdata->disc_devices, &match, (cmp_func_t)disc_device_find);
+ if (l)
+ goto failed;
snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, local_addr);
name = textfile_get(filename, peer_addr);
-
if (name) {
signal_name = dev_signal_factory(pdata->dev_id, "RemoteNameUpdated",
DBUS_TYPE_STRING, &peer_addr,
@@ -998,17 +1004,11 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
free(name);
name_status = NAME_SENT;
}
- /* queue only results triggered by D-Bus clients */
- if (pdata->requestor_name)
- disc_device_append(&pdata->disc_devices, peer, name_status);
-
- disc_device_append(&pdata->disc_devices, peer, name_status);
+ /* add in the list to track name sent/pending */
+ disc_device_append(&pdata->disc_devices, peer, name_status, pdata->discover_type);
failed:
- if (signal_device)
- dbus_message_unref(signal_device);
-
bt_free(local_addr);
bt_free(peer_addr);
}
@@ -1059,7 +1059,11 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char
slist_free(pdata->disc_devices);
pdata->disc_devices = NULL;
- if (pdata->discover_state == STATE_RESOLVING_NAMES ) {
+ /*
+ * The discovery completed signal must be sent only for discover
+ * devices request WITH name resolving
+ */
+ if (pdata->discover_state == STATE_RESOLVING_NAMES) {
message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
"DiscoveryCompleted");
diff --git a/hcid/dbus.h b/hcid/dbus.h
index cff5b7ee..69952bfc 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -63,13 +63,14 @@ typedef enum {
STATE_IDLE,
STATE_DISCOVER,
STATE_RESOLVING_NAMES
-}discover_state_t;
+} discover_state_t;
/* discover type */
-#define WITHOUT_NAME_RESOLVING 0
-#define RESOLVE_NAMES 1
+#define WITHOUT_NAME_RESOLVING 1 /* D-Bus and non D-Bus request */
+#define RESOLVE_NAME 2
typedef enum {
+ NAME_ANY,
NAME_PENDING,
NAME_SENT
} name_status_t;
@@ -77,6 +78,7 @@ typedef enum {
struct discovered_dev_info {
bdaddr_t bdaddr;
name_status_t name_status;
+ int discover_type;
};
struct bonding_request_info {
@@ -190,7 +192,7 @@ static inline DBusHandlerResult send_reply_and_unref(DBusConnection *conn, DBusM
int active_conn_find_by_bdaddr(const void *data, const void *user_data);
void bonding_request_free(struct bonding_request_info *dev);
void disc_device_info_free(void *data, void *user_data);
-int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status);
+int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status, int discover_type);
int disc_device_req_name(struct hci_dbus_data *dbus_data);
int discoverable_timeout_handler(void *data);