summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hcid/dbus.c213
-rw-r--r--hcid/device.c96
-rw-r--r--hcid/hcid.h5
3 files changed, 187 insertions, 127 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 87abc7ff..dd167f1f 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -89,7 +89,7 @@ typedef int unregister_function_t(DBusConnection *conn, uint16_t id);
/*
* Utility functions
*/
-static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
+static char *get_peer_name(const bdaddr_t *local, const bdaddr_t *peer)
{
char filename[PATH_MAX + 1], addr[18];
@@ -1433,14 +1433,95 @@ static DBusMessage* handle_dev_get_company_req(DBusMessage *msg, void *data)
static DBusMessage* handle_dev_get_features_req(DBusMessage *msg, void *data)
{
- /*FIXME: */
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)
{
- /*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;
+
+ 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;
+ 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);
+
+ reply = dbus_message_new_method_return(msg);
+
+ return reply;
}
static DBusMessage* handle_dev_get_discoverable_to_req(DBusMessage *msg, void *data)
@@ -1482,63 +1563,6 @@ static DBusMessage* handle_dev_get_mode_req(DBusMessage *msg, void *data)
return reply;
}
-static DBusMessage* handle_dev_get_name_req(DBusMessage *msg, void *data)
-{
- struct hci_dbus_data *dbus_data = data;
- DBusMessage *reply = NULL;
- int dd = -1;
- read_local_name_rp rp;
- struct hci_request rq;
- const char *pname = (char*) rp.name;
- char name[249];
-
- 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;
- }
-
- memset(&rq, 0, sizeof(rq));
- rq.ogf = OGF_HOST_CTL;
- rq.ocf = OCF_READ_LOCAL_NAME;
- rq.rparam = &rp;
- rq.rlen = READ_LOCAL_NAME_RP_SIZE;
-
- if (hci_send_req(dd, &rq, 100) < 0) {
- syslog(LOG_ERR, "Sending getting name command failed: %s (%d)",
- strerror(errno), errno);
- reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
- goto failed;
- }
-
- if (rp.status) {
- syslog(LOG_ERR, "Getting name failed with status 0x%02x", rp.status);
- reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status);
- goto failed;
- }
-
- 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;
- }
-
- strncpy(name,pname,sizeof(name)-1);
- name[248]='\0';
- pname = name;
-
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &pname,
- DBUS_TYPE_INVALID);
-
-failed:
- if (dd >= 0)
- close(dd);
-
- return reply;
-}
-
static DBusMessage* handle_dev_is_connectable_req(DBusMessage *msg, void *data)
{
/*FIXME: */
@@ -1551,12 +1575,6 @@ static DBusMessage* handle_dev_is_discoverable_req(DBusMessage *msg, void *data)
return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED);
}
-static DBusMessage* handle_dev_set_alias_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: */
@@ -1640,65 +1658,6 @@ failed:
return reply;
}
-static DBusMessage* handle_dev_set_name_req(DBusMessage *msg, void *data)
-{
- struct hci_dbus_data *dbus_data = data;
- DBusMessageIter iter;
- DBusMessage *reply = NULL;
- char *str_name;
- int dd = -1;
- uint8_t status;
- change_local_name_cp cp;
- struct hci_request rq;
-
- dbus_message_iter_init(msg, &iter);
- dbus_message_iter_get_basic(&iter, &str_name);
-
- if (strlen(str_name) == 0) {
- syslog(LOG_ERR, "HCI change name failed - Invalid Name!");
- 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;
- }
-
- memset(&rq, 0, sizeof(rq));
- strncpy((char *) cp.name, str_name, sizeof(cp.name));
- rq.ogf = OGF_HOST_CTL;
- rq.ocf = OCF_CHANGE_LOCAL_NAME;
- rq.cparam = &cp;
- rq.clen = CHANGE_LOCAL_NAME_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
-
- if (hci_send_req(dd, &rq, 100) < 0) {
- syslog(LOG_ERR, "Sending change name 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 name 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;
@@ -1853,7 +1812,7 @@ static DBusMessage* handle_dev_remote_name_req(DBusMessage *msg, void *data)
}
/* Try retrieve from local cache */
- name = get_device_name(&di.bdaddr, &bdaddr);
+ name = get_peer_name(&di.bdaddr, &bdaddr);
if (name) {
reply = dbus_message_new_method_return(msg);
diff --git a/hcid/device.c b/hcid/device.c
index 71d97dbd..feb9be12 100644
--- a/hcid/device.c
+++ b/hcid/device.c
@@ -32,12 +32,14 @@
#include <syslog.h>
#include <string.h>
#include <sys/time.h>
+#include <sys/stat.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
+#include "textfile.h"
#include "oui.h"
#define MAX_DEVICES 16
@@ -74,6 +76,8 @@ struct hci_dev {
uint16_t lmp_subver;
uint16_t manufacturer;
+ uint8_t name[248];
+
struct hci_peer *peers;
struct hci_conn *conns;
};
@@ -265,3 +269,95 @@ int get_device_company(uint16_t dev_id, char *company, size_t size)
return err;
}
+
+int get_device_name(uint16_t dev_id, char *name, size_t size)
+{
+ char tmp[249];
+ int dd;
+
+ ASSERT_DEV_ID;
+
+ memset(tmp, 0, sizeof(tmp));
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ err("Can't open device hci%d",
+ dev_id, strerror(errno), errno);
+ return -errno;
+ }
+
+ if (hci_read_local_name(dd, sizeof(tmp), tmp, 2000) < 0) {
+ err("Can't read name for hci%d: %s (%d)",
+ dev_id, strerror(errno), errno);
+ return -errno;
+ }
+
+ hci_close_dev(dd);
+
+ memcpy(devices[dev_id].name, tmp, 248);
+
+ return snprintf(name, size, "%s", tmp);
+}
+
+int set_device_name(uint16_t dev_id, const char *name)
+{
+ int dd;
+
+ ASSERT_DEV_ID;
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ err("Can't open device hci%d",
+ dev_id, strerror(errno), errno);
+ return -errno;
+ }
+
+ if (hci_write_local_name(dd, name, 5000) < 0) {
+ err("Can't read name for hci%d: %s (%d)",
+ dev_id, strerror(errno), errno);
+ return -errno;
+ }
+
+ hci_close_dev(dd);
+
+ return 0;
+}
+
+int get_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, char *alias, size_t size)
+{
+ char filename[PATH_MAX + 1], addr[18], *tmp;
+ int err;
+
+ ASSERT_DEV_ID;
+
+ ba2str(&devices[dev_id].bdaddr, addr);
+ snprintf(filename, PATH_MAX, "%s/%s/aliases", STORAGEDIR, addr);
+
+ ba2str(bdaddr, addr);
+
+ tmp = textfile_get(filename, addr);
+ if (!tmp)
+ return -ENXIO;
+
+ err = snprintf(alias, size, "%s", tmp);
+
+ free(tmp);
+
+ return err;
+}
+
+int set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias)
+{
+ char filename[PATH_MAX + 1], addr[18];
+
+ ASSERT_DEV_ID;
+
+ ba2str(&devices[dev_id].bdaddr, addr);
+ snprintf(filename, PATH_MAX, "%s/%s/aliases", STORAGEDIR, addr);
+
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ ba2str(bdaddr, addr);
+
+ return textfile_put(filename, addr, alias);
+}
diff --git a/hcid/hcid.h b/hcid/hcid.h
index 1f98c5a6..dc7d71e9 100644
--- a/hcid/hcid.h
+++ b/hcid/hcid.h
@@ -159,6 +159,11 @@ int get_device_revision(uint16_t dev_id, char *revision, size_t size);
int get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size);
int get_device_company(uint16_t dev_id, char *company, size_t size);
+int get_device_name(uint16_t dev_id, char *name, size_t size);
+int set_device_name(uint16_t dev_id, const char *name);
+int get_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, char *alias, size_t size);
+int set_device_alias(uint16_t dev_id, const bdaddr_t *bdaddr, const char *alias);
+
int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name);
int read_device_name(bdaddr_t *local, bdaddr_t *peer, char *name);
int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer, uint8_t lmp_ver, uint16_t lmp_subver);