diff options
| -rw-r--r-- | hcid/dbus-adapter.c | 187 | ||||
| -rw-r--r-- | hcid/dbus-api.txt | 19 | ||||
| -rw-r--r-- | hcid/dbus.c | 1 | 
3 files changed, 184 insertions, 23 deletions
| diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index 7365a0c1..c0da1d1a 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -638,6 +638,8 @@ static DBusHandlerResult handle_dev_set_minor_class_req(DBusConnection *conn, DB  		return error_invalid_arguments(conn, msg);  	} +	/* FIXME: check if the major class is computer. If not, return UnsupportedMajorClass */ +  	if (!minor)  		return error_invalid_arguments(conn, msg); @@ -681,7 +683,7 @@ static DBusHandlerResult handle_dev_set_minor_class_req(DBusConnection *conn, DB  		return error_failed(conn, msg, errno);  	} -	signal = dev_signal_factory(dbus_data->dev_id, "MinorClassChange", +	signal = dev_signal_factory(dbus_data->dev_id, "MinorClassChanged",  						DBUS_TYPE_STRING, &minor,  						DBUS_TYPE_INVALID);  	if (signal) { @@ -803,31 +805,168 @@ static DBusHandlerResult handle_dev_set_name_req(DBusConnection *conn, DBusMessa  static DBusHandlerResult handle_dev_get_remote_version_req(DBusConnection *conn, DBusMessage *msg, void *data)  { -	return error_not_implemented(conn, msg); -} +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	DBusError err; +	char filename[PATH_MAX + 1]; +	char addr[18], *addr_ptr, *str; +	const char *str_ver; +	char info_array[64], *info = info_array; +	int compid, ver, subver; +	int ecode; +	uint8_t features; -static DBusHandlerResult handle_dev_get_remote_revision_req(DBusConnection *conn, DBusMessage *msg, void *data) -{ -	return error_not_implemented(conn, msg); +	dbus_error_init(&err); + +	memset(info_array, 0, 64); + +	dbus_message_get_args(msg, &err, +				DBUS_TYPE_STRING, &addr_ptr, +				DBUS_TYPE_INVALID); + +	if (dbus_error_is_set(&err)) { +		error("Can't extract message arguments:%s", err.message); +		dbus_error_free(&err); +		return error_invalid_arguments(conn, msg); +	} + +	if (check_address(addr_ptr) < 0) +		return error_invalid_arguments(conn, msg); + +	ecode = get_device_address(dbus_data->dev_id, addr, sizeof(addr)); +	if (ecode < 0) +		return error_failed(conn, msg, -ecode); + +	snprintf(filename, PATH_MAX, "%s/%s/lastseen", STORAGEDIR, addr); + +	str = textfile_get(filename, addr_ptr); +	if (!str) +		return error_unknown_address(conn, msg); + +	free(str); + +	snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); + +	str = textfile_get(filename, addr_ptr); +	if (!str) +		return error_not_available(conn, msg); + +	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) != 3) { +		/* corrupted file data */ +		free(str); +		goto failed; +	} + +	free(str); + +	str_ver = lmp_vertostr(ver); + +	/* default value */ +	snprintf(info, 64, "Bluetooth %s", str_ver); + +	snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr); + +	str = textfile_get(filename, addr_ptr); +	if (!str) +		goto failed; + +	/* check if the data is not corrupted */ +	if (strlen(str) == 16) { +		/* Getting the third byte */ +		features  = ((str[6] - 48) << 4) | (str[7] - 48); +		if (features & (LMP_EDR_ACL_2M | LMP_EDR_ACL_3M)) +			snprintf(info, 64, "Bluetooth %s + EDR", str_ver); +	} + +	free(str); + +failed: + +	reply = dbus_message_new_method_return(msg); +	if (!reply) +		return error_out_of_memory(conn, msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &info, +					DBUS_TYPE_INVALID); + +	return send_reply_and_unref(conn, reply);  } -static DBusHandlerResult handle_dev_get_remote_manufacturer_req(DBusConnection *conn, DBusMessage *msg, void *data) +static DBusHandlerResult handle_dev_get_remote_revision_req(DBusConnection *conn, DBusMessage *msg, void *data)  {  	struct hci_dbus_data *dbus_data = data;  	DBusMessage *reply;  	DBusError err;  	char filename[PATH_MAX + 1];  	char addr[18], *addr_ptr, *str; -	int compid; +	char info_array[16], *info = info_array; +	int compid, ver, subver;  	int ecode; +	dbus_error_init(&err); + +	memset(info_array, 0, 16); + +	dbus_message_get_args(msg, &err, +				DBUS_TYPE_STRING, &addr_ptr, +				DBUS_TYPE_INVALID); + +	if (dbus_error_is_set(&err)) { +		error("Can't extract message arguments:%s", err.message); +		dbus_error_free(&err); +		return error_invalid_arguments(conn, msg); +	} + +	if (check_address(addr_ptr) < 0) +		return error_invalid_arguments(conn, msg); +  	ecode = get_device_address(dbus_data->dev_id, addr, sizeof(addr));  	if (ecode < 0)  		return error_failed(conn, msg, -ecode); +	snprintf(filename, PATH_MAX, "%s/%s/lastseen", STORAGEDIR, addr); + +	str = textfile_get(filename, addr_ptr); +	if (!str) +		return error_unknown_address(conn, msg); + +	free(str); +  	snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); +	str = textfile_get(filename, addr_ptr); +	if (!str) +		return error_not_available(conn, msg); + +	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) == 3) +		snprintf(info, 16, "HCI 0x%X", subver); + +	free(str); + +	reply = dbus_message_new_method_return(msg); +	if (!reply) +		return error_out_of_memory(conn, msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &info, +					DBUS_TYPE_INVALID); + +	return send_reply_and_unref(conn, reply); +} + +static DBusHandlerResult handle_dev_get_remote_manufacturer_req(DBusConnection *conn, DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	DBusError err; +	char filename[PATH_MAX + 1]; +	char addr[18], *addr_ptr, *str; +	char info_array[64], *info = info_array; +	int compid, ver, subver; +	int ecode;  	dbus_error_init(&err); + +	memset(info_array, 0, 64); +  	dbus_message_get_args(msg, &err,  				DBUS_TYPE_STRING, &addr_ptr,  				DBUS_TYPE_INVALID); @@ -838,21 +977,37 @@ static DBusHandlerResult handle_dev_get_remote_manufacturer_req(DBusConnection *  		return error_invalid_arguments(conn, msg);  	} +	if (check_address(addr_ptr) < 0) +		return error_invalid_arguments(conn, msg); + +	ecode = get_device_address(dbus_data->dev_id, addr, sizeof(addr)); +	if (ecode < 0) +		return error_failed(conn, msg, -ecode); + +	snprintf(filename, PATH_MAX, "%s/%s/lastseen", STORAGEDIR, addr); +  	str = textfile_get(filename, addr_ptr);  	if (!str) -		return error_failed(conn, msg, ENXIO); - -	compid = atoi(str); +		return error_unknown_address(conn, msg);  	free(str); -	str = bt_compidtostr(compid); +	snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); + +	str = textfile_get(filename, addr_ptr); +	if (!str) +		return error_not_available(conn, msg); + +	if (sscanf(str, "%d %d %d", &compid, &ver, &subver) == 3) +		info = bt_compidtostr(compid); + +	free(str);  	reply = dbus_message_new_method_return(msg);  	if (!reply)  		return error_out_of_memory(conn, msg); -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str, +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &info,  					DBUS_TYPE_INVALID);  	return send_reply_and_unref(conn, reply); @@ -1526,9 +1681,11 @@ static DBusHandlerResult handle_dev_remove_bonding_req(DBusConnection *conn, DBu  	snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); -  	/* Delete the link key from storage */ -	textfile_del(filename, addr_ptr); +	if (textfile_del(filename, addr_ptr)) { +		hci_close_dev(dd); +		return error_bonding_does_not_exist(conn, msg); +	}  	str2ba(addr_ptr, &bdaddr); diff --git a/hcid/dbus-api.txt b/hcid/dbus-api.txt index b3c1397b..be07afab 100644 --- a/hcid/dbus-api.txt +++ b/hcid/dbus-api.txt @@ -248,7 +248,7 @@ Methods		string GetAddress()  			Changing this value doesn't set the adapter into  			discoverable mode. The SetMode method must be used. -			Possible errors: org.bluez.Error.Failed +			Possible errors: org.bluez.Error.InvalidArguments  		boolean IsConnectable() @@ -275,7 +275,7 @@ Methods		string GetAddress()  			Return true if the local adapter is connected to  			the remote device. -			Possible errors: none +			Possible errors: org.bluez.Error.InvalidArguments  		array{string} ListConnections() @@ -329,7 +329,8 @@ Methods		string GetAddress()  			If the major class is not "computer" an error should  			be returned. -			Possible errors: org.bluez.Error.UnsupportedMajorClass +			Possible errors: org.bluez.Error.InvalidArguments +					 org.bluez.Error.UnsupportedMajorClass  		array{string} GetServiceClasses() @@ -375,7 +376,8 @@ Methods		string GetAddress()  			Example: "Bluetooth 2.0 + EDR" -			Possible errors: org.bluez.Error.UnknownAddress +			Possible errors: org.bluez.Error.InvalidArguments +					 org.bluez.Error.UnknownAddress  			                 org.bluez.Error.NotAvailable  		string GetRemoteRevision(string address) @@ -387,7 +389,8 @@ Methods		string GetAddress()  			Example: "HCI 19.2" -			Possible errors: org.bluez.Error.UnknownAddress +			Possible errors: org.bluez.Error.InvalidArguments +					 org.bluez.Error.UnknownAddress  			                 org.bluez.Error.NotAvailable  		string GetRemoteManufacturer(string address) @@ -396,7 +399,8 @@ Methods		string GetAddress()  			Example: "Nokia Mobile Phones" -			Possible errors: org.bluez.Error.UnknownAddress +			Possible errors: org.bluez.Error.InvalidArguments +					 org.bluez.Error.UnknownAddress  			                 org.bluez.Error.NotAvailable  		string GetRemoteCompany(string address) @@ -553,8 +557,7 @@ Methods		string GetAddress()  			After deleting the link key this method will send a  			BondingRemoved signal. -			Possible errors: org.bluez.Error.UnknownAddress -			                 org.bluez.Error.DoesNotExist +			Possible errors: org.bluez.Error.DoesNotExist  		boolean HasBonding(string address) diff --git a/hcid/dbus.c b/hcid/dbus.c index f58697e2..2c159ead 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -551,6 +551,7 @@ gboolean hcid_dbus_register_device(uint16_t id)  	if (ioctl(dd, HCIGETCONNLIST, (void *) cl) < 0) {  		free(cl); +		cl = NULL;  		goto failed;  	} | 
