summaryrefslogtreecommitdiffstats
path: root/hcid
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2006-03-13 20:47:52 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2006-03-13 20:47:52 +0000
commit1fe7ab081842276d8db73a44cc64c2115b618cc2 (patch)
tree5fe2f882ea3f2cf0fe99737956d11aea65cac0c1 /hcid
parent5a7676dd838717f9ce483af8e9be0acf80f2960c (diff)
Added remote name resolving queue
Diffstat (limited to 'hcid')
-rw-r--r--hcid/dbus-adapter.c84
-rw-r--r--hcid/dbus.c182
-rw-r--r--hcid/dbus.h6
-rw-r--r--hcid/hcid.h4
-rw-r--r--hcid/security.c7
5 files changed, 217 insertions, 66 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index c535b788..33ef99eb 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -1165,6 +1165,7 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D
{
DBusMessage *reply = NULL;
const char *requestor_name;
+ const char *method;
inquiry_cp cp;
evt_cmd_status rp;
struct hci_request rq;
@@ -1176,6 +1177,12 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D
if (dbus_data->requestor_name)
return error_discover_in_progress(conn, msg);
+ method = dbus_message_get_member(msg);
+ if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0)
+ dbus_data->resolve_name = 0;
+ else
+ dbus_data->resolve_name = 1;
+
dd = hci_open_dev(dbus_data->dev_id);
if (dd < 0)
return error_no_such_adapter(conn, msg);
@@ -1265,45 +1272,46 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D
}
static struct service_data dev_services[] = {
- { "GetAddress", handle_dev_get_address_req, },
- { "GetVersion", handle_dev_get_version_req, },
- { "GetRevision", handle_dev_get_revision_req, },
- { "GetManufacturer", handle_dev_get_manufacturer_req, },
- { "GetCompany", handle_dev_get_company_req, },
- { "GetMode", handle_dev_get_mode_req, },
- { "SetMode", handle_dev_set_mode_req, },
- { "GetDiscoverableTimeout", handle_dev_get_discoverable_to_req, },
- { "SetDiscoverableTimeout", handle_dev_set_discoverable_to_req, },
- { "IsConnectable", handle_dev_is_connectable_req, },
- { "IsDiscoverable", handle_dev_is_discoverable_req, },
- { "GetMajorClass", handle_dev_get_major_class_req, },
- { "ListAvailableMinorClasses", handle_dev_list_minor_classes_req, },
- { "GetMinorClass", handle_dev_get_minor_class_req, },
- { "SetMinorClass", handle_dev_set_minor_class_req, },
- { "GetServicesClasses", handle_dev_get_service_classes_req, },
- { "GetName", handle_dev_get_name_req, },
- { "SetName", handle_dev_set_name_req, },
+ { "GetAddress", handle_dev_get_address_req, },
+ { "GetVersion", handle_dev_get_version_req, },
+ { "GetRevision", handle_dev_get_revision_req, },
+ { "GetManufacturer", handle_dev_get_manufacturer_req, },
+ { "GetCompany", handle_dev_get_company_req, },
+ { "GetMode", handle_dev_get_mode_req, },
+ { "SetMode", handle_dev_set_mode_req, },
+ { "GetDiscoverableTimeout", handle_dev_get_discoverable_to_req, },
+ { "SetDiscoverableTimeout", handle_dev_set_discoverable_to_req, },
+ { "IsConnectable", handle_dev_is_connectable_req, },
+ { "IsDiscoverable", handle_dev_is_discoverable_req, },
+ { "GetMajorClass", handle_dev_get_major_class_req, },
+ { "ListAvailableMinorClasses", handle_dev_list_minor_classes_req, },
+ { "GetMinorClass", handle_dev_get_minor_class_req, },
+ { "SetMinorClass", handle_dev_set_minor_class_req, },
+ { "GetServicesClasses", handle_dev_get_service_classes_req, },
+ { "GetName", handle_dev_get_name_req, },
+ { "SetName", handle_dev_set_name_req, },
- { "GetRemoteVersion", handle_dev_get_remote_version_req, },
- { "GetRemoteRevision", handle_dev_get_remote_revision_req, },
- { "GetRemoteManufacturer", handle_dev_get_remote_manufacturer_req, },
- { "GetRemoteCompany", handle_dev_get_remote_company_req, },
- { "GetRemoteName", handle_dev_get_remote_name_req, },
- { "GetRemoteAlias", handle_dev_get_remote_alias_req, },
- { "SetRemoteAlias", handle_dev_set_remote_alias_req, },
-
- { "LastSeen", handle_dev_last_seen_req, },
- { "LastUsed", handle_dev_last_used_req, },
-
- { "CreateBonding", handle_dev_create_bonding_req, },
- { "RemoveBonding", handle_dev_remove_bonding_req, },
- { "HasBonding", handle_dev_has_bonding_req, },
- { "ListBondings", handle_dev_list_bondings_req, },
- { "GetPinCodeLength", handle_dev_get_pin_code_length_req, },
- { "GetEncryptionKeySize", handle_dev_get_encryption_key_size_req, },
-
- { "DiscoverDevices", handle_dev_discover_devices_req, },
- { "CancelDiscovery", handle_dev_cancel_discovery_req, },
+ { "GetRemoteVersion", handle_dev_get_remote_version_req, },
+ { "GetRemoteRevision", handle_dev_get_remote_revision_req, },
+ { "GetRemoteManufacturer", handle_dev_get_remote_manufacturer_req, },
+ { "GetRemoteCompany", handle_dev_get_remote_company_req, },
+ { "GetRemoteName", handle_dev_get_remote_name_req, },
+ { "GetRemoteAlias", handle_dev_get_remote_alias_req, },
+ { "SetRemoteAlias", handle_dev_set_remote_alias_req, },
+
+ { "LastSeen", handle_dev_last_seen_req, },
+ { "LastUsed", handle_dev_last_used_req, },
+
+ { "CreateBonding", handle_dev_create_bonding_req, },
+ { "RemoveBonding", handle_dev_remove_bonding_req, },
+ { "HasBonding", handle_dev_has_bonding_req, },
+ { "ListBondings", handle_dev_list_bondings_req, },
+ { "GetPinCodeLength", handle_dev_get_pin_code_length_req, },
+ { "GetEncryptionKeySize", handle_dev_get_encryption_key_size_req, },
+
+ { "DiscoverDevices", handle_dev_discover_devices_req, },
+ { "DiscoverDevicesWithoutNameResolving", handle_dev_discover_devices_req },
+ { "CancelDiscovery", handle_dev_cancel_discovery_req, },
{ NULL, NULL }
};
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 988aa56c..4efc7457 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -45,6 +45,7 @@
#include "hcid.h"
#include "dbus.h"
#include "textfile.h"
+#include "list.h"
#ifndef DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT
#define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT 0x00
@@ -100,6 +101,57 @@ static const char *phone_minor_cls[] = {
"isdn"
};
+static bdaddr_t *remote_name_find(struct slist *list, bdaddr_t *addr)
+{
+ struct slist *current;
+
+ for (current = list; current != NULL; current = current->next) {
+ bdaddr_t *data = current->data;
+ if (memcmp(data, addr, sizeof(*addr)) == 0)
+ return data;
+ }
+
+ return NULL;
+}
+
+static int remote_name_add(struct slist **list, bdaddr_t *addr)
+{
+ bdaddr_t *data;
+
+ /* ignore repeated entries */
+ data = remote_name_find(*list, addr);
+
+ if (data)
+ return -1;
+
+ data = malloc(sizeof(bdaddr_t));
+ if (!data)
+ return -1;
+
+ data = malloc(sizeof(bdaddr_t));
+ memcpy(data, addr, sizeof(bdaddr_t));
+
+ *list = slist_append(*list, data);
+
+ return 0;
+}
+
+static int remote_name_remove(struct slist **list, bdaddr_t *addr)
+{
+ bdaddr_t *data;
+ int ret_val = -1;
+
+ data = remote_name_find(*list, addr);
+
+ if (data) {
+ *list = slist_remove(*list, data);
+ free(data);
+ ret_val = 0;
+ }
+
+ return ret_val;
+}
+
/*
* Timeout functions Protypes
*/
@@ -203,6 +255,7 @@ static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t
data->timeout_hits = 0;
data->timeout_handler = NULL;
data->requestor_name = NULL;
+ data->discovered_devices = NULL;
if (fallback) {
if (!dbus_connection_register_fallback(connection, path, pvtable, data)) {
@@ -472,6 +525,36 @@ failed:
bt_free(local_addr);
}
+static inline int remote_name_resolve(struct hci_dbus_data *dbus_data)
+{
+ bdaddr_t *bdaddr;
+ remote_name_req_cp cp;
+ int dd;
+
+ /*get the next remote address */
+ if (!dbus_data->discovered_devices)
+ return -1;
+
+ bdaddr = (bdaddr_t *) dbus_data->discovered_devices->data;
+ if (!bdaddr)
+ return -1;
+
+ dd = hci_open_dev(dbus_data->dev_id);
+ if (dd < 0)
+ return -1;
+
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.bdaddr, bdaddr);
+ cp.pscan_rep_mode = 0x02;
+
+ hci_send_cmd(dd, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ,
+ REMOTE_NAME_REQ_CP_SIZE, &cp);
+
+ hci_close_dev(dd);
+
+ return 0;
+}
+
void hcid_dbus_inquiry_complete(bdaddr_t *local)
{
DBusMessage *message = NULL;
@@ -492,6 +575,10 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);
if (dbus_connection_get_object_path_data(connection, path, (void*) &pdata)) {
+ if (pdata->resolve_name)
+ if (!remote_name_resolve(pdata))
+ goto failed; /* skip, send discovery complete after resolve all remote names */
+
if (pdata->requestor_name) {
free(pdata->requestor_name);
pdata->requestor_name = NULL;
@@ -513,17 +600,20 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
dbus_connection_flush(connection);
failed:
- dbus_message_unref(message);
+ if (message)
+ dbus_message_unref(message);
bt_free(local_addr);
}
void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi)
{
char filename[PATH_MAX + 1];
- DBusMessage *message = NULL;
+ DBusMessage *signal_device = NULL;
+ DBusMessage *signal_name = NULL;
DBusMessageIter iter;
DBusMessageIter array_iter;
char path[MAX_PATH_LENGTH];
+ struct hci_dbus_data *pdata = NULL;
char *local_addr, *peer_addr, *name = NULL;
const char *major_ptr;
char invalid_minor_class[] = "";
@@ -544,9 +634,16 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);
- message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
+ signal_name = dbus_message_new_signal(path, ADAPTER_INTERFACE,
+ "RemoteNameUpdated");
+ if (signal_name == NULL) {
+ error("Can't allocate D-Bus inquiry result message");
+ goto failed;
+ }
+
+ signal_device = dbus_message_new_signal(path, ADAPTER_INTERFACE,
"RemoteDeviceFound");
- if (message == NULL) {
+ if (signal_device == NULL) {
error("Can't allocate D-Bus inquiry result message");
goto failed;
}
@@ -569,7 +666,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
break;
}
- dbus_message_iter_init_append(message, &iter);
+ dbus_message_iter_init_append(signal_device, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &peer_addr);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT16, &tmp_rssi);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &major_ptr);
@@ -586,7 +683,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
dbus_message_iter_close_container(&iter, &array_iter);
- if (dbus_connection_send(connection, message, NULL) == FALSE) {
+ if (dbus_connection_send(connection, signal_device, NULL) == FALSE) {
error("Can't send D-Bus inquiry result message");
goto failed;
}
@@ -595,31 +692,36 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
name = textfile_get(filename, peer_addr);
- if (!name)
- goto failed;
+ if (!name) {
+ /* FIXME: if necessary create a queue to resolve the name */
- dbus_message_unref(message);
+ if (!dbus_connection_get_object_path_data(connection, path, (void*) &pdata)) {
+ error("Getting %s path data failed!", path);
+ goto failed;
+ }
+
+ if (!pdata->resolve_name)
+ goto failed; /* skip - it is a normal request */
+ else
+ remote_name_add(&pdata->discovered_devices, peer);
- message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
- "RemoteDeviceFound");
- if (message == NULL) {
- error("Can't allocate D-Bus inquiry result message");
goto failed;
}
- dbus_message_append_args(message,
+
+ dbus_message_append_args(signal_name,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID);
- if (dbus_connection_send(connection, message, NULL) == FALSE) {
+ if (dbus_connection_send(connection, signal_name, NULL) == FALSE)
error("Can't send D-Bus inquiry result message");
- goto failed;
- }
-
- dbus_connection_flush(connection);
failed:
- dbus_message_unref(message);
+ if (signal_device)
+ dbus_message_unref(signal_device);
+
+ if (signal_name)
+ dbus_message_unref(signal_name);
bt_free(local_addr);
bt_free(peer_addr);
@@ -629,8 +731,9 @@ failed:
}
-void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
+void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char *name)
{
+ struct hci_dbus_data *pdata = NULL;
DBusMessage *message = NULL;
char path[MAX_PATH_LENGTH];
char *local_addr, *peer_addr;
@@ -648,6 +751,16 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);
+
+ /* remove from remote name request list */
+ if (dbus_connection_get_object_path_data(connection, path, (void*) &pdata))
+ remote_name_remove(&pdata->discovered_devices, peer);
+
+ if (!status)
+ goto request_next;
+
+
+ /* send the remote name update signal */
message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
"RemoteNameUpdated");
if (message == NULL) {
@@ -667,6 +780,33 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
dbus_connection_flush(connection);
+request_next:
+ if (!pdata->requestor_name)
+ goto failed; /* handle requests from external app */
+
+ if (!remote_name_resolve(pdata))
+ goto failed; /* skip: there is more remote name to resolve */
+
+ if (message)
+ dbus_message_unref(message);
+
+ message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
+ "DiscoveryCompleted");
+ if (message == NULL) {
+ error("Can't allocate D-Bus inquiry complete message");
+ goto failed;
+ }
+
+ if (dbus_connection_send(connection, message, NULL) == FALSE) {
+ error("Can't send D-Bus inquiry complete message");
+ goto failed;
+ }
+
+ dbus_connection_flush(connection);
+
+ free(pdata->requestor_name);
+ pdata->requestor_name = NULL;
+
failed:
if (message)
dbus_message_unref(message);
diff --git a/hcid/dbus.h b/hcid/dbus.h
index 86008489..14011fa4 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -75,8 +75,10 @@ struct hci_dbus_data {
uint32_t discoverable_timeout;
uint32_t timeout_hits;
timeout_handler_func_t *timeout_handler;
- uint8_t mode;
- char *requestor_name;
+ uint8_t mode; /* scan mode */
+ uint8_t resolve_name; /* send name on discover process */
+ struct slist *discovered_devices;
+ char *requestor_name; /* requestor unique name */
};
struct passkey_agent {
diff --git a/hcid/hcid.h b/hcid/hcid.h
index b4e6f290..ca39bc1d 100644
--- a/hcid/hcid.h
+++ b/hcid/hcid.h
@@ -115,7 +115,7 @@ void hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci);
void hcid_dbus_inquiry_start(bdaddr_t *local);
void hcid_dbus_inquiry_complete(bdaddr_t *local);
void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi);
-void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name);
+void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char *name);
void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer);
void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason);
void hcid_dbus_bonding_created_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status);
@@ -125,7 +125,7 @@ void hcid_dbus_setscan_enable_complete(bdaddr_t *local);
static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {}
static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {}
static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) {}
-static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) {}
+static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char *name) {}
static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {}
static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {}
static inline void hcid_dbus_bonding_created_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) {}
diff --git a/hcid/security.c b/hcid/security.c
index cff54d9d..f3c03ef2 100644
--- a/hcid/security.c
+++ b/hcid/security.c
@@ -325,16 +325,17 @@ static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr)
{
evt_remote_name_req_complete *evt = ptr;
bdaddr_t dba;
+ char name[249];
+ memset(name, 0, sizeof(name));
bacpy(&dba, &evt->bdaddr);
if (!evt->status) {
- char name[249];
- memset(name, 0, sizeof(name));
memcpy(name, evt->name, 248);
write_device_name(sba, &dba, name);
- hcid_dbus_remote_name(sba, &dba, name);
}
+
+ hcid_dbus_remote_name(sba, &dba, evt->status, name);
}
static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr)