summaryrefslogtreecommitdiffstats
path: root/hcid
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-02-12 05:49:17 +0000
committerMarcel Holtmann <marcel@holtmann.org>2006-02-12 05:49:17 +0000
commit47981636cf44293edb866e8565dcf812d2a3e8fb (patch)
tree6e341fff4e8b2e9f39f869d196e4af3808a2ab96 /hcid
parent96449478703013c0028864afc1ec544b6a098f65 (diff)
Split D-Bus services and errors into separate files
Diffstat (limited to 'hcid')
-rw-r--r--hcid/Makefile.am5
-rw-r--r--hcid/dbus-device.c822
-rw-r--r--hcid/dbus-error.c158
-rw-r--r--hcid/dbus-manager.c183
-rw-r--r--hcid/dbus.c1145
-rw-r--r--hcid/dbus.h30
-rw-r--r--hcid/hcid.h6
-rw-r--r--hcid/security.c14
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);