diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-23 18:32:16 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-23 18:32:16 +0000 | 
| commit | 277e0363f2839a05b80c1bc4263cfeaf9909be8c (patch) | |
| tree | 1a8830c7b7b030e9d4f5031ac08801f8f0474142 | |
| parent | 7cc971c79cd88798c5c40f9cdf85532a7aeab8a9 (diff) | |
Added device class tracking
| -rw-r--r-- | hcid/dbus-adapter.c | 112 | ||||
| -rw-r--r-- | hcid/dbus-adapter.h | 1 | ||||
| -rw-r--r-- | hcid/dbus-api.txt | 13 | ||||
| -rw-r--r-- | hcid/dbus-hci.c | 49 | ||||
| -rw-r--r-- | hcid/dbus-hci.h | 1 | ||||
| -rw-r--r-- | hcid/device.c | 27 | ||||
| -rw-r--r-- | hcid/hcid.h | 1 | ||||
| -rw-r--r-- | hcid/security.c | 3 | 
8 files changed, 98 insertions, 109 deletions
| diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index 27f7b1c8..ba8d1d90 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -768,8 +768,6 @@ static DBusHandlerResult adapter_get_major_class(DBusConnection *conn,  	const struct adapter *adapter = data;  	DBusMessage *reply;  	const char *str_ptr = "computer"; -	uint8_t cls[3]; -	int dd;  	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))  		return error_invalid_arguments(conn, msg); @@ -778,22 +776,8 @@ static DBusHandlerResult adapter_get_major_class(DBusConnection *conn,  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	dd = hci_open_dev(adapter->dev_id); -	if (dd < 0) -		return error_no_such_adapter(conn, msg); - -	if (hci_read_class_of_dev(dd, cls, 1000) < 0) { -		int err = errno; -		error("Can't read class of device on hci%d: %s(%d)", -				adapter->dev_id, strerror(errno), errno); -		hci_close_dev(dd); -		return error_failed(conn, msg, err); -	} - -	hci_close_dev(dd); -  	/* FIXME: Currently, only computer major class is supported */ -	if ((cls[1] & 0x1f) != 1) +	if ((adapter->class[1] & 0x1f) != 1)  		return error_unsupported_major_class(conn, msg);  	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, @@ -810,31 +794,13 @@ static DBusHandlerResult adapter_list_minor_classes(DBusConnection *conn,  	DBusMessageIter iter;  	DBusMessageIter array_iter;  	const char **minor_ptr; -	uint8_t cls[3];  	uint8_t major_class; -	int dd, size, i; - -	if (!adapter->up) -		return error_not_ready(conn, msg); +	int size, i;  	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))  		return error_invalid_arguments(conn, msg); -	dd = hci_open_dev(adapter->dev_id); -	if (dd < 0) -		return error_no_such_adapter(conn, msg); - -	if (hci_read_class_of_dev(dd, cls, 1000) < 0) { -		int err = errno; -		error("Can't read class of device on hci%d: %s(%d)", -				adapter->dev_id, strerror(errno), errno); -		hci_close_dev(dd); -		return error_failed(conn, msg, err); -	} - -	hci_close_dev(dd); - -	major_class = cls[1] & 0x1F; +	major_class = adapter->class[1] & 0x1F;  	switch (major_class) {  	case 1: /* computer */ @@ -871,39 +837,20 @@ static DBusHandlerResult adapter_get_minor_class(DBusConnection *conn,  	struct adapter *adapter = data;  	DBusMessage *reply;  	const char *str_ptr = ""; -	uint8_t cls[3];  	uint8_t minor_class; -	int dd; - -	if (!adapter->up) -		return error_not_ready(conn, msg);  	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))  		return error_invalid_arguments(conn, msg); -	dd = hci_open_dev(adapter->dev_id); -	if (dd < 0) -		return error_no_such_adapter(conn, msg); - -	if (hci_read_class_of_dev(dd, cls, 1000) < 0) { -		int err = errno; -		error("Can't read class of device on hci%d: %s(%d)", -				adapter->dev_id, strerror(errno), errno); -		hci_close_dev(dd); -		return error_failed(conn, msg, err); -	} - -	hci_close_dev(dd); -  	/* FIXME: Currently, only computer major class is supported */ -	if ((cls[1] & 0x1f) != 1) +	if ((adapter->class[1] & 0x1f) != 1)  		return error_unsupported_major_class(conn, msg);  	reply = dbus_message_new_method_return(msg);  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	minor_class = cls[0] >> 2; +	minor_class = adapter->class[0] >> 2;  	/* Validate computer minor class */  	if (minor_class > (sizeof(computer_minor_cls) / sizeof(*computer_minor_cls))) @@ -923,9 +870,7 @@ static DBusHandlerResult adapter_set_minor_class(DBusConnection *conn,  {  	struct adapter *adapter = data;  	DBusMessage *reply; -	bdaddr_t bdaddr;  	const char *minor; -	uint8_t cls[3];  	uint32_t dev_class = 0xFFFFFFFF;  	int i, dd; @@ -944,18 +889,11 @@ static DBusHandlerResult adapter_set_minor_class(DBusConnection *conn,  	if (dd < 0)  		return error_no_such_adapter(conn, msg); -	if (hci_read_class_of_dev(dd, cls, 1000) < 0) { -		int err = errno; -		error("Can't read class of device on hci%d: %s(%d)", -				adapter->dev_id, strerror(errno), errno); -		hci_close_dev(dd); -		return error_failed(conn, msg, err); -	} -  	/* Currently, only computer major class is supported */ -	if ((cls[1] & 0x1f) != 1) +	if ((adapter->class[1] & 0x1f) != 1) { +		hci_close_dev(dd);  		return error_unsupported_major_class(conn, msg); - +	}  	for (i = 0; i < sizeof(computer_minor_cls) / sizeof(*computer_minor_cls); i++)  		if (!strcasecmp(minor, computer_minor_cls[i])) {  			/* Remove the format type */ @@ -964,18 +902,13 @@ static DBusHandlerResult adapter_set_minor_class(DBusConnection *conn,  		}  	/* Check if it's a valid minor class */ -	if (dev_class == 0xFFFFFFFF) +	if (dev_class == 0xFFFFFFFF) { +		hci_close_dev(dd);  		return error_invalid_arguments(conn, msg); - -	/* update the minor class before store */ -	cls[0] = (dev_class & 0xff); +	}  	/* set the service class and major class  */ -	dev_class |= (cls[2] << 16) | (cls[1] << 8); - -	hci_devba(adapter->dev_id, &bdaddr); - -	write_local_class(&bdaddr, cls); +	dev_class |= (adapter->class[2] << 16) | (adapter->class[1] << 8);  	if (hci_write_class_of_dev(dd, dev_class, 2000) < 0) {  		int err = errno; @@ -1006,8 +939,7 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,  	DBusMessageIter iter;  	DBusMessageIter array_iter;  	const char *str_ptr; -	uint8_t cls[3]; -	int dd, i; +	int i;  	if (!adapter->up)  		return error_not_ready(conn, msg); @@ -1015,19 +947,9 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,  	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))  		return error_invalid_arguments(conn, msg); -	dd = hci_open_dev(adapter->dev_id); -	if (dd < 0) -		return error_no_such_adapter(conn, msg); - -	if (hci_read_class_of_dev(dd, cls, 1000) < 0) { -		int err = errno; -		error("Can't read class of device on hci%d: %s(%d)", -				adapter->dev_id, strerror(errno), errno); -		hci_close_dev(dd); -		return error_failed(conn, msg, err); -	} -  	reply = dbus_message_new_method_return(msg); +	if (!reply) +		return DBUS_HANDLER_RESULT_NEED_MEMORY;  	dbus_message_iter_init_append(reply, &iter); @@ -1035,7 +957,7 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,  				DBUS_TYPE_STRING_AS_STRING, &array_iter);  	for (i = 0; i < (sizeof(service_cls) / sizeof(*service_cls)); i++) { -		if (cls[2] & (1 << i)) { +		if (adapter->class[2] & (1 << i)) {  			str_ptr = service_cls[i];  			dbus_message_iter_append_basic(&array_iter,  						DBUS_TYPE_STRING, &str_ptr); @@ -1044,8 +966,6 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,  	dbus_message_iter_close_container(&iter, &array_iter); -	hci_close_dev(dd); -  	return send_message_and_unref(conn, reply);  } diff --git a/hcid/dbus-adapter.h b/hcid/dbus-adapter.h index 6086787c..2c75c5dc 100644 --- a/hcid/dbus-adapter.h +++ b/hcid/dbus-adapter.h @@ -91,6 +91,7 @@ struct adapter {  	guint timeout_id;		/* discoverable timeout id */  	uint32_t discov_timeout;	/* discoverable time(msec) */  	uint8_t mode;			/* scan mode */ +	uint8_t class[3];		/* device class */  	int discov_active;		/* standard discovery active: includes name resolution step */  	int pdiscov_active;		/* periodic discovery active */  	int pinq_idle;			/* tracks the idle time for periodic inquiry */ diff --git a/hcid/dbus-api.txt b/hcid/dbus-api.txt index 7f1ed3b6..9fc19578 100644 --- a/hcid/dbus-api.txt +++ b/hcid/dbus-api.txt @@ -434,9 +434,8 @@ Methods		dict GetInfo()  			For the other values, unsupported major class  			error is returned. -			Possible errors: org.bluez.Error.NoSuchAdapter +			Possible errors: org.bluez.Error.InvalidArguments  					 org.bluez.Error.UnsupportedMajorClass -					 org.bluez.Error.Failed  		array{string} ListAvailableMinorClasses() @@ -448,9 +447,7 @@ Methods		dict GetInfo()  			If the major class is not "computer" an error should  			be returned. -			Possible errors: org.bluez.Error.NotReady -					 org.bluez.Error.NoSuchAdapter -					 org.bluez.Error.Failed +			Possible errors: org.bluez.Error.InvalidArguments  					 org.bluez.Error.UnsupportedMajorClass  		string GetMinorClass() @@ -466,10 +463,8 @@ Methods		dict GetInfo()  			The default value is "uncategorized". -			Possible errors: org.bluez.Error.NotReady -					 org.bluez.Error.NoSuchAdapter -					 org.bluez.Error.Failed -					 org.bluez.Error.UnsupportedMajorClass +			Possible errors:org.bluez.Error.InvalidArguments +					org.bluez.Error.UnsupportedMajorClass  		void SetMinorClass(string minor) diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index c0e3b5f3..242d8e3d 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -586,8 +586,11 @@ int hcid_dbus_start_device(uint16_t id)  	if (err < 0)  		goto failed; -	adapter_mode_changed(adapter, path, mode); +	err = get_device_class(adapter->dev_id, adapter->class); +	if (err < 0) +		goto failed; +	adapter_mode_changed(adapter, path, mode);  	/*   	 * retrieve the active connections: address the scenario where  	 * the are active connections before the daemon've started @@ -1838,6 +1841,50 @@ failed:  	bt_free(local_addr);  } +void hcid_dbus_write_class_complete(bdaddr_t *local) +{ +	struct adapter *adapter; +	char path[MAX_PATH_LENGTH]; +	char *local_addr; +	bdaddr_t tmp; +	int id, dd = -1; +	uint8_t cls[3]; + +	baswap(&tmp, local); local_addr = batostr(&tmp); +	id = hci_devid(local_addr); +	if (id < 0) { +		error("No matching device id for %s", local_addr); +		goto failed; +	} + +	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id); +	if (!dbus_connection_get_object_user_data(connection, path, +							(void *) &adapter)) { +		error("Getting %s path data failed!", path); +		goto failed; +	} + +	dd = hci_open_dev(id); +	if (dd < 0) { +		error("HCI device open failed: hci%d", id); +		goto failed; +	} + +	if (hci_read_class_of_dev(dd, cls, 1000) < 0) { +		error("Can't read class of device on hci%d: %s(%d)", +					id, strerror(errno), errno); +		goto failed; +	} + +	write_local_class(local, cls); +	memcpy(adapter->class, cls, 3); +failed: +	if (dd >= 0) +		hci_close_dev(dd); + +	bt_free(local_addr); +} +  void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr)  { diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h index 5a7f9628..eb81415f 100644 --- a/hcid/dbus-hci.h +++ b/hcid/dbus-hci.h @@ -49,6 +49,7 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle  void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);  void hcid_dbus_setname_complete(bdaddr_t *local);  void hcid_dbus_setscan_enable_complete(bdaddr_t *local); +void hcid_dbus_write_class_complete(bdaddr_t *local);  void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr);  int unregister_adapter_path(const char *path); diff --git a/hcid/device.c b/hcid/device.c index 4d2239ec..920a4dad 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -81,6 +81,7 @@ struct hci_dev {  	uint16_t manufacturer;  	uint8_t  name[248]; +	uint8_t  class[3];  	struct hci_peer *peers;  	struct hci_conn *conns; @@ -203,7 +204,7 @@ int start_device(uint16_t dev_id)  	struct hci_dev *dev;  	struct hci_version ver;  	uint8_t features[8], inqmode; -	int dd; +	int dd, err;  	ASSERT_DEV_ID; @@ -233,15 +234,23 @@ int start_device(uint16_t dev_id)  	dev->manufacturer = ver.manufacturer;  	if (hci_read_local_features(dd, features, 1000) < 0) { -		int err = errno; +		err = errno;  		error("Can't read features for hci%d: %s (%d)", -					dev_id, strerror(errno), errno); +					dev_id, strerror(err), err);  		hci_close_dev(dd);  		return -err;  	}  	memcpy(dev->features, features, 8); +	if (hci_read_class_of_dev(dd, dev->class, 1000) < 0) { +		err = errno; +		error("Can't read class of device on hci%d: %s(%d)", +				dev_id, strerror(err), err); +		hci_close_dev(dd); +		return -err; +	} +  	inqmode = get_inquiry_mode(dev);  	if (inqmode < 1)  		goto done; @@ -285,6 +294,18 @@ int get_device_address(uint16_t dev_id, char *address, size_t size)  	return ba2str(&dev->bdaddr, address);  } +int get_device_class(uint16_t dev_id, uint8_t *cls) +{ +	struct hci_dev *dev; + +	ASSERT_DEV_ID; + +	dev = &devices[dev_id]; +	memcpy(cls, dev->class, 3); + +	return 0; +} +  int get_device_version(uint16_t dev_id, char *version, size_t size)  {  	struct hci_dev *dev; diff --git a/hcid/hcid.h b/hcid/hcid.h index 86b21639..50451a6b 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -157,6 +157,7 @@ int start_device(uint16_t dev_id);  int stop_device(uint16_t dev_id);  int get_device_address(uint16_t dev_id, char *address, size_t size); +int get_device_class(uint16_t dev_id, uint8_t *class);  int get_device_version(uint16_t dev_id, char *version, size_t size);  int get_device_revision(uint16_t dev_id, char *revision, size_t size);  int get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size); diff --git a/hcid/security.c b/hcid/security.c index 77062dbd..3f72f5cd 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -436,6 +436,9 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)  	case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE):  		hcid_dbus_setscan_enable_complete(sba);  		break; +	case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV): +		hcid_dbus_write_class_complete(sba); +		break;  	case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_REPLY):  	case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY):  		hcid_dbus_pin_code_reply(sba, ptr); | 
