dundee: Handle Profile connect and disconnect
authorPaulo Borges <paulo.borges@openbossa.org>
Wed, 20 Mar 2013 22:26:42 +0000 (19:26 -0300)
committerDaniel Wagner <daniel.wagner@bmw-carit.de>
Sun, 24 Mar 2013 12:25:37 +0000 (13:25 +0100)
dundee/bluez5.c

index 3ecc9cf..3f9c646 100644 (file)
@@ -41,16 +41,63 @@ struct bluetooth_device {
        char *path;
        char *address;
        char *name;
+
+       struct cb_data *connect_cbd;
+
+       int fd;
 };
 
 static DBusMessage *profile_new_connection(DBusConnection *conn,
                                        DBusMessage *msg, void *user_data)
 {
-       DBG("");
+       struct bluetooth_device *bt_device;
+       dundee_device_connect_cb_t cb;
+       DBusMessageIter iter;
+       const char *path;
+       int fd;
 
-       return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
-                                               ".NotImplemented",
-                                               "Implementation not provided");
+       if (!dbus_message_iter_init(msg, &iter))
+               goto error;
+
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+               goto error;
+
+       dbus_message_iter_get_basic(&iter, &path);
+
+       bt_device = g_hash_table_lookup(registered_devices, path);
+       if (bt_device == NULL)
+               goto error;
+
+       cb = bt_device->connect_cbd->cb;
+
+       dbus_message_iter_next(&iter);
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UNIX_FD)
+               goto call_failure;
+
+       dbus_message_iter_get_basic(&iter, &fd);
+       if (fd < 0)
+               goto call_failure;
+
+       DBG("%s %d", bt_device->path, fd);
+
+       bt_device->fd = fd;
+
+       CALLBACK_WITH_SUCCESS(cb, fd, bt_device->connect_cbd->data);
+
+       g_free(bt_device->connect_cbd);
+       bt_device->connect_cbd = NULL;
+
+       return dbus_message_new_method_return(msg);
+
+call_failure:
+       CALLBACK_WITH_FAILURE(cb, -1, bt_device->connect_cbd->data);
+
+       g_free(bt_device->connect_cbd);
+       bt_device->connect_cbd = NULL;
+
+error:
+       return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE ".Rejected",
+                                       "Invalid arguments in method call");
 }
 
 static DBusMessage *profile_release(DBusConnection *conn,
@@ -76,11 +123,31 @@ static DBusMessage *profile_cancel(DBusConnection *conn,
 static DBusMessage *profile_disconnection(DBusConnection *conn,
                                        DBusMessage *msg, void *user_data)
 {
-       DBG("");
+       struct bluetooth_device *bt_device;
+       DBusMessageIter iter;
+       const char *path;
 
-       return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
-                                               ".NotImplemented",
-                                               "Implementation not provided");
+       if (!dbus_message_iter_init(msg, &iter))
+               goto error;
+
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+               goto error;
+
+       dbus_message_iter_get_basic(&iter, &path);
+
+       bt_device = g_hash_table_lookup(registered_devices, path);
+       if (bt_device == NULL)
+               goto error;
+
+       DBG("%s", bt_device->path);
+
+       CALLBACK_WITH_SUCCESS(dundee_device_disconnect, bt_device->device);
+
+       return dbus_message_new_method_return(msg);
+
+error:
+       return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE ".Rejected",
+                                       "Invalid arguments in method call");
 }
 
 static const GDBusMethodTable profile_methods[] = {
@@ -105,27 +172,55 @@ static void bluetooth_device_destroy(gpointer user_data)
        if (bt_device->device != NULL)
                dundee_device_unregister(bt_device->device);
 
+       if (bt_device->connect_cbd != NULL)
+               g_free(bt_device->connect_cbd);
+
        g_free(bt_device->path);
        g_free(bt_device->address);
        g_free(bt_device->name);
        g_free(bt_device);
 }
 
+static void bluetooth_device_connect_callback(gboolean success,
+                                                       gpointer user_data)
+{
+       struct bluetooth_device *bt_device = user_data;
+
+       if (success) {
+               DBG("Success");
+               return;
+       }
+
+       DBG("ConnectProfile() returned an error");
+
+       g_free(bt_device->connect_cbd);
+       bt_device->connect_cbd = NULL;
+}
+
 static void bluetooth_device_connect(struct dundee_device *device,
                        dundee_device_connect_cb_t cb, void *data)
 {
        struct bluetooth_device *bt_device = dundee_device_get_data(device);
+       struct cb_data *cbd = cb_data_new(cb, data);
 
        DBG("%s", bt_device->path);
 
+       cbd->user = bt_device;
+       bt_device->connect_cbd = cbd;
+
        bt_connect_profile(ofono_dbus_get_connection(), bt_device->path,
-                                               DUN_GW_UUID, NULL, NULL);
+               DUN_GW_UUID, bluetooth_device_connect_callback, bt_device);
 }
 
 static void bluetooth_device_disconnect(struct dundee_device *device,
                                dundee_device_disconnect_cb_t cb, void *data)
 {
-       DBG("");
+       struct bluetooth_device *bt_device = dundee_device_get_data(device);
+
+       DBG("%s", bt_device->path);
+
+       shutdown(bt_device->fd, SHUT_RDWR);
+       CALLBACK_WITH_SUCCESS(cb, data);
 }
 
 struct dundee_device_driver bluetooth_driver = {