diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-03-13 20:47:52 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-03-13 20:47:52 +0000 | 
| commit | 1fe7ab081842276d8db73a44cc64c2115b618cc2 (patch) | |
| tree | 5fe2f882ea3f2cf0fe99737956d11aea65cac0c1 | |
| parent | 5a7676dd838717f9ce483af8e9be0acf80f2960c (diff) | |
Added remote name resolving queue
| -rw-r--r-- | hcid/dbus-adapter.c | 84 | ||||
| -rw-r--r-- | hcid/dbus.c | 182 | ||||
| -rw-r--r-- | hcid/dbus.h | 6 | ||||
| -rw-r--r-- | hcid/hcid.h | 4 | ||||
| -rw-r--r-- | hcid/security.c | 7 | 
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) | 
