diff options
| -rw-r--r-- | hcid/Makefile.am | 5 | ||||
| -rw-r--r-- | hcid/dbus-device.c | 822 | ||||
| -rw-r--r-- | hcid/dbus-error.c | 158 | ||||
| -rw-r--r-- | hcid/dbus-manager.c | 183 | ||||
| -rw-r--r-- | hcid/dbus.c | 1145 | ||||
| -rw-r--r-- | hcid/dbus.h | 30 | ||||
| -rw-r--r-- | hcid/hcid.h | 6 | ||||
| -rw-r--r-- | hcid/security.c | 14 | 
8 files changed, 1216 insertions, 1147 deletions
diff --git a/hcid/Makefile.am b/hcid/Makefile.am index a4189f5f..3b01cc6d 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -18,7 +18,7 @@ sbin_PROGRAMS = hcid  noinst_SCRIPTS = dbus-test  if DBUS -dbus_hcid_sources = dbus.h dbus.c +dbus_hcid_sources = dbus.h dbus.c dbus-error.c dbus-manager.c dbus-device.c  dbus_hcid_libs    = @DBUS_LIBS@  dbus_hcid_cflags  = -DENABLE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE  else @@ -45,6 +45,7 @@ AM_YFLAGS = -d  CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c dbus-test bluez-hcid.conf +EXTRA_DIST = $(man_MANS) $(conf_DATA) bluez-hcid.conf dbus-test \ +		dbus.h dbus.c dbus-error.c dbus-manager.c dbus-device.c  MAINTAINERCLEANFILES = Makefile.in diff --git a/hcid/dbus-device.c b/hcid/dbus-device.c new file mode 100644 index 00000000..d129effc --- /dev/null +++ b/hcid/dbus-device.c @@ -0,0 +1,822 @@ +/* + * + *  BlueZ - Bluetooth protocol stack for Linux + * + *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org> + * + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, write to the Free Software + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h> + +#include <dbus/dbus.h> + +#include "hcid.h" +#include "dbus.h" + +#include "textfile.h" + +static char *get_peer_name(const bdaddr_t *local, const bdaddr_t *peer) +{ +	char filename[PATH_MAX + 1], addr[18]; + +	ba2str(local, addr); +	snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); + +	ba2str(peer, addr); +	return textfile_get(filename, addr); +} + +static DBusMessage* handle_dev_get_address_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	char str[18], *str_ptr = str; + +	get_device_address(dbus_data->dev_id, str, sizeof(str)); + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_get_version_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	char str[20], *str_ptr = str; + +	get_device_version(dbus_data->dev_id, str, sizeof(str)); + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_get_revision_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	char str[20], *str_ptr = str; + +	get_device_revision(dbus_data->dev_id, str, sizeof(str)); + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_get_manufacturer_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	char str[64], *str_ptr = str; + +	get_device_manufacturer(dbus_data->dev_id, str, sizeof(str)); + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_get_company_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	char str[64], *str_ptr = str; + +	get_device_company(dbus_data->dev_id, str, sizeof(str)); + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_get_features_req(DBusMessage *msg, void *data) +{ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_get_name_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply; +	char str[249], *str_ptr = str; + +	get_device_name(dbus_data->dev_id, str, sizeof(str)); + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_set_name_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessageIter iter; +	DBusMessage *reply; +	char *str_ptr; + +	dbus_message_iter_init(msg, &iter); +	dbus_message_iter_get_basic(&iter, &str_ptr); + +	if (strlen(str_ptr) == 0) { +		syslog(LOG_ERR, "Name change failed: Invalid parameter"); +		return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); +	} + +	set_device_name(dbus_data->dev_id, str_ptr); + +	reply = dbus_message_new_method_return(msg); + +	return reply; +} + +static DBusMessage* handle_dev_get_alias_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusMessageIter iter; +	DBusMessage *reply; +	char str[249], *str_ptr = str, *addr_ptr; +	bdaddr_t bdaddr; + +	dbus_message_iter_init(msg, &iter); +	dbus_message_iter_get_basic(&iter, &addr_ptr); + +	str2ba(addr_ptr, &bdaddr); + +	get_device_alias(dbus_data->dev_id, &bdaddr, str, sizeof(str)); + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_set_alias_req(DBusMessage *msg, void *data) +{ +	struct hci_dbus_data *dbus_data = data; +	DBusConnection *connection = get_dbus_connection(); +	DBusMessageIter iter; +	DBusMessage *reply, *signal; +	char *str_ptr, *addr_ptr; +	bdaddr_t bdaddr; + +	dbus_message_iter_init(msg, &iter); +	dbus_message_iter_get_basic(&iter, &addr_ptr); +	dbus_message_iter_next(&iter); +	dbus_message_iter_get_basic(&iter, &str_ptr); + +	if (strlen(str_ptr) == 0) { +		syslog(LOG_ERR, "Alias change failed: Invalid parameter"); +		return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); +	} + +	str2ba(addr_ptr, &bdaddr); + +	set_device_alias(dbus_data->dev_id, &bdaddr, str_ptr); + +	signal = dev_signal_factory(dbus_data->dev_id, "AliasChanged", +						DBUS_TYPE_STRING, &addr_ptr, +						DBUS_TYPE_STRING, &str_ptr, +						DBUS_TYPE_INVALID); +	if (signal) { +		dbus_connection_send(connection, signal, NULL); +		dbus_connection_flush(connection); +		dbus_message_unref(signal); +	} + +	signal = dev_signal_factory(dbus_data->dev_id, "RemoteAlias", +						DBUS_TYPE_STRING, &addr_ptr, +						DBUS_TYPE_STRING, &str_ptr, +						DBUS_TYPE_INVALID); +	if (signal) { +		dbus_connection_send(connection, signal, NULL); +		dbus_connection_flush(connection); +		dbus_message_unref(signal); +	} + +	reply = dbus_message_new_method_return(msg); + +	return reply; +} + +static DBusMessage* handle_dev_get_discoverable_to_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_get_mode_req(DBusMessage *msg, void *data) +{ +	const struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply = NULL; +	const uint8_t hci_mode = dbus_data->path_data; +	uint8_t scan_mode; + +	switch (hci_mode) { +	case SCAN_DISABLED: +		scan_mode = MODE_OFF; +		break; +	case SCAN_PAGE: +		scan_mode = MODE_CONNECTABLE; +		break; +	case (SCAN_PAGE | SCAN_INQUIRY): +		scan_mode = MODE_DISCOVERABLE; +		break; +	case SCAN_INQUIRY: +	/* inquiry scan mode is not handled, return 0xff */ +	default: +		/* reserved */ +		scan_mode = 0xff; +	} + +	reply = dbus_message_new_method_return(msg); + +	dbus_message_append_args(reply, +					DBUS_TYPE_BYTE, &scan_mode, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static DBusMessage* handle_dev_is_connectable_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_is_discoverable_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_set_class_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_set_discoverable_to_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_set_mode_req(DBusMessage *msg, void *data) +{ +	const struct hci_dbus_data *dbus_data = data; +	DBusMessage *reply = NULL; +	struct hci_request rq; +	int dd = -1; +	const uint8_t scan_mode; +	uint8_t hci_mode; +	uint8_t status = 0; +	const uint8_t current_mode = dbus_data->path_data; + +	dbus_message_get_args(msg, NULL, +					DBUS_TYPE_BYTE, &scan_mode, +					DBUS_TYPE_INVALID); + +	switch (scan_mode) { +	case MODE_OFF: +		hci_mode = SCAN_DISABLED; +		break; +	case MODE_CONNECTABLE: +		hci_mode = SCAN_PAGE; +		break; +	case MODE_DISCOVERABLE: +		hci_mode = (SCAN_PAGE | SCAN_INQUIRY); +		break; +	default: +		/* invalid mode */ +		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); +		goto failed; +	} + +	dd = hci_open_dev(dbus_data->dev_id); +	if (dd < 0) { +		syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); +		goto failed; +	} + +	/* Check if the new requested mode is different from the current */ +	if (current_mode != hci_mode) { +		memset(&rq, 0, sizeof(rq)); +		rq.ogf    = OGF_HOST_CTL; +		rq.ocf    = OCF_WRITE_SCAN_ENABLE; +		rq.cparam = &hci_mode; +		rq.clen   = sizeof(hci_mode); +		rq.rparam = &status; +		rq.rlen   = sizeof(status); + +		if (hci_send_req(dd, &rq, 100) < 0) { +			syslog(LOG_ERR, "Sending write scan enable command failed: %s (%d)", +							strerror(errno), errno); +			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno); +			goto failed; +		} +		if (status) { +			syslog(LOG_ERR, "Setting scan enable failed with status 0x%02x", status); +			reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET | status); +			goto failed; +		} + +	} + +	reply = dbus_message_new_method_return(msg); + +failed: +	if (dd >= 0) +		close(dd); + +	return reply; +} + +static DBusMessage* handle_dev_discover_req(DBusMessage *msg, void *data) +{ +	DBusMessage *reply = NULL; +	inquiry_cp cp; +	evt_cmd_status rp; +	struct hci_request rq; +	struct hci_dbus_data *dbus_data = data; +	int dd = -1; +	uint8_t length = 8, num_rsp = 0; +	uint32_t lap = 0x9e8b33; + +	dd = hci_open_dev(dbus_data->dev_id); +	if (dd < 0) { +		syslog(LOG_ERR, "Unable to open device %d: %s (%d)", +					dbus_data->dev_id, strerror(errno), errno); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	memset(&cp, 0, sizeof(cp)); +	cp.lap[0]  = lap & 0xff; +	cp.lap[1]  = (lap >> 8) & 0xff; +	cp.lap[2]  = (lap >> 16) & 0xff; +	cp.length  = length; +	cp.num_rsp = num_rsp; + +	memset(&rq, 0, sizeof(rq)); +	rq.ogf    = OGF_LINK_CTL; +	rq.ocf    = OCF_INQUIRY; +	rq.cparam = &cp; +	rq.clen   = INQUIRY_CP_SIZE; +	rq.rparam = &rp; +	rq.rlen   = EVT_CMD_STATUS_SIZE; +	rq.event  = EVT_CMD_STATUS; + +	if (hci_send_req(dd, &rq, 100) < 0) { +		syslog(LOG_ERR, "Unable to start inquiry: %s (%d)", +							strerror(errno), errno); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	reply = dbus_message_new_method_return(msg); + +failed: +	if (dd >= 0) +		hci_close_dev(dd); + +	return reply; + +} + +static DBusMessage* handle_dev_discover_cache_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_discover_cancel_req(DBusMessage *msg, void *data) +{ +	DBusMessage *reply = NULL; +	struct hci_request rq; +	struct hci_dbus_data *dbus_data = data; +	uint8_t status; +	int dd = -1; + +	dd = hci_open_dev(dbus_data->dev_id); +	if (dd < 0) { +		syslog(LOG_ERR, "Unable to open device %d: %s (%d)", +					dbus_data->dev_id, strerror(errno), errno); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	memset(&rq, 0, sizeof(rq)); +	rq.ogf    = OGF_LINK_CTL; +	rq.ocf    = OCF_INQUIRY_CANCEL; +	rq.rparam = &status; +	rq.rlen   = sizeof(status); + +	if (hci_send_req(dd, &rq, 100) < 0) { +		syslog(LOG_ERR, "Sending cancel inquiry failed: %s (%d)", +							strerror(errno), errno); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	if (status) { +		syslog(LOG_ERR, "Cancel inquiry failed with status 0x%02x", status); +		reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); +		goto failed; +	} + +	reply = dbus_message_new_method_return(msg); + +failed: +	if (dd >= 0) +		hci_close_dev(dd); + +	return reply; +} + +static DBusMessage* handle_dev_discover_service_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_last_seen_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_last_used_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_remote_alias_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_remote_name_req(DBusMessage *msg, void *data) +{ +	DBusConnection *connection = get_dbus_connection(); +	DBusMessage *reply = NULL; +	DBusMessage *signal = NULL; +	struct hci_dbus_data *dbus_data = data; +	const char *str_bdaddr; +	char *name; +	char path[MAX_PATH_LENGTH]; +	bdaddr_t bdaddr; +	struct hci_dev_info di; +	struct hci_request rq; +	remote_name_req_cp cp; +	evt_cmd_status rp; +	int dd = -1; + +	dbus_message_get_args(msg, NULL, +					DBUS_TYPE_STRING, &str_bdaddr, +					DBUS_TYPE_INVALID); + +	str2ba(str_bdaddr, &bdaddr); +	if (hci_devinfo(dbus_data->dev_id, &di) < 0) { +		syslog(LOG_ERR, "Can't get device info"); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); +		goto failed; +	} + +	/* Try retrieve from local cache */ +	name = get_peer_name(&di.bdaddr, &bdaddr); +	if (name) { + +		reply = dbus_message_new_method_return(msg); + +		snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, dbus_data->dev_id); + +		signal = dbus_message_new_signal(path, DEVICE_INTERFACE, +							DEV_SIG_REMOTE_NAME); + +		dbus_message_append_args(signal, +						DBUS_TYPE_STRING, &str_bdaddr, +						DBUS_TYPE_STRING, &name, +						DBUS_TYPE_INVALID); + +		if (dbus_connection_send(connection, signal, NULL) == FALSE) { +			syslog(LOG_ERR, "Can't send D-BUS remote name signal message"); +			goto failed; +		} + +		dbus_message_unref(signal); +		free(name); + +	} else { + +		/* Send HCI command */ +		dd = hci_open_dev(dbus_data->dev_id); +		if (dd < 0) { +			syslog(LOG_ERR, "Unable to open device %d: %s (%d)", +						dbus_data->dev_id, strerror(errno), errno); +			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno); +			goto failed; +		} + +		memset(&cp, 0, sizeof(cp)); +		cp.bdaddr = bdaddr; +		cp.pscan_rep_mode = 0x02; + +		memset(&rq, 0, sizeof(rq)); +		rq.ogf    = OGF_LINK_CTL; +		rq.ocf    = OCF_REMOTE_NAME_REQ; +		rq.cparam = &cp; +		rq.clen   = REMOTE_NAME_REQ_CP_SIZE; +		rq.rparam = &rp; +		rq.rlen   = EVT_CMD_STATUS_SIZE; +		rq.event  = EVT_CMD_STATUS; + +		if (hci_send_req(dd, &rq, 100) < 0) { +			syslog(LOG_ERR, "Unable to send remote name request: %s (%d)", +						strerror(errno), errno); +			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno); +			goto failed; +		} + +		if (rp.status) { +			syslog(LOG_ERR, "Remote name request failed"); +			reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET | rp.status); +			goto failed; +		} +	} + +	reply = dbus_message_new_method_return(msg); +failed: +	if (dd >= 0) +		hci_close_dev(dd); + +	return reply; +} + +static DBusMessage* handle_dev_remote_version_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_create_bonding_req(DBusMessage *msg, void *data) +{ +	struct hci_request rq; +	auth_requested_cp cp; +	evt_cmd_status rp; +	DBusMessage *reply = NULL; +	char *str_bdaddr = NULL; +	struct hci_dbus_data *dbus_data = data; +	struct hci_conn_info_req *cr = NULL; +	bdaddr_t bdaddr; +	int dev_id = -1; +	int dd = -1; + +	dbus_message_get_args(msg, NULL, +					DBUS_TYPE_STRING, &str_bdaddr, +					DBUS_TYPE_INVALID); + +	str2ba(str_bdaddr, &bdaddr); + +	dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + +	if (dev_id < 0) { +		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); +		goto failed; +	} + +	if (dbus_data->dev_id != dev_id) { +		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); +		goto failed; +	} + +	dd = hci_open_dev(dev_id); +	if (dd < 0) { +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); +		goto failed; +	} + +	cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); +	if (!cr) { +		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); +		goto failed; +	} + +	bacpy(&cr->bdaddr, &bdaddr); +	cr->type = ACL_LINK; + +	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	memset(&cp, 0, sizeof(cp)); +	cp.handle = cr->conn_info->handle; + +	memset(&rq, 0, sizeof(rq)); +	rq.ogf    = OGF_LINK_CTL; +	rq.ocf    = OCF_AUTH_REQUESTED; +	rq.cparam = &cp; +	rq.clen   = AUTH_REQUESTED_CP_SIZE; +	rq.rparam = &rp; +	rq.rlen   = EVT_CMD_STATUS_SIZE; +	rq.event  = EVT_CMD_STATUS; + +	if (hci_send_req(dd, &rq, 100) < 0) { +		syslog(LOG_ERR, "Unable to send authentication request: %s (%d)", +							strerror(errno), errno); +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	reply = dbus_message_new_method_return(msg); + +failed: +	if (dd >= 0) +		close(dd); + +	if (cr) +		free(cr); + +	return reply; +} + +static DBusMessage* handle_dev_list_bondings_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_has_bonding_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_remove_bonding_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + + +static DBusMessage* handle_dev_pin_code_length_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static DBusMessage* handle_dev_encryption_key_size_req(DBusMessage *msg, void *data) +{ +	/*FIXME: */ +	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); +} + +static const struct service_data dev_services[] = { +	{ DEV_GET_ADDRESS,		handle_dev_get_address_req,		DEV_GET_ADDRESS_SIGNATURE		}, +	{ DEV_GET_ALIAS,		handle_dev_get_alias_req,		DEV_GET_ALIAS_SIGNATURE			}, +	{ DEV_GET_COMPANY,		handle_dev_get_company_req,		DEV_GET_COMPANY_SIGNATURE		}, +	{ DEV_GET_DISCOVERABLE_TO,	handle_dev_get_discoverable_to_req,	DEV_GET_DISCOVERABLE_TO_SIGNATURE	}, +	{ DEV_GET_FEATURES,		handle_dev_get_features_req,		DEV_GET_FEATURES_SIGNATURE		}, +	{ DEV_GET_MANUFACTURER,		handle_dev_get_manufacturer_req,	DEV_GET_MANUFACTURER_SIGNATURE		}, +	{ DEV_GET_MODE,			handle_dev_get_mode_req,		DEV_GET_MODE_SIGNATURE			}, +	{ DEV_GET_NAME,			handle_dev_get_name_req,		DEV_GET_NAME_SIGNATURE			}, +	{ DEV_GET_REVISION,		handle_dev_get_revision_req,		DEV_GET_REVISION_SIGNATURE		}, +	{ DEV_GET_VERSION,		handle_dev_get_version_req,		DEV_GET_VERSION_SIGNATURE		}, + +	{ DEV_IS_CONNECTABLE,		handle_dev_is_connectable_req,		DEV_IS_CONNECTABLE_SIGNATURE		}, +	{ DEV_IS_DISCOVERABLE,		handle_dev_is_discoverable_req,		DEV_IS_DISCOVERABLE_SIGNATURE		}, + +	{ DEV_SET_ALIAS,		handle_dev_set_alias_req,		DEV_SET_ALIAS_SIGNATURE			}, +	{ DEV_SET_CLASS,		handle_dev_set_class_req,		DEV_SET_CLASS_SIGNATURE			}, +	{ DEV_SET_DISCOVERABLE_TO,	handle_dev_set_discoverable_to_req,	DEV_SET_DISCOVERABLE_TO_SIGNATURE	}, +	{ DEV_SET_MODE,			handle_dev_set_mode_req,		DEV_SET_MODE_SIGNATURE			}, +	{ DEV_SET_NAME,			handle_dev_set_name_req,		DEV_SET_NAME_SIGNATURE			}, + +	{ DEV_DISCOVER,			handle_dev_discover_req,		DEV_DISCOVER_SIGNATURE			}, +	{ DEV_DISCOVER_CACHE,		handle_dev_discover_cache_req,		DEV_DISCOVER_CACHE_SIGNATURE		}, +	{ DEV_DISCOVER_CANCEL,		handle_dev_discover_cancel_req,		DEV_DISCOVER_CANCEL_SIGNATURE		}, +	{ DEV_DISCOVER_SERVICE,		handle_dev_discover_service_req,	DEV_DISCOVER_SERVICE_SIGNATURE		}, + +	{ DEV_LAST_SEEN,		handle_dev_last_seen_req,		DEV_LAST_SEEN_SIGNATURE			}, +	{ DEV_LAST_USED,		handle_dev_last_used_req,		DEV_LAST_USED_SIGNATURE			}, + +	{ DEV_REMOTE_ALIAS,		handle_dev_remote_alias_req,		DEV_REMOTE_ALIAS_SIGNATURE		}, +	{ DEV_REMOTE_NAME,		handle_dev_remote_name_req,		DEV_REMOTE_NAME_SIGNATURE		}, +	{ DEV_REMOTE_VERSION,		handle_dev_remote_version_req,		DEV_REMOTE_VERSION_SIGNATURE		}, + +	{ DEV_CREATE_BONDING,		handle_dev_create_bonding_req,		DEV_CREATE_BONDING_SIGNATURE		}, +	{ DEV_LIST_BONDINGS,		handle_dev_list_bondings_req,		DEV_LIST_BONDINGS_SIGNATURE		}, +	{ DEV_HAS_BONDING_NAME,		handle_dev_has_bonding_req,		DEV_HAS_BONDING_SIGNATURE		}, +	{ DEV_REMOVE_BONDING,		handle_dev_remove_bonding_req,		DEV_REMOVE_BONDING_SIGNATURE		}, + +	{ DEV_PIN_CODE_LENGTH,		handle_dev_pin_code_length_req,		DEV_PIN_CODE_LENGTH_SIGNATURE		}, +	{ DEV_ENCRYPTION_KEY_SIZE,	handle_dev_encryption_key_size_req,	DEV_ENCRYPTION_KEY_SIZE_SIGNATURE	}, + +	{ NULL, NULL, NULL} +}; + +DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data) +{ +	const struct service_data *handlers = dev_services; +	DBusMessage *reply = NULL; +	struct hci_dbus_data *dbus_data = data; +	const char *method; +	const char *signature; +	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; +	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +	method = dbus_message_get_member(msg); +	signature = dbus_message_get_signature(msg); + +	syslog(LOG_INFO, "[%s,%d] path:%s, method:%s", __PRETTY_FUNCTION__, __LINE__, dbus_message_get_path(msg), method); + +	if (dbus_data->path_id == DEVICE_ROOT_ID) { +		/* Device is down(path unregistered) or the path is wrong */ +		ret = DBUS_HANDLER_RESULT_HANDLED; +		error = BLUEZ_EDBUS_UNKNOWN_PATH; +		goto failed; +	} + +	/* It's a device path id */ +	for (; handlers->name != NULL; handlers++) { +		if (strcmp(handlers->name, method)) +			continue; + +		ret = DBUS_HANDLER_RESULT_HANDLED; + +		if (!strcmp(handlers->signature, signature)) { +			reply = handlers->handler_func(msg, data); +			error = 0; +			break; +		} else { +			/* Set the error, but continue looping incase there is +			 * another method with the same name but a different +			 * signature */ +			error = BLUEZ_EDBUS_WRONG_SIGNATURE; +			continue; +		} +	} + +failed: +	if (error) +		reply = bluez_new_failure_msg(msg, error); + +	if (reply) { +		if (!dbus_connection_send (conn, reply, NULL)) +			syslog(LOG_ERR, "Can't send reply message!"); +		dbus_message_unref(reply); +	} + +	return ret; +} diff --git a/hcid/dbus-error.c b/hcid/dbus-error.c new file mode 100644 index 00000000..df8913ad --- /dev/null +++ b/hcid/dbus-error.c @@ -0,0 +1,158 @@ +/* + * + *  BlueZ - Bluetooth protocol stack for Linux + * + *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org> + * + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, write to the Free Software + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> + +#include <dbus/dbus.h> + +#include "hcid.h" +#include "dbus.h" + +typedef struct  { +	uint32_t code; +	const char *str; +} bluez_error_t; + +static const bluez_error_t dbus_error_array[] = { +	{ BLUEZ_EDBUS_UNKNOWN_METHOD,	"Method not found"		}, +	{ BLUEZ_EDBUS_WRONG_SIGNATURE,	"Wrong method signature"	}, +	{ BLUEZ_EDBUS_WRONG_PARAM,	"Invalid parameters"		}, +	{ BLUEZ_EDBUS_RECORD_NOT_FOUND,	"No record found"		}, +	{ BLUEZ_EDBUS_NO_MEM,		"No memory"			}, +	{ BLUEZ_EDBUS_CONN_NOT_FOUND,	"Connection not found"		}, +	{ BLUEZ_EDBUS_UNKNOWN_PATH,	"Unknown D-BUS path"		}, +	{ BLUEZ_EDBUS_NOT_IMPLEMENTED,	"Method not implemented"	}, +	{ 0, NULL } +}; + +static const bluez_error_t hci_error_array[] = { +	{ HCI_UNKNOWN_COMMAND,			"Unknown HCI Command"						}, +	{ HCI_NO_CONNECTION,			"Unknown Connection Identifier"					}, +	{ HCI_HARDWARE_FAILURE,			"Hardware Failure"						}, +	{ HCI_PAGE_TIMEOUT,			"Page Timeout"							}, +	{ HCI_AUTHENTICATION_FAILURE,		"Authentication Failure"					}, +	{ HCI_PIN_OR_KEY_MISSING,		"PIN Missing"							}, +	{ HCI_MEMORY_FULL,			"Memory Capacity Exceeded"					}, +	{ HCI_CONNECTION_TIMEOUT,		"Connection Timeout"						}, +	{ HCI_MAX_NUMBER_OF_CONNECTIONS,	"Connection Limit Exceeded"					}, +	{ HCI_MAX_NUMBER_OF_SCO_CONNECTIONS,	"Synchronous Connection Limit To A Device Exceeded"		}, +	{ HCI_ACL_CONNECTION_EXISTS,		"ACL Connection Already Exists"					}, +	{ HCI_COMMAND_DISALLOWED,		"Command Disallowed"						}, +	{ HCI_REJECTED_LIMITED_RESOURCES,	"Connection Rejected due to Limited Resources"			}, +	{ HCI_REJECTED_SECURITY,		"Connection Rejected Due To Security Reasons"			}, +	{ HCI_REJECTED_PERSONAL,		"Connection Rejected due to Unacceptable BD_ADDR"		}, +	{ HCI_HOST_TIMEOUT,			"Connection Accept Timeout Exceeded"				}, +	{ HCI_UNSUPPORTED_FEATURE,		"Unsupported Feature or Parameter Value"			}, +	{ HCI_INVALID_PARAMETERS,		"Invalid HCI Command Parameters"				}, +	{ HCI_OE_USER_ENDED_CONNECTION,		"Remote User Terminated Connection"				}, +	{ HCI_OE_LOW_RESOURCES,			"Remote Device Terminated Connection due to Low Resources"	}, +	{ HCI_OE_POWER_OFF,			"Remote Device Terminated Connection due to Power Off"		}, +	{ HCI_CONNECTION_TERMINATED,		"Connection Terminated By Local Host"				}, +	{ HCI_REPEATED_ATTEMPTS,		"Repeated Attempts"						}, +	{ HCI_PAIRING_NOT_ALLOWED,		"Pairing Not Allowed"						}, +	{ HCI_UNKNOWN_LMP_PDU,			"Unknown LMP PDU"						}, +	{ HCI_UNSUPPORTED_REMOTE_FEATURE,	"Unsupported Remote Feature"					}, +	{ HCI_SCO_OFFSET_REJECTED,		"SCO Offset Rejected"						}, +	{ HCI_SCO_INTERVAL_REJECTED,		"SCO Interval Rejected"						}, +	{ HCI_AIR_MODE_REJECTED,		"SCO Air Mode Rejected"						}, +	{ HCI_INVALID_LMP_PARAMETERS,		"Invalid LMP Parameters"					}, +	{ HCI_UNSPECIFIED_ERROR,		"Unspecified Error"						}, +	{ HCI_UNSUPPORTED_LMP_PARAMETER_VALUE,	"Unsupported LMP Parameter Value"				}, +	{ HCI_ROLE_CHANGE_NOT_ALLOWED,		"Role Change Not Allowed"					}, +	{ HCI_LMP_RESPONSE_TIMEOUT,		"LMP Response Timeout"						}, +	{ HCI_LMP_ERROR_TRANSACTION_COLLISION,	"LMP Error Transaction Collision"				}, +	{ HCI_LMP_PDU_NOT_ALLOWED,		"LMP PDU Not Allowed"						}, +	{ HCI_ENCRYPTION_MODE_NOT_ACCEPTED,	"Encryption Mode Not Acceptable"				}, +	{ HCI_UNIT_LINK_KEY_USED,		"Link Key Can Not be Changed"					}, +	{ HCI_QOS_NOT_SUPPORTED,		"Requested QoS Not Supported"					}, +	{ HCI_INSTANT_PASSED,			"Instant Passed"						}, +	{ HCI_PAIRING_NOT_SUPPORTED,		"Pairing With Unit Key Not Supported"				}, +	{ HCI_TRANSACTION_COLLISION,		"Different Transaction Collision"				}, +	{ HCI_QOS_UNACCEPTABLE_PARAMETER,	"QoS Unacceptable Parameter"					}, +	{ HCI_QOS_REJECTED,			"QoS Rejected"							}, +	{ HCI_CLASSIFICATION_NOT_SUPPORTED,	"Channel Classification Not Supported"				}, +	{ HCI_INSUFFICIENT_SECURITY,		"Insufficient Security"						}, +	{ HCI_PARAMETER_OUT_OF_RANGE,		"Parameter Out Of Mandatory Range"				}, +	{ HCI_ROLE_SWITCH_PENDING,		"Role Switch Pending"						}, +	{ HCI_SLOT_VIOLATION,			"Reserved Slot Violation"					}, +	{ HCI_ROLE_SWITCH_FAILED,		"Role Switch Failed"						}, +	{ 0, NULL }, +}; + +static const char *bluez_dbus_error_to_str(const uint32_t ecode)  +{ +	const bluez_error_t *ptr; +	uint32_t raw_code = 0; + +	if (ecode & BLUEZ_ESYSTEM_OFFSET) { +		/* System error */ +		raw_code = (~BLUEZ_ESYSTEM_OFFSET) & ecode; +		syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code)); +		return strerror(raw_code); +	} else if (ecode & BLUEZ_EDBUS_OFFSET) { +		/* D-Bus error */ +		for (ptr = dbus_error_array; ptr->code; ptr++) { +			if (ptr->code == ecode) { +				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); +				return ptr->str; +			} +		} +	} else { +		/* BLUEZ_EBT_OFFSET - Bluetooth HCI errors */ +		for (ptr = hci_error_array; ptr->code; ptr++) { +			if (ptr->code == ecode) { +				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); +				return ptr->str; +			} +		} +	} + +	return NULL; +} + +DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode) +{ +	DBusMessageIter iter; +	DBusMessage *reply; +	const char *error_msg; + +	error_msg = bluez_dbus_error_to_str(ecode); +	if (!error_msg) +		return NULL; + +	reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg); + +	dbus_message_iter_init_append(reply, &iter); +	dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode); + +	return reply; +} diff --git a/hcid/dbus-manager.c b/hcid/dbus-manager.c new file mode 100644 index 00000000..dfb00022 --- /dev/null +++ b/hcid/dbus-manager.c @@ -0,0 +1,183 @@ +/* + * + *  BlueZ - Bluetooth protocol stack for Linux + * + *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org> + * + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, write to the Free Software + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h> + +#include <dbus/dbus.h> + +#include "hcid.h" +#include "dbus.h" + +static DBusMessage* handle_mgr_device_list_req(DBusMessage *msg, void *data) +{ +	DBusMessageIter iter; +	DBusMessageIter array_iter; +	DBusMessage *reply; +	struct hci_dev_list_req *dl; +	struct hci_dev_req *dr; +	int i, sk = -1; + +	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); +	if (sk < 0) { +		syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); +		return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +	} + +	dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); +	if (!dl) { +		syslog(LOG_ERR, "Can't allocate memory"); +		close(sk); +		return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); +	} + +	dl->dev_num = HCI_MAX_DEV; +	dr = dl->dev_req; + +	if (ioctl(sk, HCIGETDEVLIST, dl) < 0) { +		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); +		goto failed; +	} + +	dr = dl->dev_req; + +	reply = dbus_message_new_method_return(msg); +	if (reply == NULL) { +		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); +		goto failed; +	} + +	dbus_message_iter_init_append(reply, &iter); + +	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, +				DBUS_TYPE_STRING_AS_STRING, &array_iter); + +	for (i = 0; i < dl->dev_num; i++, dr++) { +		char path[MAX_PATH_LENGTH], *path_ptr = path; +		struct hci_dev_info di; + +		memset(&di, 0 , sizeof(struct hci_dev_info)); +		di.dev_id = dr->dev_id; + +		if (ioctl(sk, HCIGETDEVINFO, &di) < 0) +			continue; + +		snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, di.name); + +		dbus_message_iter_append_basic(&array_iter, +						DBUS_TYPE_STRING, &path_ptr); +	} + +	dbus_message_iter_close_container(&iter, &array_iter); + +failed: +	free(dl); + +	close(sk); + +	return reply; +} + +static DBusMessage* handle_mgr_default_device_req(DBusMessage *msg, void *data) +{ +	DBusMessage *reply; +	char path[MAX_PATH_LENGTH], *path_ptr = path; +	int default_dev = get_default_dev_id(); + +	if (default_dev < 0) +		return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + +	reply = dbus_message_new_method_return(msg); +	if (!reply) { +		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); +		return reply; +	} + +	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, default_dev); + +	dbus_message_append_args(reply, DBUS_TYPE_STRING, &path_ptr, +					DBUS_TYPE_INVALID); + +	return reply; +} + +static const struct service_data mgr_services[] = { +	{ MGR_DEVICE_LIST,	handle_mgr_device_list_req,		MGR_DEVICE_LIST_SIGNATURE	}, +	{ MGR_DEFAULT_DEVICE,	handle_mgr_default_device_req,		MGR_DEFAULT_DEVICE_SIGNATURE	}, +	{ NULL, NULL, NULL } +}; + +DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data) +{ +	const struct service_data *handlers; +	DBusMessage *reply = NULL; +	const char *iface; +	const char *method; +	const char *signature; +	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; +	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +	iface = dbus_message_get_interface(msg); +	method = dbus_message_get_member(msg); +	signature = dbus_message_get_signature(msg); + +	syslog(LOG_INFO, "[%s,%d] path:%s, method:%s", __PRETTY_FUNCTION__, __LINE__, dbus_message_get_path(msg), method); + +	if (strcmp(iface, MANAGER_INTERFACE) != 0) +		return ret; + +	for (handlers = mgr_services; handlers->name != NULL; handlers++) { +		if (strcmp(handlers->name, method)) +			continue; + +		if (strcmp(handlers->signature, signature) != 0) +			error = BLUEZ_EDBUS_WRONG_SIGNATURE; +		else { +			reply = handlers->handler_func(msg, data); +			error = 0; +		} + +		ret = DBUS_HANDLER_RESULT_HANDLED; +	} + +	if (error) +		reply = bluez_new_failure_msg(msg, error); + +	if (reply) { +		if (!dbus_connection_send (conn, reply, NULL)) +			syslog(LOG_ERR, "Can't send reply message!"); +		dbus_message_unref(reply); +	} + +	return ret; +} diff --git a/hcid/dbus.c b/hcid/dbus.c index f123a993..fadc98d8 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -45,7 +45,6 @@  #include "hcid.h"  #include "dbus.h" -#include "textfile.h"  #ifndef DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT  #define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT	0x00 @@ -56,7 +55,6 @@ static int default_dev = -1;  #define TIMEOUT				(30 * 1000)		/* 30 seconds */  #define DBUS_RECONNECT_TIMER		(5 * 1000 * 1000)	/* 5 sec */ -#define MAX_PATH_LENGTH			64  #define MAX_CONN_NUMBER			10  #define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" @@ -69,35 +67,14 @@ struct pin_request {  	bdaddr_t bda;  }; -typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *); - -struct service_data { -	const char		*name; -	service_handler_func_t	*handler_func; -	const char		*signature; -}; - -struct hci_dbus_data { -	uint16_t dev_id; -	uint16_t path_id; -	uint32_t path_data; -}; - -typedef int register_function_t(DBusConnection *conn, uint16_t id); -typedef int unregister_function_t(DBusConnection *conn, uint16_t id); - -/* - * Utility functions - */ -static char *get_peer_name(const bdaddr_t *local, const bdaddr_t *peer) +DBusConnection *get_dbus_connection(void)  { -	char filename[PATH_MAX + 1], addr[18]; - -	ba2str(local, addr); -	snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); +	return connection; +} -	ba2str(peer, addr); -	return textfile_get(filename, addr); +int get_default_dev_id(void) +{ +	return default_dev;  }  static int8_t dev_append_signal_args(DBusMessage *signal, int first, va_list var_args) @@ -126,7 +103,7 @@ failed:  	return retval;  } -static DBusMessage *dev_signal_factory(const int devid, const char *prop_name, const int first, ...) +DBusMessage *dev_signal_factory(const int devid, const char *prop_name, const int first, ...)  {  	DBusMessage *signal = NULL;  	char path[MAX_PATH_LENGTH]; @@ -152,137 +129,8 @@ static DBusMessage *dev_signal_factory(const int devid, const char *prop_name, c  }  /* - * D-Bus error messages functions and declarations. - * This section should be moved to a common file  - * in the future - * - */ - -typedef struct  { -	uint32_t code; -	const char *str; -} bluez_error_t; - -static const bluez_error_t dbus_error_array[] = { -	{ BLUEZ_EDBUS_UNKNOWN_METHOD,	"Method not found"		}, -	{ BLUEZ_EDBUS_WRONG_SIGNATURE,	"Wrong method signature"	}, -	{ BLUEZ_EDBUS_WRONG_PARAM,	"Invalid parameters"		}, -	{ BLUEZ_EDBUS_RECORD_NOT_FOUND,	"No record found"		}, -	{ BLUEZ_EDBUS_NO_MEM,		"No memory"			}, -	{ BLUEZ_EDBUS_CONN_NOT_FOUND,	"Connection not found"		}, -	{ BLUEZ_EDBUS_UNKNOWN_PATH,	"Unknown D-BUS path"		}, -	{ BLUEZ_EDBUS_NOT_IMPLEMENTED,	"Method not implemented"	}, -	{ 0, NULL } -}; - -static const bluez_error_t hci_error_array[] = { -	{ HCI_UNKNOWN_COMMAND,			"Unknown HCI Command"						}, -	{ HCI_NO_CONNECTION,			"Unknown Connection Identifier"					}, -	{ HCI_HARDWARE_FAILURE,			"Hardware Failure"						}, -	{ HCI_PAGE_TIMEOUT,			"Page Timeout"							}, -	{ HCI_AUTHENTICATION_FAILURE,		"Authentication Failure"					}, -	{ HCI_PIN_OR_KEY_MISSING,		"PIN Missing"							}, -	{ HCI_MEMORY_FULL,			"Memory Capacity Exceeded"					}, -	{ HCI_CONNECTION_TIMEOUT,		"Connection Timeout"						}, -	{ HCI_MAX_NUMBER_OF_CONNECTIONS,	"Connection Limit Exceeded"					}, -	{ HCI_MAX_NUMBER_OF_SCO_CONNECTIONS,	"Synchronous Connection Limit To A Device Exceeded"		}, -	{ HCI_ACL_CONNECTION_EXISTS,		"ACL Connection Already Exists"					}, -	{ HCI_COMMAND_DISALLOWED,		"Command Disallowed"						}, -	{ HCI_REJECTED_LIMITED_RESOURCES,	"Connection Rejected due to Limited Resources"			}, -	{ HCI_REJECTED_SECURITY,		"Connection Rejected Due To Security Reasons"			}, -	{ HCI_REJECTED_PERSONAL,		"Connection Rejected due to Unacceptable BD_ADDR"		}, -	{ HCI_HOST_TIMEOUT,			"Connection Accept Timeout Exceeded"				}, -	{ HCI_UNSUPPORTED_FEATURE,		"Unsupported Feature or Parameter Value"			}, -	{ HCI_INVALID_PARAMETERS,		"Invalid HCI Command Parameters"				}, -	{ HCI_OE_USER_ENDED_CONNECTION,		"Remote User Terminated Connection"				}, -	{ HCI_OE_LOW_RESOURCES,			"Remote Device Terminated Connection due to Low Resources"	}, -	{ HCI_OE_POWER_OFF,			"Remote Device Terminated Connection due to Power Off"		}, -	{ HCI_CONNECTION_TERMINATED,		"Connection Terminated By Local Host"				}, -	{ HCI_REPEATED_ATTEMPTS,		"Repeated Attempts"						}, -	{ HCI_PAIRING_NOT_ALLOWED,		"Pairing Not Allowed"						}, -	{ HCI_UNKNOWN_LMP_PDU,			"Unknown LMP PDU"						}, -	{ HCI_UNSUPPORTED_REMOTE_FEATURE,	"Unsupported Remote Feature"					}, -	{ HCI_SCO_OFFSET_REJECTED,		"SCO Offset Rejected"						}, -	{ HCI_SCO_INTERVAL_REJECTED,		"SCO Interval Rejected"						}, -	{ HCI_AIR_MODE_REJECTED,		"SCO Air Mode Rejected"						}, -	{ HCI_INVALID_LMP_PARAMETERS,		"Invalid LMP Parameters"					}, -	{ HCI_UNSPECIFIED_ERROR,		"Unspecified Error"						}, -	{ HCI_UNSUPPORTED_LMP_PARAMETER_VALUE,	"Unsupported LMP Parameter Value"				}, -	{ HCI_ROLE_CHANGE_NOT_ALLOWED,		"Role Change Not Allowed"					}, -	{ HCI_LMP_RESPONSE_TIMEOUT,		"LMP Response Timeout"						}, -	{ HCI_LMP_ERROR_TRANSACTION_COLLISION,	"LMP Error Transaction Collision"				}, -	{ HCI_LMP_PDU_NOT_ALLOWED,		"LMP PDU Not Allowed"						}, -	{ HCI_ENCRYPTION_MODE_NOT_ACCEPTED,	"Encryption Mode Not Acceptable"				}, -	{ HCI_UNIT_LINK_KEY_USED,		"Link Key Can Not be Changed"					}, -	{ HCI_QOS_NOT_SUPPORTED,		"Requested QoS Not Supported"					}, -	{ HCI_INSTANT_PASSED,			"Instant Passed"						}, -	{ HCI_PAIRING_NOT_SUPPORTED,		"Pairing With Unit Key Not Supported"				}, -	{ HCI_TRANSACTION_COLLISION,		"Different Transaction Collision"				}, -	{ HCI_QOS_UNACCEPTABLE_PARAMETER,	"QoS Unacceptable Parameter"					}, -	{ HCI_QOS_REJECTED,			"QoS Rejected"							}, -	{ HCI_CLASSIFICATION_NOT_SUPPORTED,	"Channel Classification Not Supported"				}, -	{ HCI_INSUFFICIENT_SECURITY,		"Insufficient Security"						}, -	{ HCI_PARAMETER_OUT_OF_RANGE,		"Parameter Out Of Mandatory Range"				}, -	{ HCI_ROLE_SWITCH_PENDING,		"Role Switch Pending"						}, -	{ HCI_SLOT_VIOLATION,			"Reserved Slot Violation"					}, -	{ HCI_ROLE_SWITCH_FAILED,		"Role Switch Failed"						}, -	{ 0, NULL }, -}; - -static const char *bluez_dbus_error_to_str(const uint32_t ecode)  -{ -	const bluez_error_t *ptr; -	uint32_t raw_code = 0; - -	if (ecode & BLUEZ_ESYSTEM_OFFSET) { -		/* System error */ -		raw_code = (~BLUEZ_ESYSTEM_OFFSET) & ecode; -		syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code)); -		return strerror(raw_code); -	} else if (ecode & BLUEZ_EDBUS_OFFSET) { -		/* D-Bus error */ -		for (ptr = dbus_error_array; ptr->code; ptr++) { -			if (ptr->code == ecode) { -				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); -				return ptr->str; -			} -		} -	} else { -		/* BLUEZ_EBT_OFFSET - Bluetooth HCI errors */ -		for (ptr = hci_error_array; ptr->code; ptr++) { -			if (ptr->code == ecode) { -				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); -				return ptr->str; -			} -		} -	} - -	return NULL; -} - -static DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode) -{ -	DBusMessageIter iter; -	DBusMessage *reply; -	const char *error_msg; - -	error_msg = bluez_dbus_error_to_str(ecode); -	if (!error_msg) -		return NULL; - -	reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg); - -	dbus_message_iter_init_append(reply, &iter); -	dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode); - -	return reply; -} - -/*   * Virtual table that handle the object path hierarchy   */ -static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data); -static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data);  static const DBusObjectPathVTable obj_dev_vtable = {  	.message_function	= &msg_func_device, @@ -295,108 +143,6 @@ static const DBusObjectPathVTable obj_mgr_vtable = {  };  /* - * Services provided under the path DEVICE_PATH - */ - -static DBusMessage* handle_dev_get_address_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_alias_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_company_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_discoverable_to_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_features_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_manufacturer_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_mode_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_name_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_get_revision_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_get_version_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_is_connectable_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_is_discoverable_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_set_alias_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_class_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_discoverable_to_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_mode_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_set_name_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_discover_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_discover_cache_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_discover_cancel_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_discover_service_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_last_seen_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_last_used_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_remote_alias_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_remote_name_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_remote_version_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_create_bonding_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_list_bondings_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_has_bonding_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_remove_bonding_req(DBusMessage *msg, void *data); - -static DBusMessage* handle_dev_pin_code_length_req(DBusMessage *msg, void *data); -static DBusMessage* handle_dev_encryption_key_size_req(DBusMessage *msg, void *data); - - -static const struct service_data dev_services[] = { -	{ DEV_GET_ADDRESS,		handle_dev_get_address_req,		DEV_GET_ADDRESS_SIGNATURE		}, -	{ DEV_GET_ALIAS,		handle_dev_get_alias_req,		DEV_GET_ALIAS_SIGNATURE			}, -	{ DEV_GET_COMPANY,		handle_dev_get_company_req,		DEV_GET_COMPANY_SIGNATURE		}, -	{ DEV_GET_DISCOVERABLE_TO,	handle_dev_get_discoverable_to_req,	DEV_GET_DISCOVERABLE_TO_SIGNATURE	}, -	{ DEV_GET_FEATURES,		handle_dev_get_features_req,		DEV_GET_FEATURES_SIGNATURE		}, -	{ DEV_GET_MANUFACTURER,		handle_dev_get_manufacturer_req,	DEV_GET_MANUFACTURER_SIGNATURE		}, -	{ DEV_GET_MODE,			handle_dev_get_mode_req,		DEV_GET_MODE_SIGNATURE			}, -	{ DEV_GET_NAME,			handle_dev_get_name_req,		DEV_GET_NAME_SIGNATURE			}, -	{ DEV_GET_REVISION,		handle_dev_get_revision_req,		DEV_GET_REVISION_SIGNATURE		}, -	{ DEV_GET_VERSION,		handle_dev_get_version_req,		DEV_GET_VERSION_SIGNATURE		}, - -	{ DEV_IS_CONNECTABLE,		handle_dev_is_connectable_req,		DEV_IS_CONNECTABLE_SIGNATURE		}, -	{ DEV_IS_DISCOVERABLE,		handle_dev_is_discoverable_req,		DEV_IS_DISCOVERABLE_SIGNATURE		}, - -	{ DEV_SET_ALIAS,		handle_dev_set_alias_req,		DEV_SET_ALIAS_SIGNATURE			}, -	{ DEV_SET_CLASS,		handle_dev_set_class_req,		DEV_SET_CLASS_SIGNATURE			}, -	{ DEV_SET_DISCOVERABLE_TO,	handle_dev_set_discoverable_to_req,	DEV_SET_DISCOVERABLE_TO_SIGNATURE	}, -	{ DEV_SET_MODE,			handle_dev_set_mode_req,		DEV_SET_MODE_SIGNATURE			}, -	{ DEV_SET_NAME,			handle_dev_set_name_req,		DEV_SET_NAME_SIGNATURE			}, - -	{ DEV_DISCOVER,			handle_dev_discover_req,		DEV_DISCOVER_SIGNATURE			}, -	{ DEV_DISCOVER_CACHE,		handle_dev_discover_cache_req,		DEV_DISCOVER_CACHE_SIGNATURE		}, -	{ DEV_DISCOVER_CANCEL,		handle_dev_discover_cancel_req,		DEV_DISCOVER_CANCEL_SIGNATURE		}, -	{ DEV_DISCOVER_SERVICE,		handle_dev_discover_service_req,	DEV_DISCOVER_SERVICE_SIGNATURE		}, - -	{ DEV_LAST_SEEN,		handle_dev_last_seen_req,		DEV_LAST_SEEN_SIGNATURE			}, -	{ DEV_LAST_USED,		handle_dev_last_used_req,		DEV_LAST_USED_SIGNATURE			}, - -	{ DEV_REMOTE_ALIAS,		handle_dev_remote_alias_req,		DEV_REMOTE_ALIAS_SIGNATURE		}, -	{ DEV_REMOTE_NAME,		handle_dev_remote_name_req,		DEV_REMOTE_NAME_SIGNATURE		}, -	{ DEV_REMOTE_VERSION,		handle_dev_remote_version_req,		DEV_REMOTE_VERSION_SIGNATURE		}, - -	{ DEV_CREATE_BONDING,		handle_dev_create_bonding_req,		DEV_CREATE_BONDING_SIGNATURE		}, -	{ DEV_LIST_BONDINGS,		handle_dev_list_bondings_req,		DEV_LIST_BONDINGS_SIGNATURE		}, -	{ DEV_HAS_BONDING_NAME,		handle_dev_has_bonding_req,		DEV_HAS_BONDING_SIGNATURE		}, -	{ DEV_REMOVE_BONDING,		handle_dev_remove_bonding_req,		DEV_REMOVE_BONDING_SIGNATURE		}, - -	{ DEV_PIN_CODE_LENGTH,		handle_dev_pin_code_length_req,		DEV_PIN_CODE_LENGTH_SIGNATURE		}, -	{ DEV_ENCRYPTION_KEY_SIZE,	handle_dev_encryption_key_size_req,	DEV_ENCRYPTION_KEY_SIZE_SIGNATURE	}, - -	{ NULL, NULL, NULL} -}; - -/* - * Services provided under the path MANAGER_PATH - */ -static DBusMessage* handle_mgr_device_list_req(DBusMessage *msg, void *data); -static DBusMessage* handle_mgr_default_device_req(DBusMessage *msg, void *data); - -static const struct service_data mgr_services[] = { -	{ MGR_DEVICE_LIST,	handle_mgr_device_list_req,		MGR_DEVICE_LIST_SIGNATURE	}, -	{ MGR_DEFAULT_DEVICE,	handle_mgr_default_device_req,		MGR_DEFAULT_DEVICE_SIGNATURE	}, -	{ NULL, NULL, NULL } -}; - -/*   * HCI D-Bus services   */  static DBusHandlerResult hci_dbus_signal_filter(DBusConnection *conn, DBusMessage *msg, void *data); @@ -734,7 +480,7 @@ failed:  	bt_free(peer_addr);  } -void hcid_dbus_discover_start(bdaddr_t *local) +void hcid_dbus_inquiry_start(bdaddr_t *local)  {  	DBusMessage *message = NULL;  	char path[MAX_PATH_LENGTH]; @@ -771,7 +517,7 @@ failed:  	bt_free(local_addr);  } -void hcid_dbus_discover_complete(bdaddr_t *local) +void hcid_dbus_inquiry_complete(bdaddr_t *local)  {  	DBusMessage *message = NULL;  	char path[MAX_PATH_LENGTH]; @@ -808,7 +554,7 @@ failed:  	bt_free(local_addr);  } -void hcid_dbus_discover_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi)  {  	DBusMessage *message = NULL;  	char path[MAX_PATH_LENGTH]; @@ -1164,7 +910,6 @@ failed:  	if (dl)  		free(dl); -  }  static void reconnect_timer_start(void) @@ -1225,780 +970,6 @@ static DBusHandlerResult hci_dbus_signal_filter (DBusConnection *conn, DBusMessa  	return ret;  } -static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data) -{ -	const struct service_data *handlers = dev_services; -	DBusMessage *reply = NULL; -	struct hci_dbus_data *dbus_data = data; -	const char *method; -	const char *signature; -	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; -	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - -	method = dbus_message_get_member(msg); -	signature = dbus_message_get_signature(msg); - -	syslog(LOG_INFO, "[%s,%d] path:%s, method:%s", __PRETTY_FUNCTION__, __LINE__, dbus_message_get_path(msg), method); -	        -	if (dbus_data->path_id == DEVICE_ROOT_ID) { -		/* Device is down(path unregistered) or the path is wrong */ -		ret = DBUS_HANDLER_RESULT_HANDLED; -		error = BLUEZ_EDBUS_UNKNOWN_PATH; -		goto failed; -	} - -	/* It's a device path id */ -	for (; handlers->name != NULL; handlers++) { -		if (strcmp(handlers->name, method)) -			continue; - -		ret = DBUS_HANDLER_RESULT_HANDLED; - -		if (!strcmp(handlers->signature, signature)) { -			reply = handlers->handler_func(msg, data); -			error = 0; -			break; -		} else { -			/* Set the error, but continue looping incase there is -			 * another method with the same name but a different -			 * signature */ -			error = BLUEZ_EDBUS_WRONG_SIGNATURE; -			continue; -		} -	} - -failed: -	if (error) -		reply = bluez_new_failure_msg(msg, error); - -	if (reply) { -		if (!dbus_connection_send (conn, reply, NULL)) -			syslog(LOG_ERR, "Can't send reply message!"); -		dbus_message_unref(reply); -	} - -	return ret; -} - -static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data) -{ -	const struct service_data *handlers; -	DBusMessage *reply = NULL; -	const char *iface; -	const char *method; -	const char *signature; -	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; -	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - -	iface = dbus_message_get_interface(msg); -	method = dbus_message_get_member(msg); -	signature = dbus_message_get_signature(msg); - -	syslog(LOG_INFO, "[%s,%d] path:%s, method:%s", __PRETTY_FUNCTION__, __LINE__, dbus_message_get_path(msg), method); - -	if (strcmp(iface, MANAGER_INTERFACE) != 0) -		return ret; - -	for (handlers = mgr_services; handlers->name != NULL; handlers++) { -		if (strcmp(handlers->name, method)) -			continue; - -		if (strcmp(handlers->signature, signature) != 0) -			error = BLUEZ_EDBUS_WRONG_SIGNATURE; -		else { -			reply = handlers->handler_func(msg, data); -			error = 0; -		} - -		ret = DBUS_HANDLER_RESULT_HANDLED; -	} - -	if (error) -		reply = bluez_new_failure_msg(msg, error); - -	if (reply) { -		if (!dbus_connection_send (conn, reply, NULL)) -			syslog(LOG_ERR, "Can't send reply message!"); -		dbus_message_unref(reply); -	} - -	return ret; -} - -/***************************************************************** - * - *  Section reserved to device D-Bus services implementation - * - *****************************************************************/ - -static DBusMessage* handle_dev_get_address_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply; -	char str[18], *str_ptr = str; - -	get_device_address(dbus_data->dev_id, str, sizeof(str)); - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_get_version_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply; -	char str[20], *str_ptr = str; - -	get_device_version(dbus_data->dev_id, str, sizeof(str)); - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_get_revision_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply; -	char str[20], *str_ptr = str; - -	get_device_revision(dbus_data->dev_id, str, sizeof(str)); - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_get_manufacturer_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply; -	char str[64], *str_ptr = str; - -	get_device_manufacturer(dbus_data->dev_id, str, sizeof(str)); - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_get_company_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply; -	char str[64], *str_ptr = str; - -	get_device_company(dbus_data->dev_id, str, sizeof(str)); - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_get_features_req(DBusMessage *msg, void *data) -{ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_get_name_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply; -	char str[249], *str_ptr = str; - -	get_device_name(dbus_data->dev_id, str, sizeof(str)); - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_set_name_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessageIter iter; -	DBusMessage *reply; -	char *str_ptr; - -	dbus_message_iter_init(msg, &iter); -	dbus_message_iter_get_basic(&iter, &str_ptr); - -	if (strlen(str_ptr) == 0) { -		syslog(LOG_ERR, "Name change failed: Invalid parameter"); -		return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); -	} - -	set_device_name(dbus_data->dev_id, str_ptr); - -	reply = dbus_message_new_method_return(msg); - -	return reply; -} - -static DBusMessage* handle_dev_get_alias_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessageIter iter; -	DBusMessage *reply; -	char str[249], *str_ptr = str, *addr_ptr; -	bdaddr_t bdaddr; - -	dbus_message_iter_init(msg, &iter); -	dbus_message_iter_get_basic(&iter, &addr_ptr); - -	str2ba(addr_ptr, &bdaddr); - -	get_device_alias(dbus_data->dev_id, &bdaddr, str, sizeof(str)); - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_set_alias_req(DBusMessage *msg, void *data) -{ -	struct hci_dbus_data *dbus_data = data; -	DBusMessageIter iter; -	DBusMessage *reply, *signal; -	char *str_ptr, *addr_ptr; -	bdaddr_t bdaddr; - -	dbus_message_iter_init(msg, &iter); -	dbus_message_iter_get_basic(&iter, &addr_ptr); -	dbus_message_iter_next(&iter); -	dbus_message_iter_get_basic(&iter, &str_ptr); - -	if (strlen(str_ptr) == 0) { -		syslog(LOG_ERR, "Alias change failed: Invalid parameter"); -		return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); -	} - -	str2ba(addr_ptr, &bdaddr); - -	set_device_alias(dbus_data->dev_id, &bdaddr, str_ptr); - -	signal = dev_signal_factory(dbus_data->dev_id, "AliasChanged", -						DBUS_TYPE_STRING, &addr_ptr, -						DBUS_TYPE_STRING, &str_ptr, -						DBUS_TYPE_INVALID); -	if (signal) { -		dbus_connection_send(connection, signal, NULL); -		dbus_connection_flush(connection); -		dbus_message_unref(signal); -	} - -	signal = dev_signal_factory(dbus_data->dev_id, "RemoteAlias", -						DBUS_TYPE_STRING, &addr_ptr, -						DBUS_TYPE_STRING, &str_ptr, -						DBUS_TYPE_INVALID); -	if (signal) { -		dbus_connection_send(connection, signal, NULL); -		dbus_connection_flush(connection); -		dbus_message_unref(signal); -	} - -	reply = dbus_message_new_method_return(msg); - -	return reply; -} - -static DBusMessage* handle_dev_get_discoverable_to_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_get_mode_req(DBusMessage *msg, void *data) -{ -	const struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply = NULL; -	const uint8_t hci_mode = dbus_data->path_data; -	uint8_t scan_mode; - -	switch (hci_mode) { -	case SCAN_DISABLED: -		scan_mode = MODE_OFF; -		break; -	case SCAN_PAGE: -		scan_mode = MODE_CONNECTABLE; -		break; -	case (SCAN_PAGE | SCAN_INQUIRY): -		scan_mode = MODE_DISCOVERABLE; -		break; -	case SCAN_INQUIRY: -	/* inquiry scan mode is not handled, return 0xff */ -	default: -		/* reserved */ -		scan_mode = 0xff; -	} - -	reply = dbus_message_new_method_return(msg); - -	dbus_message_append_args(reply, -					DBUS_TYPE_BYTE, &scan_mode, -					DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage* handle_dev_is_connectable_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_is_discoverable_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_set_class_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_set_discoverable_to_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_set_mode_req(DBusMessage *msg, void *data) -{ -	const struct hci_dbus_data *dbus_data = data; -	DBusMessage *reply = NULL; -	struct hci_request rq; -	int dd = -1; -	const uint8_t scan_mode; -	uint8_t hci_mode; -	uint8_t status = 0; -	const uint8_t current_mode = dbus_data->path_data; - -	dbus_message_get_args(msg, NULL, -					DBUS_TYPE_BYTE, &scan_mode, -					DBUS_TYPE_INVALID); - -	switch (scan_mode) { -	case MODE_OFF: -		hci_mode = SCAN_DISABLED; -		break; -	case MODE_CONNECTABLE: -		hci_mode = SCAN_PAGE; -		break; -	case MODE_DISCOVERABLE: -		hci_mode = (SCAN_PAGE | SCAN_INQUIRY); -		break; -	default: -		/* invalid mode */ -		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); -		goto failed; -	} - -	dd = hci_open_dev(dbus_data->dev_id); -	if (dd < 0) { -		syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id); -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); -		goto failed; -	} - -	/* Check if the new requested mode is different from the current */ -	if (current_mode != hci_mode) { -		memset(&rq, 0, sizeof(rq)); -		rq.ogf    = OGF_HOST_CTL; -		rq.ocf    = OCF_WRITE_SCAN_ENABLE; -		rq.cparam = &hci_mode; -		rq.clen   = sizeof(hci_mode); -		rq.rparam = &status; -		rq.rlen   = sizeof(status); - -		if (hci_send_req(dd, &rq, 100) < 0) { -			syslog(LOG_ERR, "Sending write scan enable command failed: %s (%d)", -							strerror(errno), errno); -			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno); -			goto failed; -		} -		if (status) { -			syslog(LOG_ERR, "Setting scan enable failed with status 0x%02x", status); -			reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET | status); -			goto failed; -		} - -	} - -	reply = dbus_message_new_method_return(msg); - -failed: -	if (dd >= 0) -		close(dd); - -	return reply; -} - -static DBusMessage* handle_dev_discover_req(DBusMessage *msg, void *data) -{ -	DBusMessage *reply = NULL; -	inquiry_cp cp; -	evt_cmd_status rp; -	struct hci_request rq; -	struct hci_dbus_data *dbus_data = data; -	int dd = -1; -	uint8_t length = 8, num_rsp = 0; -	uint32_t lap = 0x9e8b33; - -	dd = hci_open_dev(dbus_data->dev_id); -	if (dd < 0) { -		syslog(LOG_ERR, "Unable to open device %d: %s (%d)", -					dbus_data->dev_id, strerror(errno), errno); -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -		goto failed; -	} - -	memset(&cp, 0, sizeof(cp)); -	cp.lap[0]  = lap & 0xff; -	cp.lap[1]  = (lap >> 8) & 0xff; -	cp.lap[2]  = (lap >> 16) & 0xff; -	cp.length  = length; -	cp.num_rsp = num_rsp; - -	memset(&rq, 0, sizeof(rq)); -	rq.ogf    = OGF_LINK_CTL; -	rq.ocf    = OCF_INQUIRY; -	rq.cparam = &cp; -	rq.clen   = INQUIRY_CP_SIZE; -	rq.rparam = &rp; -	rq.rlen   = EVT_CMD_STATUS_SIZE; -	rq.event  = EVT_CMD_STATUS; - -	if (hci_send_req(dd, &rq, 100) < 0) { -		syslog(LOG_ERR, "Unable to start inquiry: %s (%d)", -							strerror(errno), errno); -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -		goto failed; -	} - -	reply = dbus_message_new_method_return(msg); - -failed: -	if (dd >= 0) -		hci_close_dev(dd); - -	return reply; - -} - -static DBusMessage* handle_dev_discover_cache_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_discover_cancel_req(DBusMessage *msg, void *data) -{ -	DBusMessage *reply = NULL; -	struct hci_request rq; -	struct hci_dbus_data *dbus_data = data; -	uint8_t status; -	int dd = -1; - -	dd = hci_open_dev(dbus_data->dev_id); -	if (dd < 0) { -		syslog(LOG_ERR, "Unable to open device %d: %s (%d)", -					dbus_data->dev_id, strerror(errno), errno); -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -		goto failed; -	} - -	memset(&rq, 0, sizeof(rq)); -	rq.ogf    = OGF_LINK_CTL; -	rq.ocf    = OCF_INQUIRY_CANCEL; -	rq.rparam = &status; -	rq.rlen   = sizeof(status); - -	if (hci_send_req(dd, &rq, 100) < 0) { -		syslog(LOG_ERR, "Sending cancel inquiry failed: %s (%d)", -							strerror(errno), errno); -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -		goto failed; -	} - -	if (status) { -		syslog(LOG_ERR, "Cancel inquiry failed with status 0x%02x", status); -		reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); -		goto failed; -	} - -	reply = dbus_message_new_method_return(msg); - -failed: -	if (dd >= 0) -		hci_close_dev(dd); - -	return reply; -} - -static DBusMessage* handle_dev_discover_service_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_last_seen_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_last_used_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_remote_alias_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_remote_name_req(DBusMessage *msg, void *data) -{ -	DBusMessage *reply = NULL; -	DBusMessage *signal = NULL; -	struct hci_dbus_data *dbus_data = data; -	const char *str_bdaddr; -	char *name; -	char path[MAX_PATH_LENGTH]; -	bdaddr_t bdaddr; -	struct hci_dev_info di; -	struct hci_request rq; -	remote_name_req_cp cp; -	evt_cmd_status rp; -	int dd = -1; - -	dbus_message_get_args(msg, NULL, -					DBUS_TYPE_STRING, &str_bdaddr, -					DBUS_TYPE_INVALID); - -	str2ba(str_bdaddr, &bdaddr); -	if (hci_devinfo(dbus_data->dev_id, &di) < 0) { -		syslog(LOG_ERR, "Can't get device info"); -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); -		goto failed; -	} - -	/* Try retrieve from local cache */ -	name = get_peer_name(&di.bdaddr, &bdaddr); -	if (name) { - -		reply = dbus_message_new_method_return(msg); - -		snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, dbus_data->dev_id); - -		signal = dbus_message_new_signal(path, DEVICE_INTERFACE, -							DEV_SIG_REMOTE_NAME); - -		dbus_message_append_args(signal, -						DBUS_TYPE_STRING, &str_bdaddr, -						DBUS_TYPE_STRING, &name, -						DBUS_TYPE_INVALID); - -		if (dbus_connection_send(connection, signal, NULL) == FALSE) { -			syslog(LOG_ERR, "Can't send D-BUS remote name signal message"); -			goto failed; -		} - -		dbus_message_unref(signal); -		free(name); - -	} else { - -		/* Send HCI command */ -		dd = hci_open_dev(dbus_data->dev_id); -		if (dd < 0) { -			syslog(LOG_ERR, "Unable to open device %d: %s (%d)", -						dbus_data->dev_id, strerror(errno), errno); -			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno); -			goto failed; -		} - -		memset(&cp, 0, sizeof(cp)); -		cp.bdaddr = bdaddr; -		cp.pscan_rep_mode = 0x02; - -		memset(&rq, 0, sizeof(rq)); -		rq.ogf    = OGF_LINK_CTL; -		rq.ocf    = OCF_REMOTE_NAME_REQ; -		rq.cparam = &cp; -		rq.clen   = REMOTE_NAME_REQ_CP_SIZE; -		rq.rparam = &rp; -		rq.rlen   = EVT_CMD_STATUS_SIZE; -		rq.event  = EVT_CMD_STATUS; - -		if (hci_send_req(dd, &rq, 100) < 0) { -			syslog(LOG_ERR, "Unable to send remote name request: %s (%d)", -						strerror(errno), errno); -			reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno); -			goto failed; -		} - -		if (rp.status) { -			syslog(LOG_ERR, "Remote name request failed"); -			reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET | rp.status); -			goto failed; -		} -	} - -	reply = dbus_message_new_method_return(msg); -failed: -	if (dd >= 0) -		hci_close_dev(dd); - -	return reply; -} - -static DBusMessage* handle_dev_remote_version_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_create_bonding_req(DBusMessage *msg, void *data) -{ -	struct hci_request rq; -	auth_requested_cp cp; -	evt_cmd_status rp; -	DBusMessage *reply = NULL; -	char *str_bdaddr = NULL; -	struct hci_dbus_data *dbus_data = data; -	struct hci_conn_info_req *cr = NULL; -	bdaddr_t bdaddr; -	int dev_id = -1; -	int dd = -1; - -	dbus_message_get_args(msg, NULL, -					DBUS_TYPE_STRING, &str_bdaddr, -					DBUS_TYPE_INVALID); - -	str2ba(str_bdaddr, &bdaddr); - -	dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); - -	if (dev_id < 0) { -		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); -		goto failed; -	} - -	if (dbus_data->dev_id != dev_id) { -		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); -		goto failed; -	} - -	dd = hci_open_dev(dev_id); -	if (dd < 0) { -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); -		goto failed; -	} - -	cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); -	if (!cr) { -		reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); -		goto failed; -	} - -	bacpy(&cr->bdaddr, &bdaddr); -	cr->type = ACL_LINK; - -	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -		goto failed; -	} - -	memset(&cp, 0, sizeof(cp)); -	cp.handle = cr->conn_info->handle; - -	memset(&rq, 0, sizeof(rq)); -	rq.ogf    = OGF_LINK_CTL; -	rq.ocf    = OCF_AUTH_REQUESTED; -	rq.cparam = &cp; -	rq.clen   = AUTH_REQUESTED_CP_SIZE; -	rq.rparam = &rp; -	rq.rlen   = EVT_CMD_STATUS_SIZE; -	rq.event  = EVT_CMD_STATUS; - -	if (hci_send_req(dd, &rq, 100) < 0) { -		syslog(LOG_ERR, "Unable to send authentication request: %s (%d)", -							strerror(errno), errno); -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -		goto failed; -	} - -	reply = dbus_message_new_method_return(msg); - -failed: -	if (dd >= 0) -		close(dd); - -	if (cr) -		free(cr); - -	return reply; -} - -static DBusMessage* handle_dev_list_bondings_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_has_bonding_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_remove_bonding_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - - -static DBusMessage* handle_dev_pin_code_length_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} - -static DBusMessage* handle_dev_encryption_key_size_req(DBusMessage *msg, void *data) -{ -	/*FIXME: */ -	return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); -} -  /*****************************************************************   *     *  Section reserved to device HCI callbacks @@ -2173,99 +1144,3 @@ failed:  	bt_free(local_addr);  } - -/***************************************************************** - *   - *  Section reserved to Manager D-Bus services implementation - *   - *****************************************************************/ -static DBusMessage* handle_mgr_device_list_req(DBusMessage *msg, void *data) -{ -	DBusMessageIter iter; -	DBusMessageIter array_iter; -	DBusMessage *reply; -	struct hci_dev_list_req *dl = NULL; -	struct hci_dev_req *dr      = NULL; -	int i, sk = -1; - -	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); -	if (sk < 0) { -		syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); -		return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -	} - -	dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); -	if (!dl) { -		syslog(LOG_ERR, "Can't allocate memory"); -		close(sk); -		return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); -	} - -	dl->dev_num = HCI_MAX_DEV; -	dr = dl->dev_req; - -	if (ioctl(sk, HCIGETDEVLIST, dl) < 0) { -		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); -		goto failed; -	} - -	dr = dl->dev_req; - -	reply = dbus_message_new_method_return(msg); -	if (reply == NULL) { -		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); -		goto failed; -	} - -	dbus_message_iter_init_append(reply, &iter); - -	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, -				DBUS_TYPE_STRING_AS_STRING, &array_iter); - -	for (i = 0; i < dl->dev_num; i++, dr++) { -		char path[MAX_PATH_LENGTH], *path_ptr = path; -		struct hci_dev_info di; - -		memset(&di, 0 , sizeof(struct hci_dev_info)); -		di.dev_id = dr->dev_id; - -		if (ioctl(sk, HCIGETDEVINFO, &di) < 0) -			continue; - -		snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, di.name); - -		dbus_message_iter_append_basic(&array_iter, -						DBUS_TYPE_STRING, &path_ptr); -	} - -	dbus_message_iter_close_container(&iter, &array_iter); - -failed: -	free(dl); - -	close(sk); - -	return reply; -} - -static DBusMessage* handle_mgr_default_device_req(DBusMessage *msg, void *data) -{ -	DBusMessage *reply; -	char path[MAX_PATH_LENGTH], *path_ptr = path; - -	if (default_dev < 0) -		return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) { -		syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); -		return reply; -	} - -	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, default_dev); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &path_ptr, -					DBUS_TYPE_INVALID); - -	return reply; -} diff --git a/hcid/dbus.h b/hcid/dbus.h index 668302c3..913733f7 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -52,6 +52,36 @@  #define INVALID_PATH_ID		0xFFFF  #define INVALID_DEV_ID		0xFFFF +#define MAX_PATH_LENGTH		64 + +typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *); + +struct service_data { +	const char		*name; +	service_handler_func_t	*handler_func; +	const char		*signature; +}; + +struct hci_dbus_data { +	uint16_t dev_id; +	uint16_t path_id; +	uint32_t path_data; +}; + +typedef int register_function_t(DBusConnection *conn, uint16_t id); +typedef int unregister_function_t(DBusConnection *conn, uint16_t id); + +DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data); +DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data); + +DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode); + +DBusMessage *dev_signal_factory(const int devid, const char *prop_name, const int first, ...); + +DBusConnection *get_dbus_connection(void); + +int get_default_dev_id(void); +  /*========================================================================       BlueZ D-Bus Manager service definitions "/org/bluez/Manager"   *========================================================================*/ diff --git a/hcid/hcid.h b/hcid/hcid.h index dc7d71e9..52e44f32 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -124,9 +124,9 @@ gboolean hcid_dbus_dev_up(uint16_t id);  gboolean hcid_dbus_dev_down(uint16_t id);  void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); -void hcid_dbus_discover_start(bdaddr_t *local); -void hcid_dbus_discover_complete(bdaddr_t *local); -void hcid_dbus_discover_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi); +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_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status);  void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer); diff --git a/hcid/security.c b/hcid/security.c index 36774f2b..58b049ed 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -389,7 +389,7 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr)  		return;  	if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) -		hcid_dbus_discover_start(sba); +		hcid_dbus_inquiry_start(sba);  }  static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) @@ -397,7 +397,7 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)  	evt_cmd_complete *evt = ptr;  	switch (evt->opcode) {  	case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): -		hcid_dbus_discover_complete(sba); +		hcid_dbus_inquiry_complete(sba);  		break;  	case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME):  		hcid_dbus_setname_complete(sba); @@ -442,7 +442,7 @@ static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr)  static inline void inquiry_complete(int dev, bdaddr_t *sba, void *ptr)  { -	hcid_dbus_discover_complete(sba); +	hcid_dbus_inquiry_complete(sba);  }  static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) @@ -456,7 +456,7 @@ static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr)  			| (info->dev_class[1] << 8)  			| (info->dev_class[2] << 16); -		hcid_dbus_discover_result(sba, &info->bdaddr, class, 0); +		hcid_dbus_inquiry_result(sba, &info->bdaddr, class, 0);  		update_lastseen(sba, &info->bdaddr); @@ -479,7 +479,7 @@ static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, vo  				| (info->dev_class[1] << 8)  				| (info->dev_class[2] << 16); -			hcid_dbus_discover_result(sba, &info->bdaddr, +			hcid_dbus_inquiry_result(sba, &info->bdaddr,  							class, info->rssi);  			update_lastseen(sba, &info->bdaddr); @@ -493,7 +493,7 @@ static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, vo  				| (info->dev_class[1] << 8)  				| (info->dev_class[2] << 16); -			hcid_dbus_discover_result(sba, &info->bdaddr, +			hcid_dbus_inquiry_result(sba, &info->bdaddr,  							class, info->rssi);  			update_lastseen(sba, &info->bdaddr); @@ -514,7 +514,7 @@ static inline void extended_inquiry_result(int dev, bdaddr_t *sba, int plen, voi  			| (info->dev_class[1] << 8)  			| (info->dev_class[2] << 16); -		hcid_dbus_discover_result(sba, &info->bdaddr, class, info->rssi); +		hcid_dbus_inquiry_result(sba, &info->bdaddr, class, info->rssi);  		update_lastseen(sba, &info->bdaddr);  | 
