summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-08-29 23:51:09 +0200
committerMarcel Holtmann <marcel@holtmann.org>2008-08-29 23:51:09 +0200
commit2e2f9a82505b962d20db8cbded2752a27537c566 (patch)
tree8ab6cb9ecf4cfcf6a174527112f3d4da7b8fbf79
parent41708dccb5d831adaf0862da9c1d7fe3c197db3c (diff)
parent93750261a6093a8d987cd23327fd3d90467b5739 (diff)
Merge branch 'for-upstream' of git://gitorious.org/bluez/aloks-clone
-rw-r--r--src/adapter.c166
-rw-r--r--src/adapter.h8
-rw-r--r--src/dbus-hci.c238
-rw-r--r--src/dbus-hci.h2
4 files changed, 196 insertions, 218 deletions
diff --git a/src/adapter.c b/src/adapter.c
index afd909ba..f52cc671 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -167,6 +167,40 @@ static DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn,
err > 0 ? strerror(err) : "Connection attempt failed");
}
+static void send_out_of_range(const char *path, GSList *l)
+{
+ while (l) {
+ const char *peer_addr = l->data;
+
+ g_dbus_emit_signal(connection, path,
+ ADAPTER_INTERFACE, "DeviceDisappeared",
+ DBUS_TYPE_STRING, &peer_addr,
+ DBUS_TYPE_INVALID);
+
+ l = l->next;
+ }
+}
+
+static int found_device_cmp(const struct remote_dev_info *d1,
+ const struct remote_dev_info *d2)
+{
+ int ret;
+
+ if (bacmp(&d2->bdaddr, BDADDR_ANY)) {
+ ret = bacmp(&d1->bdaddr, &d2->bdaddr);
+ if (ret)
+ return ret;
+ }
+
+ if (d2->name_status != NAME_ANY) {
+ ret = (d1->name_status - d2->name_status);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static int auth_req_cmp(const void *p1, const void *p2)
{
const struct pending_auth_info *pb1 = p1;
@@ -2483,7 +2517,6 @@ int adapter_stop(struct adapter *adapter)
adapter->up = 0;
adapter->scan_mode = SCAN_DISABLED;
adapter->mode = MODE_OFF;
- adapter->pinq_idle = 0;
adapter->state = DISCOVER_TYPE_NONE;
unload_drivers(adapter);
@@ -2731,6 +2764,21 @@ void adapter_set_state(struct adapter *adapter, int state)
if (!adapter)
return;
+ /* Both Standard and periodic Inquiry are in progress */
+ if ((state & STD_INQUIRY) && (state & PERIODIC_INQUIRY))
+ goto set;
+
+ if (!adapter->found_devices)
+ goto set;
+
+ /* Free list if standard/periodic inquiry is done */
+ if ((adapter->state & (STD_INQUIRY | PERIODIC_INQUIRY)) &&
+ (state & (~STD_INQUIRY | ~PERIODIC_INQUIRY))) {
+ g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
+ g_slist_free(adapter->found_devices);
+ adapter->found_devices = NULL;
+ }
+set:
adapter->state = state;
}
@@ -2739,6 +2787,122 @@ int adapter_get_state(struct adapter *adapter)
return adapter->state;
}
+struct remote_dev_info *adapter_search_found_devices(struct adapter *adapter,
+ struct remote_dev_info *match)
+{
+ GSList *l;
+
+ l = g_slist_find_custom(adapter->found_devices, match,
+ (GCompareFunc) found_device_cmp);
+ if (l)
+ return l->data;
+
+ return NULL;
+}
+
+int dev_rssi_cmp(struct remote_dev_info *d1, struct remote_dev_info *d2)
+{
+ int rssi1, rssi2;
+
+ rssi1 = d1->rssi < 0 ? -d1->rssi : d1->rssi;
+ rssi2 = d2->rssi < 0 ? -d2->rssi : d2->rssi;
+
+ return rssi1 - rssi2;
+}
+
+int adapter_add_found_device(struct adapter *adapter, bdaddr_t *bdaddr,
+ int8_t rssi, name_status_t name_status)
+{
+ struct remote_dev_info *dev, match;
+
+ memset(&match, 0, sizeof(struct remote_dev_info));
+ bacpy(&match.bdaddr, bdaddr);
+ match.name_status = NAME_ANY;
+
+ /* ignore repeated entries */
+ dev = adapter_search_found_devices(adapter, &match);
+ if (dev) {
+ /* device found, update the attributes */
+ if (rssi != 0)
+ dev->rssi = rssi;
+
+ /* Get remote name can be received while inquiring.
+ * Keep in mind that multiple inquiry result events can
+ * be received from the same remote device.
+ */
+ if (name_status != NAME_NOT_REQUIRED)
+ dev->name_status = name_status;
+
+ adapter->found_devices = g_slist_sort(adapter->found_devices,
+ (GCompareFunc) dev_rssi_cmp);
+
+ return -EALREADY;
+ }
+
+ dev = g_new0(struct remote_dev_info, 1);
+
+ bacpy(&dev->bdaddr, bdaddr);
+ dev->rssi = rssi;
+ dev->name_status = name_status;
+
+ adapter->found_devices = g_slist_insert_sorted(adapter->found_devices,
+ dev, (GCompareFunc) dev_rssi_cmp);
+
+ return 0;
+}
+
+int adapter_remove_found_device(struct adapter *adapter, bdaddr_t *bdaddr)
+{
+ struct remote_dev_info *dev, match;
+
+ memset(&match, 0, sizeof(struct remote_dev_info));
+ bacpy(&match.bdaddr, bdaddr);
+
+ dev = adapter_search_found_devices(adapter, &match);
+ if (!dev)
+ return -1;
+
+ adapter->found_devices = g_slist_remove(adapter->found_devices, dev);
+ g_free(dev);
+
+ return 0;
+}
+
+void adapter_update_oor_devices(struct adapter *adapter)
+{
+ GSList *l = adapter->found_devices;
+ struct remote_dev_info *dev;
+ bdaddr_t tmp;
+
+ send_out_of_range(adapter->path, adapter->oor_devices);
+
+ g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);
+ g_slist_free(adapter->oor_devices);
+ adapter->oor_devices = NULL;
+
+ while (l) {
+ dev = l->data;
+ baswap(&tmp, &dev->bdaddr);
+ adapter->oor_devices = g_slist_append(adapter->oor_devices,
+ batostr(&tmp));
+ l = l->next;
+ }
+}
+
+void adapter_remove_oor_device(struct adapter *adapter, char *peer_addr)
+{
+ GSList *l;
+
+ l = g_slist_find_custom(adapter->oor_devices, peer_addr,
+ (GCompareFunc) strcmp);
+ if (l) {
+ char *dev = l->data;
+ adapter->oor_devices = g_slist_remove(adapter->oor_devices,
+ dev);
+ g_free(dev);
+ }
+}
+
int btd_register_adapter_driver(struct btd_adapter_driver *driver)
{
adapter_drivers = g_slist_append(adapter_drivers, driver);
diff --git a/src/adapter.h b/src/adapter.h
index b39fcd03..e5432b66 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -102,7 +102,6 @@ struct adapter {
uint8_t scan_mode; /* scan mode: SCAN_DISABLED, SCAN_PAGE, SCAN_INQUIRY */
uint8_t mode; /* off, connectable, discoverable, limited */
uint8_t global_mode; /* last valid global mode */
- int pinq_idle; /* tracks the idle time for periodic inquiry */
int state; /* standard inq, periodic inq, name resloving */
GSList *found_devices;
GSList *oor_devices; /* out of range device list */
@@ -169,6 +168,13 @@ void adapter_set_mode(struct adapter *adapter, uint8_t mode);
uint8_t adapter_get_mode(struct adapter *adapter);
void adapter_set_state(struct adapter *adapter, int state);
int adapter_get_state(struct adapter *adapter);
+struct remote_dev_info *adapter_search_found_devices(struct adapter *adapter,
+ struct remote_dev_info *match);
+int adapter_add_found_device(struct adapter *adapter, bdaddr_t *bdaddr,
+ int8_t rssi, name_status_t name_status);
+int adapter_remove_found_device(struct adapter *adapter, bdaddr_t *bdaddr);
+void adapter_update_oor_devices(struct adapter *adapter);
+void adapter_remove_oor_device(struct adapter *adapter, char *peer_addr);
struct btd_adapter_driver {
const char *name;
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index e4c0f345..70b15062 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -91,97 +91,6 @@ void bonding_request_free(struct bonding_request_info *bonding)
g_free(bonding);
}
-int found_device_cmp(const struct remote_dev_info *d1,
- const struct remote_dev_info *d2)
-{
- int ret;
-
- if (bacmp(&d2->bdaddr, BDADDR_ANY)) {
- ret = bacmp(&d1->bdaddr, &d2->bdaddr);
- if (ret)
- return ret;
- }
-
- if (d2->name_status != NAME_ANY) {
- ret = (d1->name_status - d2->name_status);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-int dev_rssi_cmp(struct remote_dev_info *d1, struct remote_dev_info *d2)
-{
- int rssi1, rssi2;
-
- rssi1 = d1->rssi < 0 ? -d1->rssi : d1->rssi;
- rssi2 = d2->rssi < 0 ? -d2->rssi : d2->rssi;
-
- return rssi1 - rssi2;
-}
-
-static int found_device_add(GSList **list, bdaddr_t *bdaddr, int8_t rssi,
- name_status_t name_status)
-{
- struct remote_dev_info *dev, match;
- GSList *l;
-
- memset(&match, 0, sizeof(struct remote_dev_info));
- bacpy(&match.bdaddr, bdaddr);
- match.name_status = NAME_ANY;
-
- /* ignore repeated entries */
- l = g_slist_find_custom(*list, &match, (GCompareFunc) found_device_cmp);
- if (l) {
- /* device found, update the attributes */
- dev = l->data;
-
- if (rssi != 0)
- dev->rssi = rssi;
-
- /* Get remote name can be received while inquiring.
- * Keep in mind that multiple inquiry result events can
- * be received from the same remote device.
- */
- if (name_status != NAME_NOT_REQUIRED)
- dev->name_status = name_status;
-
- *list = g_slist_sort(*list, (GCompareFunc) dev_rssi_cmp);
-
- return -EALREADY;
- }
-
- dev = g_new0(struct remote_dev_info, 1);
-
- bacpy(&dev->bdaddr, bdaddr);
- dev->rssi = rssi;
- dev->name_status = name_status;
-
- *list = g_slist_insert_sorted(*list, dev, (GCompareFunc) dev_rssi_cmp);
-
- return 0;
-}
-
-static int found_device_remove(GSList **list, bdaddr_t *bdaddr)
-{
- struct remote_dev_info *dev, match;
- GSList *l;
-
- memset(&match, 0, sizeof(struct remote_dev_info));
- bacpy(&match.bdaddr, bdaddr);
-
- l = g_slist_find_custom(*list, &match, (GCompareFunc) found_device_cmp);
- if (!l)
- return -1;
-
- dev = l->data;
- *list = g_slist_remove(*list, dev);
- g_free(dev);
-
- return 0;
-}
-
int active_conn_find_by_bdaddr(const void *data, const void *user_data)
{
const struct active_conn_info *con = data;
@@ -845,22 +754,16 @@ static int found_device_req_name(struct adapter *adapter)
struct hci_request rq;
evt_cmd_status rp;
remote_name_req_cp cp;
- struct remote_dev_info match;
- GSList *l;
+ struct remote_dev_info *dev, match;
int dd, req_sent = 0;
uint16_t dev_id = adapter_get_dev_id(adapter);
- /* get the next remote address */
- if (!adapter->found_devices)
- return -ENODATA;
-
memset(&match, 0, sizeof(struct remote_dev_info));
bacpy(&match.bdaddr, BDADDR_ANY);
match.name_status = NAME_REQUIRED;
- l = g_slist_find_custom(adapter->found_devices, &match,
- (GCompareFunc) found_device_cmp);
- if (!l)
+ dev = adapter_search_found_devices(adapter, &match);
+ if (!dev)
return -ENODATA;
dd = hci_open_dev(dev_id);
@@ -878,9 +781,7 @@ static int found_device_req_name(struct adapter *adapter)
/* send at least one request or return failed if the list is empty */
do {
- struct remote_dev_info *dev = l->data;
-
- /* flag to indicate the current remote name requested */
+ /* flag to indicate the current remote name requested */
dev->name_status = NAME_REQUESTED;
memset(&rp, 0, sizeof(rp));
@@ -902,14 +803,11 @@ static int found_device_req_name(struct adapter *adapter)
/* if failed, request the next element */
/* remove the element from the list */
- adapter->found_devices = g_slist_remove(adapter->found_devices, dev);
- g_free(dev);
+ adapter_remove_found_device(adapter, &dev->bdaddr);
/* get the next element */
- l = g_slist_find_custom(adapter->found_devices, &match,
- (GCompareFunc) found_device_cmp);
-
- } while (l);
+ dev = adapter_search_found_devices(adapter, &match);
+ } while (dev);
hci_close_dev(dd);
@@ -919,25 +817,9 @@ static int found_device_req_name(struct adapter *adapter)
return 0;
}
-static void send_out_of_range(const char *path, GSList *l)
-{
- while (l) {
- const char *peer_addr = l->data;
-
- g_dbus_emit_signal(connection, path,
- ADAPTER_INTERFACE, "DeviceDisappeared",
- DBUS_TYPE_STRING, &peer_addr,
- DBUS_TYPE_INVALID);
-
- l = l->next;
- }
-}
-
void hcid_dbus_inquiry_complete(bdaddr_t *local)
{
struct adapter *adapter;
- struct remote_dev_info *dev;
- bdaddr_t tmp;
const gchar *path;
int state;
@@ -951,27 +833,8 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
/* Out of range verification */
if ((adapter_get_state(adapter) & PERIODIC_INQUIRY) &&
- !(adapter_get_state(adapter) & STD_INQUIRY)) {
- GSList *l;
-
- send_out_of_range(path, adapter->oor_devices);
-
- g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);
- g_slist_free(adapter->oor_devices);
- adapter->oor_devices = NULL;
-
- l = adapter->found_devices;
- while (l) {
- dev = l->data;
- baswap(&tmp, &dev->bdaddr);
- adapter->oor_devices = g_slist_append(adapter->oor_devices,
- batostr(&tmp));
- l = l->next;
- }
- }
-
- adapter->pinq_idle = 1;
-
+ !(adapter_get_state(adapter) & STD_INQUIRY))
+ adapter_update_oor_devices(adapter);
/*
* Enable resolution again: standard inquiry can be
* received in the periodic inquiry idle state.
@@ -1006,11 +869,6 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
adapter_set_state(adapter, state);
}
- /* free discovered devices list */
- g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
- g_slist_free(adapter->found_devices);
- adapter->found_devices = NULL;
-
if (adapter->discov_requestor) {
g_dbus_remove_watch(connection, adapter->discov_listener);
adapter->discov_listener = 0;
@@ -1094,11 +952,6 @@ void hcid_dbus_periodic_inquiry_exit(bdaddr_t *local, uint8_t status)
state &= ~(PERIODIC_INQUIRY | RESOLVE_NAME);
adapter_set_state(adapter, state);
- /* free discovered devices list */
- g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
- g_slist_free(adapter->found_devices);
- adapter->found_devices = NULL;
-
/* free out of range devices list */
g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);
g_slist_free(adapter->oor_devices);
@@ -1208,10 +1061,9 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
{
char filename[PATH_MAX + 1];
struct adapter *adapter;
- GSList *l;
char local_addr[18], peer_addr[18], *name, *tmp_name;
const char *paddr = peer_addr;
- struct remote_dev_info match;
+ struct remote_dev_info *dev, match;
dbus_int16_t tmp_rssi = rssi;
uint8_t name_type = 0x00;
name_status_t name_status;
@@ -1242,29 +1094,16 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
state |= PERIODIC_INQUIRY;
adapter_set_state(adapter, state);
}
-
- /* reset the idle flag when the inquiry complete event arrives */
- if (adapter_get_state(adapter) & PERIODIC_INQUIRY) {
- adapter->pinq_idle = 0;
-
/* Out of range list update */
- l = g_slist_find_custom(adapter->oor_devices, peer_addr,
- (GCompareFunc) strcmp);
- if (l) {
- char *dev = l->data;
- adapter->oor_devices = g_slist_remove(adapter->oor_devices,
- dev);
- g_free(dev);
- }
- }
+ if (adapter_get_state(adapter) & PERIODIC_INQUIRY)
+ adapter_remove_oor_device(adapter, peer_addr);
memset(&match, 0, sizeof(struct remote_dev_info));
bacpy(&match.bdaddr, peer);
match.name_status = NAME_SENT;
/* if found: don't send the name again */
- l = g_slist_find_custom(adapter->found_devices, &match,
- (GCompareFunc) found_device_cmp);
- if (l)
+ dev = adapter_search_found_devices(adapter, &match);
+ if (dev)
return;
/* the inquiry result can be triggered by NON D-Bus client */
@@ -1317,7 +1156,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
}
/* add in the list to track name sent/pending */
- found_device_add(&adapter->found_devices, peer, rssi, name_status);
+ adapter_add_found_device(adapter, peer, rssi, name_status);
}
void hcid_dbus_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class)
@@ -1390,17 +1229,12 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
}
/* remove from remote name request list */
- found_device_remove(&adapter->found_devices, peer);
+ adapter_remove_found_device(adapter, peer);
/* check if there is more devices to request names */
if (!found_device_req_name(adapter))
return; /* skip if a new request has been sent */
- /* free discovered devices list */
- g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
- g_slist_free(adapter->found_devices);
- adapter->found_devices = NULL;
-
/* The discovery completed signal must be sent only for discover
* devices request WITH name resolving */
if (adapter->discov_requestor) {
@@ -1942,7 +1776,6 @@ static int remote_name_cancel(int dd, bdaddr_t *dba, int to)
int cancel_discovery(struct adapter *adapter)
{
struct remote_dev_info *dev, match;
- GSList *l;
int dd, err = 0;
uint16_t dev_id = adapter_get_dev_id(adapter);
int state;
@@ -1964,10 +1797,8 @@ int cancel_discovery(struct adapter *adapter)
bacpy(&match.bdaddr, BDADDR_ANY);
match.name_status = NAME_REQUESTED;
- l = g_slist_find_custom(adapter->found_devices, &match,
- (GCompareFunc) found_device_cmp);
- if (l) {
- dev = l->data;
+ dev = adapter_search_found_devices(adapter, &match);
+ if (dev) {
if (remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {
error("Read remote name cancel failed: %s, (%d)",
strerror(errno), errno);
@@ -1984,14 +1815,6 @@ int cancel_discovery(struct adapter *adapter)
hci_close_dev(dd);
cleanup:
- /*
- * Reset discov_requestor and discover_state in the remote name
- * request event handler or in the inquiry complete handler.
- */
- g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
- g_slist_free(adapter->found_devices);
- adapter->found_devices = NULL;
-
/* Disable name resolution for non D-Bus clients */
if (!adapter->pdiscov_requestor) {
state = adapter_get_state(adapter);
@@ -2028,27 +1851,23 @@ static int periodic_inquiry_exit(int dd, int to)
int cancel_periodic_discovery(struct adapter *adapter)
{
struct remote_dev_info *dev, match;
- GSList *l;
int dd, err = 0;
uint16_t dev_id = adapter_get_dev_id(adapter);
if (!(adapter_get_state(adapter) & PERIODIC_INQUIRY))
- goto cleanup;
+ return err;
dd = hci_open_dev(dev_id);
- if (dd < 0) {
- err = -ENODEV;
- goto cleanup;
- }
+ if (dd < 0)
+ return -ENODEV;
+
/* find the pending remote name request */
memset(&match, 0, sizeof(struct remote_dev_info));
bacpy(&match.bdaddr, BDADDR_ANY);
match.name_status = NAME_REQUESTED;
- l = g_slist_find_custom(adapter->found_devices, &match,
- (GCompareFunc) found_device_cmp);
- if (l) {
- dev = l->data;
+ dev = adapter_search_found_devices(adapter, &match);
+ if (dev) {
if (remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {
error("Read remote name cancel failed: %s, (%d)",
strerror(errno), errno);
@@ -2066,15 +1885,6 @@ int cancel_periodic_discovery(struct adapter *adapter)
hci_close_dev(dd);
-cleanup:
- /*
- * Reset pdiscov_requestor and pdiscov_active is done when the
- * cmd complete event for exit periodic inquiry mode cmd arrives.
- */
- g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);
- g_slist_free(adapter->found_devices);
- adapter->found_devices = NULL;
-
return err;
}
diff --git a/src/dbus-hci.h b/src/dbus-hci.h
index 621657d0..72b22741 100644
--- a/src/dbus-hci.h
+++ b/src/dbus-hci.h
@@ -55,8 +55,6 @@ int cancel_periodic_discovery(struct adapter *adapter);
int active_conn_find_by_bdaddr(const void *data, const void *user_data);
void bonding_request_free(struct bonding_request_info *dev);
-int found_device_cmp(const struct remote_dev_info *d1,
- const struct remote_dev_info *d2);
int set_limited_discoverable(int dd, const uint8_t *cls, gboolean limited);
int set_service_classes(int dd, const uint8_t *cls, uint8_t value);