diff options
Diffstat (limited to 'hcid')
-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); |