summaryrefslogtreecommitdiffstats
path: root/hcid/dbus-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'hcid/dbus-device.c')
-rw-r--r--hcid/dbus-device.c932
1 files changed, 466 insertions, 466 deletions
diff --git a/hcid/dbus-device.c b/hcid/dbus-device.c
index 9310bd8a..c19b26d1 100644
--- a/hcid/dbus-device.c
+++ b/hcid/dbus-device.c
@@ -122,65 +122,6 @@ static DBusMessage *handle_dev_get_revision_req(DBusMessage *msg, void *data)
return reply;
}
-static DBusMessage *handle_dev_get_service_classes_req(DBusMessage *msg, void *data)
-{
- struct hci_dbus_data *dbus_data = data;
- DBusMessage *reply;
- DBusMessageIter iter;
- DBusMessageIter array_iter;
- const char *str_ptr;
- uint8_t cls[3];
- int dd, i;
-
- dd = hci_open_dev(dbus_data->dev_id);
- if (dd < 0) {
- syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id);
- return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
- }
-
- if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
- syslog(LOG_ERR, "Can't read class of device on hci%d: %s(%d)",
- dbus_data->dev_id, strerror(errno), errno);
- hci_close_dev(dd);
- return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno);
- }
-
- reply = dbus_message_new_method_return(msg);
-
- 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 < (sizeof(service_cls) / sizeof(*service_cls)); i++) {
- if (cls[2] & (1 << i)) {
- str_ptr = service_cls[i];
- dbus_message_iter_append_basic(&array_iter,
- DBUS_TYPE_STRING, &str_ptr);
- }
- }
-
- dbus_message_iter_close_container(&iter, &array_iter);
-
- hci_close_dev(dd);
-
- return reply;
-}
-
-static DBusMessage *handle_dev_get_major_class_req(DBusMessage *msg, void *data)
-{
- DBusMessage *reply;
- const char *str_ptr = "computer";
-
- reply = dbus_message_new_method_return(msg);
-
- /*FIXME: Check the real device major class */
- 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;
@@ -197,51 +138,6 @@ static DBusMessage *handle_dev_get_manufacturer_req(DBusMessage *msg, void *data
return reply;
}
-static DBusMessage *handle_dev_get_minor_class_req(DBusMessage *msg, void *data)
-{
- struct hci_dbus_data *dbus_data = data;
- DBusMessage *reply;
- const char *str_ptr = "";
- uint8_t cls[3];
- uint8_t minor_class;
- int dd;
-
- dd = hci_open_dev(dbus_data->dev_id);
- if (dd < 0) {
- syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id);
- return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
- }
-
- if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
- syslog(LOG_ERR, "Can't read class of device on hci%d: %s(%d)",
- dbus_data->dev_id, strerror(errno), errno);
- hci_close_dev(dd);
- return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno);
- }
-
- reply = dbus_message_new_method_return(msg);
-
- /* FIXME: Currently, only computer major class is supported */
- if ((cls[1] & 0x1f) != 1)
- goto failed;
-
- minor_class = cls[0] >> 2;
-
- /* Validate computer minor class */
- if (minor_class > (sizeof(computer_minor_cls) / sizeof(*computer_minor_cls)))
- goto failed;
-
- str_ptr = computer_minor_cls[minor_class];
-
-failed:
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
- DBUS_TYPE_INVALID);
-
- hci_close_dev(dd);
-
- return reply;
-}
-
static DBusMessage *handle_dev_get_company_req(DBusMessage *msg, void *data)
{
struct hci_dbus_data *dbus_data = data;
@@ -276,110 +172,101 @@ static DBusMessage *handle_dev_get_features_req(DBusMessage *msg, void *data)
return reply;
}
-static DBusMessage *handle_dev_get_name_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_get_mode_req(DBusMessage *msg, void *data)
{
- struct hci_dbus_data *dbus_data = data;
- DBusMessage *reply;
- char str[249], *str_ptr = str;
+ const struct hci_dbus_data *dbus_data = data;
+ DBusMessage *reply = NULL;
+ const uint8_t hci_mode = dbus_data->mode;
+ const char *scan_mode;
- get_device_name(dbus_data->dev_id, str, sizeof(str));
+ 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 unknown */
+ default:
+ /* reserved */
+ scan_mode = MODE_UNKNOWN;
+ }
reply = dbus_message_new_method_return(msg);
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &scan_mode,
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;
- bdaddr_t bdaddr;
- 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);
- }
-
- hci_devba(dbus_data->dev_id, &bdaddr);
-
- write_local_name(&bdaddr, str_ptr);
-
- set_device_name(dbus_data->dev_id, str_ptr);
-
- reply = dbus_message_new_method_return(msg);
-
- return reply;
-}
-
-static DBusMessage *handle_dev_get_remote_alias_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_set_mode_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;
- int err;
-
- dbus_message_iter_init(msg, &iter);
- dbus_message_iter_get_basic(&iter, &addr_ptr);
-
- str2ba(addr_ptr, &bdaddr);
-
- err = get_device_alias(dbus_data->dev_id, &bdaddr, str, sizeof(str));
- if (err < 0)
- return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | -err);
-
- reply = dbus_message_new_method_return(msg);
+ const struct hci_dbus_data *dbus_data = data;
+ DBusMessage *reply = NULL;
+ struct hci_request rq;
+ int dd = -1;
+ const char* scan_mode;
+ uint8_t hci_mode;
+ uint8_t status = 0;
+ const uint8_t current_mode = dbus_data->mode;
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
+ dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &scan_mode,
DBUS_TYPE_INVALID);
- return reply;
-}
-
-static DBusMessage *handle_dev_set_remote_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 (!scan_mode)
+ return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
- if (strlen(str_ptr) == 0) {
- syslog(LOG_ERR, "Alias change failed: Invalid parameter");
+ if (strcasecmp(MODE_OFF, scan_mode) == 0)
+ hci_mode = SCAN_DISABLED;
+ else if (strcasecmp(MODE_CONNECTABLE, scan_mode) == 0)
+ hci_mode = SCAN_PAGE;
+ else if (strcasecmp(MODE_DISCOVERABLE, scan_mode) == 0)
+ hci_mode = (SCAN_PAGE | SCAN_INQUIRY);
+ else
return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
+
+ dd = hci_open_dev(dbus_data->dev_id);
+ if (dd < 0) {
+ syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id);
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
}
- str2ba(addr_ptr, &bdaddr);
+ /* 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);
- set_device_alias(dbus_data->dev_id, &bdaddr, str_ptr);
+ 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;
+ }
- signal = dev_signal_factory(dbus_data->dev_id, DEV_SIG_REMOTE_ALIAS_CHANGED,
- 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);
+failed:
+ if (dd >= 0)
+ close(dd);
+
return reply;
}
@@ -396,34 +283,19 @@ static DBusMessage *handle_dev_get_discoverable_to_req(DBusMessage *msg, void *d
return reply;
}
-static DBusMessage *handle_dev_get_mode_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_set_discoverable_to_req(DBusMessage *msg, void *data)
{
- const struct hci_dbus_data *dbus_data = data;
+ struct hci_dbus_data *dbus_data = data;
DBusMessage *reply = NULL;
- const uint8_t hci_mode = dbus_data->mode;
- const char *scan_mode;
+ DBusMessageIter iter;
+ uint32_t timeout;
- 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 unknown */
- default:
- /* reserved */
- scan_mode = MODE_UNKNOWN;
- }
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_get_basic(&iter, &timeout);
- reply = dbus_message_new_method_return(msg);
+ dbus_data->discoverable_timeout = timeout;
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &scan_mode,
- DBUS_TYPE_INVALID);
+ reply = dbus_message_new_method_return(msg);
return reply;
}
@@ -464,20 +336,62 @@ static DBusMessage *handle_dev_is_discoverable_req(DBusMessage *msg, void *data)
return reply;
}
-static DBusMessage *handle_dev_set_discoverable_to_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_get_major_class_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ const char *str_ptr = "computer";
+
+ reply = dbus_message_new_method_return(msg);
+
+ /*FIXME: Check the real device major class */
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
+ DBUS_TYPE_INVALID);
+
+ return reply;
+}
+
+static DBusMessage *handle_dev_get_minor_class_req(DBusMessage *msg, void *data)
{
struct hci_dbus_data *dbus_data = data;
- DBusMessage *reply = NULL;
- DBusMessageIter iter;
- uint32_t timeout;
+ DBusMessage *reply;
+ const char *str_ptr = "";
+ uint8_t cls[3];
+ uint8_t minor_class;
+ int dd;
- dbus_message_iter_init(msg, &iter);
- dbus_message_iter_get_basic(&iter, &timeout);
+ dd = hci_open_dev(dbus_data->dev_id);
+ if (dd < 0) {
+ syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id);
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
+ }
- dbus_data->discoverable_timeout = timeout;
+ if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
+ syslog(LOG_ERR, "Can't read class of device on hci%d: %s(%d)",
+ dbus_data->dev_id, strerror(errno), errno);
+ hci_close_dev(dd);
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno);
+ }
reply = dbus_message_new_method_return(msg);
+ /* FIXME: Currently, only computer major class is supported */
+ if ((cls[1] & 0x1f) != 1)
+ goto failed;
+
+ minor_class = cls[0] >> 2;
+
+ /* Validate computer minor class */
+ if (minor_class > (sizeof(computer_minor_cls) / sizeof(*computer_minor_cls)))
+ goto failed;
+
+ str_ptr = computer_minor_cls[minor_class];
+
+failed:
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
+ DBUS_TYPE_INVALID);
+
+ hci_close_dev(dd);
+
return reply;
}
@@ -558,32 +472,15 @@ failed:
return reply;
}
-static DBusMessage *handle_dev_set_mode_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_get_service_classes_req(DBusMessage *msg, void *data)
{
- const struct hci_dbus_data *dbus_data = data;
- DBusMessage *reply = NULL;
- struct hci_request rq;
- int dd = -1;
- const char* scan_mode;
- uint8_t hci_mode;
- uint8_t status = 0;
- const uint8_t current_mode = dbus_data->mode;
-
- dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &scan_mode,
- DBUS_TYPE_INVALID);
-
- if (!scan_mode)
- return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
-
- if (strcasecmp(MODE_OFF, scan_mode) == 0)
- hci_mode = SCAN_DISABLED;
- else if (strcasecmp(MODE_CONNECTABLE, scan_mode) == 0)
- hci_mode = SCAN_PAGE;
- else if (strcasecmp(MODE_DISCOVERABLE, scan_mode) == 0)
- hci_mode = (SCAN_PAGE | SCAN_INQUIRY);
- else
- return bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM);
+ struct hci_dbus_data *dbus_data = data;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter array_iter;
+ const char *str_ptr;
+ uint8_t cls[3];
+ int dd, i;
dd = hci_open_dev(dbus_data->dev_id);
if (dd < 0) {
@@ -591,200 +488,118 @@ static DBusMessage *handle_dev_set_mode_req(DBusMessage *msg, void *data)
return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
}
- /* 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_read_class_of_dev(dd, cls, 1000) < 0) {
+ syslog(LOG_ERR, "Can't read class of device on hci%d: %s(%d)",
+ dbus_data->dev_id, strerror(errno), errno);
+ hci_close_dev(dd);
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | errno);
+ }
- 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);
+
+ 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 < (sizeof(service_cls) / sizeof(*service_cls)); i++) {
+ if (cls[2] & (1 << i)) {
+ str_ptr = service_cls[i];
+ dbus_message_iter_append_basic(&array_iter,
+ DBUS_TYPE_STRING, &str_ptr);
+ }
}
- reply = dbus_message_new_method_return(msg);
+ dbus_message_iter_close_container(&iter, &array_iter);
-failed:
- if (dd >= 0)
- close(dd);
+ hci_close_dev(dd);
return reply;
}
-static DBusMessage *handle_dev_discover_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_get_name_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;
+ DBusMessage *reply;
+ char str[249], *str_ptr = str;
- 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;
- }
+ get_device_name(dbus_data->dev_id, str, sizeof(str));
reply = dbus_message_new_method_return(msg);
-failed:
- if (dd >= 0)
- hci_close_dev(dd);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
+ DBUS_TYPE_INVALID);
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)
+static DBusMessage *handle_dev_set_name_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;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ bdaddr_t bdaddr;
+ char *str_ptr;
- 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;
+ 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);
}
- memset(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LINK_CTL;
- rq.ocf = OCF_INQUIRY_CANCEL;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
+ hci_devba(dbus_data->dev_id, &bdaddr);
- 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;
- }
+ write_local_name(&bdaddr, str_ptr);
- 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;
- }
+ set_device_name(dbus_data->dev_id, str_ptr);
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)
+static DBusMessage *handle_dev_get_remote_version_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)
+static DBusMessage *handle_dev_get_remote_revision_req(DBusMessage *msg, void *data)
{
- struct hci_dbus_data *dbus_data = data;
- DBusMessageIter iter;
- DBusMessage *reply;
- char filename[PATH_MAX + 1];
- char addr[18], *addr_ptr, *str;
-
- get_device_address(dbus_data->dev_id, addr, sizeof(addr));
-
- snprintf(filename, PATH_MAX, "%s/%s/lastseen", STORAGEDIR, addr);
-
- dbus_message_iter_init(msg, &iter);
- dbus_message_iter_get_basic(&iter, &addr_ptr);
-
- str = textfile_get(filename, addr_ptr);
- if (!str)
- return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | ENXIO);
-
- reply = dbus_message_new_method_return(msg);
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
- DBUS_TYPE_INVALID);
-
- free(str);
+ /*FIXME: */
+ return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED);
+}
- return reply;
+static DBusMessage *handle_dev_get_remote_manufacturer_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)
+static DBusMessage *handle_dev_get_remote_company_req(DBusMessage *msg, void *data)
{
- struct hci_dbus_data *dbus_data = data;
- DBusMessageIter iter;
DBusMessage *reply;
- char filename[PATH_MAX + 1];
- char addr[18], *addr_ptr, *str;
-
- get_device_address(dbus_data->dev_id, addr, sizeof(addr));
+ bdaddr_t bdaddr;
+ char oui[9], *str_bdaddr, *tmp;
- snprintf(filename, PATH_MAX, "%s/%s/lastused", STORAGEDIR, addr);
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str_bdaddr,
+ DBUS_TYPE_INVALID);
- dbus_message_iter_init(msg, &iter);
- dbus_message_iter_get_basic(&iter, &addr_ptr);
+ str2ba(str_bdaddr, &bdaddr);
+ ba2oui(&bdaddr, oui);
- str = textfile_get(filename, addr_ptr);
- if (!str)
- return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | ENXIO);
+ tmp = ouitocomp(oui);
+ if (!tmp)
+ return bluez_new_failure_msg(msg, BLUEZ_EDBUS_RECORD_NOT_FOUND);
reply = dbus_message_new_method_return(msg);
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &tmp,
DBUS_TYPE_INVALID);
- free(str);
+ free(tmp);
return reply;
}
@@ -822,46 +637,124 @@ static DBusMessage *handle_dev_get_remote_name_req(DBusMessage *msg, void *data)
return reply;
}
-static DBusMessage *handle_dev_get_remote_version_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_get_remote_alias_req(DBusMessage *msg, void *data)
{
- /*FIXME: */
- return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED);
+ struct hci_dbus_data *dbus_data = data;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ char str[249], *str_ptr = str, *addr_ptr;
+ bdaddr_t bdaddr;
+ int err;
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_get_basic(&iter, &addr_ptr);
+
+ str2ba(addr_ptr, &bdaddr);
+
+ err = get_device_alias(dbus_data->dev_id, &bdaddr, str, sizeof(str));
+ if (err < 0)
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | -err);
+
+ 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_remote_revision_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_set_remote_alias_req(DBusMessage *msg, void *data)
{
- /*FIXME: */
- return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED);
+ 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, DEV_SIG_REMOTE_ALIAS_CHANGED,
+ 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_remote_manufacturer_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_last_seen_req(DBusMessage *msg, void *data)
{
- /*FIXME: */
- return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED);
+ struct hci_dbus_data *dbus_data = data;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ char filename[PATH_MAX + 1];
+ char addr[18], *addr_ptr, *str;
+
+ get_device_address(dbus_data->dev_id, addr, sizeof(addr));
+
+ snprintf(filename, PATH_MAX, "%s/%s/lastseen", STORAGEDIR, addr);
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_get_basic(&iter, &addr_ptr);
+
+ str = textfile_get(filename, addr_ptr);
+ if (!str)
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | ENXIO);
+
+ reply = dbus_message_new_method_return(msg);
+
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
+
+ free(str);
+
+ return reply;
}
-static DBusMessage *handle_dev_get_remote_company_req(DBusMessage *msg, void *data)
+static DBusMessage *handle_dev_last_used_req(DBusMessage *msg, void *data)
{
+ struct hci_dbus_data *dbus_data = data;
+ DBusMessageIter iter;
DBusMessage *reply;
- bdaddr_t bdaddr;
- char oui[9], *str_bdaddr, *tmp;
+ char filename[PATH_MAX + 1];
+ char addr[18], *addr_ptr, *str;
- dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str_bdaddr,
- DBUS_TYPE_INVALID);
+ get_device_address(dbus_data->dev_id, addr, sizeof(addr));
- str2ba(str_bdaddr, &bdaddr);
- ba2oui(&bdaddr, oui);
+ snprintf(filename, PATH_MAX, "%s/%s/lastused", STORAGEDIR, addr);
- tmp = ouitocomp(oui);
- if (!tmp)
- return bluez_new_failure_msg(msg, BLUEZ_EDBUS_RECORD_NOT_FOUND);
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_get_basic(&iter, &addr_ptr);
+
+ str = textfile_get(filename, addr_ptr);
+ if (!str)
+ return bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET | ENXIO);
reply = dbus_message_new_method_return(msg);
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &tmp,
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID);
- free(tmp);
+ free(str);
return reply;
}
@@ -948,68 +841,6 @@ failed:
return reply;
}
-static DBusMessage *handle_dev_list_bondings_req(DBusMessage *msg, void *data)
-{
- void do_append(char *key, char *value, void *data)
- {
- DBusMessageIter *iter = data;
-
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
- }
-
- struct hci_dbus_data *dbus_data = data;
- DBusMessageIter iter;
- DBusMessageIter array_iter;
- DBusMessage *reply;
- char filename[PATH_MAX + 1];
- char addr[18];
-
- get_device_address(dbus_data->dev_id, addr, sizeof(addr));
-
- snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr);
-
- reply = dbus_message_new_method_return(msg);
-
- dbus_message_iter_init_append(reply, &iter);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_STRING_AS_STRING, &array_iter);
-
- textfile_foreach(filename, do_append, &array_iter);
-
- dbus_message_iter_close_container(&iter, &array_iter);
-
- return reply;
-}
-
-static DBusMessage *handle_dev_has_bonding_req(DBusMessage *msg, void *data)
-{
- struct hci_dbus_data *dbus_data = data;
- DBusMessageIter iter;
- DBusMessage *reply;
- char filename[PATH_MAX + 1];
- char addr[18], *addr_ptr, *str;
- dbus_bool_t result = FALSE;
-
- get_device_address(dbus_data->dev_id, addr, sizeof(addr));
-
- snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr);
-
- dbus_message_iter_init(msg, &iter);
- dbus_message_iter_get_basic(&iter, &addr_ptr);
-
- str = textfile_get(filename, addr_ptr);
- result = str ? TRUE : FALSE;
- free(str);
-
- reply = dbus_message_new_method_return(msg);
-
- dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &result,
- DBUS_TYPE_INVALID);
-
- return reply;
-}
-
static DBusMessage *handle_dev_remove_bonding_req(DBusMessage *msg, void *data)
{
struct hci_dbus_data *dbus_data = data;
@@ -1088,6 +919,68 @@ failed:
return reply;
}
+static DBusMessage *handle_dev_has_bonding_req(DBusMessage *msg, void *data)
+{
+ struct hci_dbus_data *dbus_data = data;
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ char filename[PATH_MAX + 1];
+ char addr[18], *addr_ptr, *str;
+ dbus_bool_t result = FALSE;
+
+ get_device_address(dbus_data->dev_id, addr, sizeof(addr));
+
+ snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr);
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_get_basic(&iter, &addr_ptr);
+
+ str = textfile_get(filename, addr_ptr);
+ result = str ? TRUE : FALSE;
+ free(str);
+
+ reply = dbus_message_new_method_return(msg);
+
+ dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &result,
+ DBUS_TYPE_INVALID);
+
+ return reply;
+}
+
+static DBusMessage *handle_dev_list_bondings_req(DBusMessage *msg, void *data)
+{
+ void do_append(char *key, char *value, void *data)
+ {
+ DBusMessageIter *iter = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &key);
+ }
+
+ struct hci_dbus_data *dbus_data = data;
+ DBusMessageIter iter;
+ DBusMessageIter array_iter;
+ DBusMessage *reply;
+ char filename[PATH_MAX + 1];
+ char addr[18];
+
+ get_device_address(dbus_data->dev_id, addr, sizeof(addr));
+
+ snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr);
+
+ reply = dbus_message_new_method_return(msg);
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array_iter);
+
+ textfile_foreach(filename, do_append, &array_iter);
+
+ dbus_message_iter_close_container(&iter, &array_iter);
+
+ return reply;
+}
+
static DBusMessage *handle_dev_pin_code_length_req(DBusMessage *msg, void *data)
{
struct hci_dbus_data *dbus_data = data;
@@ -1150,6 +1043,113 @@ static DBusMessage *handle_dev_encryption_key_size_req(DBusMessage *msg, void *d
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_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_cache_req(DBusMessage *msg, void *data)
+{
+ /*FIXME: */
+ return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED);
+}
+
+static DBusMessage *handle_dev_discover_service_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_VERSION, handle_dev_get_version_req, DEV_GET_VERSION_SIGNATURE },
@@ -1189,8 +1189,8 @@ static const struct service_data dev_services[] = {
{ DEV_ENCRYPTION_KEY_SIZE, handle_dev_encryption_key_size_req, DEV_ENCRYPTION_KEY_SIZE_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_CACHE, handle_dev_discover_cache_req, DEV_DISCOVER_CACHE_SIGNATURE },
{ DEV_DISCOVER_SERVICE, handle_dev_discover_service_req, DEV_DISCOVER_SERVICE_SIGNATURE },
{ NULL, NULL, NULL}