summaryrefslogtreecommitdiff
path: root/hcid
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-11-01 19:49:49 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-11-01 19:49:49 +0000
commit4b50da3bc0de3797ead5b632c77d49a45db12444 (patch)
treead0fbc5eaf85972b2056bdd0592d156cdb5cd136 /hcid
parentb525d3b600bc325a4d1937b0bb6920d51b99dd79 (diff)
downloadbluez-4b50da3bc0de3797ead5b632c77d49a45db12444.tar.gz
Add up and down methods
Diffstat (limited to 'hcid')
-rw-r--r--hcid/dbus.c103
1 files changed, 95 insertions, 8 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c
index b9838b0a2..bdc5e2aad 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -258,6 +258,8 @@ static struct profile_obj_path_data obj_path_table[] = {
static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data);
static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data);
+static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data);
static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data);
static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data);
static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data);
@@ -273,8 +275,8 @@ static const DBusObjectPathVTable obj_mgr_vtable = {
};
static const struct service_data device_services[] = {
- { DEV_UP, handle_not_implemented_req, DEV_UP_SIGNATURE },
- { DEV_DOWN, handle_not_implemented_req, DEV_DOWN_SIGNATURE },
+ { DEV_UP, handle_device_up_req, DEV_UP_SIGNATURE },
+ { DEV_DOWN, handle_device_down_req, DEV_DOWN_SIGNATURE },
{ DEV_RESET, handle_not_implemented_req, DEV_RESET_SIGNATURE },
{ DEV_SET_PROPERTY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE },
{ DEV_GET_PROPERTY, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE },
@@ -380,12 +382,15 @@ static void free_pin_req(void *req)
static gboolean register_dbus_path(const char *path, uint16_t id, const DBusObjectPathVTable *pvtable)
{
struct hci_dbus_data *data;
+
syslog(LOG_INFO,"Registering DBUS Path: %s", path);
+
data = malloc(sizeof(struct hci_dbus_data));
if (data == NULL) {
syslog(LOG_ERR,"Failed to alloc memory to DBUS path register data (%s)", path);
return FALSE;
}
+
data->id = id;
if (!dbus_connection_register_object_path(connection, path, pvtable, data)) {
@@ -393,13 +398,16 @@ static gboolean register_dbus_path(const char *path, uint16_t id, const DBusObje
free(data);
return FALSE;
}
+
return TRUE;
}
static gboolean unregister_dbus_path(const char *path)
{
void *data;
+
syslog(LOG_INFO,"Unregistering DBUS Path: %s", path);
+
if (dbus_connection_get_object_path_data(connection, path, &data) && data)
free(data);
@@ -407,6 +415,7 @@ static gboolean unregister_dbus_path(const char *path)
syslog(LOG_ERR,"DBUS failed to unregister %s object", path);
return FALSE;
}
+
return TRUE;
}
@@ -1187,14 +1196,16 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg,
if (child && *child) {
struct profile_obj_path_data *profile;
child++;
-
- for (profile = obj_path_table ;profile->name != NULL; profile++) {
- if (strcmp(profile->name, child) == 0) {
- handlers = profile->get_svc_table();
- break;
+ if (!strncmp(child, "hci", 3)) {
+ handlers = device_services;
+ } else {
+ for (profile = obj_path_table; profile->name != NULL; profile++) {
+ if (strcmp(profile->name, child) == 0) {
+ handlers = profile->get_svc_table();
+ break;
+ }
}
}
-
}
}
@@ -1716,6 +1727,80 @@ failed:
* Section reserved to Manager D-Bus message handlers
*
*****************************************************************/
+static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ struct hci_dbus_data *dbus_data = data;
+ struct hci_dev_info di;
+ struct hci_dev_req dr;
+ int sk = -1;
+
+ /* Create and bind HCI socket */
+ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+ if (sk < 0) {
+ syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
+ }
+
+ if (ioctl(sk, HCIDEVUP, dbus_data->id) < 0 && errno != EALREADY) {
+ syslog(LOG_ERR, "Can't init device hci%d: %s (%d)\n",
+ dbus_data->id, strerror(errno), errno);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
+ }
+
+ if (ioctl(sk, HCIGETDEVINFO, (void *) &di) >= 0 &&
+ !hci_test_bit(HCI_RAW, &di.flags)) {
+ dr.dev_id = dbus_data->id;
+ dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; /* piscan */
+ if (ioctl(sk, HCISETSCAN, (unsigned long) &dr) < 0) {
+ syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)\n",
+ dbus_data->id, strerror(errno), errno);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
+ }
+ }
+
+ reply = dbus_message_new_method_return(msg);
+
+failed:
+ if (sk >= 0)
+ close(sk);
+
+ return reply;
+}
+
+static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ struct hci_dbus_data *dbus_data = data;
+ int sk = -1;
+
+ /* Create and bind HCI socket */
+ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+ if (sk < 0) {
+ syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
+ }
+
+ if (ioctl(sk, HCIDEVDOWN, dbus_data->id) < 0) {
+ syslog(LOG_ERR, "Can't down device hci%d: %s (%d)\n",
+ dbus_data->id, strerror(errno), errno);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
+ }
+
+ reply = dbus_message_new_method_return(msg);
+
+failed:
+ if (sk >= 0)
+ close(sk);
+
+ return reply;
+}
+
static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data)
{
DBusMessageIter iter;
@@ -1810,8 +1895,10 @@ static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data)
failed:
if (sk >= 0)
close(sk);
+
if (dl)
free(dl);
+
return reply;
}