diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-08-29 23:51:09 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-08-29 23:51:09 +0200 |
commit | 2e2f9a82505b962d20db8cbded2752a27537c566 (patch) | |
tree | 8ab6cb9ecf4cfcf6a174527112f3d4da7b8fbf79 /src/adapter.c | |
parent | 41708dccb5d831adaf0862da9c1d7fe3c197db3c (diff) | |
parent | 93750261a6093a8d987cd23327fd3d90467b5739 (diff) |
Merge branch 'for-upstream' of git://gitorious.org/bluez/aloks-clone
Diffstat (limited to 'src/adapter.c')
-rw-r--r-- | src/adapter.c | 166 |
1 files changed, 165 insertions, 1 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); |