Now a RFCOMM incoming connection can be made, all the pieces are here.
---
 plugins/bluetooth.c |  123 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 122 insertions(+), 1 deletions(-)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 0b5a021..f3b9140 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -90,6 +90,9 @@ struct server {
        guint           handle;
        ConnectFunc     connect_cb;
        gpointer        user_data;
+       gboolean        pending_auth;
+       GIOChannel      *client_io;
+       guint           client_watch;
 };
 
 typedef struct {
@@ -453,10 +456,25 @@ static gboolean property_changed(DBusConnection 
*connection, DBusMessage *msg,
        return TRUE;
 }
 
+static void disconnect(struct server *server)
+{
+       if (server->client_io == NULL)
+               return;
+
+       server->client_io = NULL;
+
+       if (server->client_watch > 0) {
+               g_source_remove(server->client_watch);
+               server->client_watch = 0;
+       }
+}
+
 static void server_stop(gpointer data)
 {
        struct server *server = data;
 
+       disconnect(server);
+
        if (server->handle > 0) {
                DBusMessage *msg;
 
@@ -481,11 +499,114 @@ static void server_stop(gpointer data)
        server->adapter = NULL;
 }
 
+static void cancel_authorization(struct server *server)
+{
+       DBusMessage *msg;
+
+       msg = dbus_message_new_method_call(BLUEZ_SERVICE, server->adapter,
+                       BLUEZ_SERVICE_INTERFACE, "CancelAuthorization");
+       if (!msg)
+               return;
+
+       g_dbus_send_message(connection, msg);
+}
+
+static void auth_cb(DBusPendingCall *call, gpointer user_data)
+{
+       struct server *server = user_data;
+       DBusMessage *reply = dbus_pending_call_steal_reply(call);
+       DBusError derr;
+       GError *err = NULL;
+
+       dbus_error_init(&derr);
+
+       server->pending_auth = FALSE;
+
+       if (dbus_set_error_from_message(&derr, reply)) {
+               ofono_error("RequestAuthorization error: %s, %s",
+                               derr.name, derr.message);
+
+               if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY))
+                       cancel_authorization(server);
+
+               dbus_error_free(&derr);
+               goto failed;
+       }
+
+       ofono_info("RequestAuthorization() succeeded");
+
+       if (!bt_io_accept(server->client_io, server->connect_cb,
+                                       server->user_data, NULL, &err)) {
+               ofono_error("%s", err->message);
+               g_error_free(err);
+               goto failed;
+       }
+       return;
+
+failed:
+       dbus_message_unref(reply);
+       disconnect(server);
+}
+
+static gboolean client_event(GIOChannel *io, GIOCondition cond,
+                                               gpointer user_data)
+{
+       struct server *server = user_data;
+
+       if (server->pending_auth == TRUE)
+               cancel_authorization(server);
+
+       server->pending_auth = FALSE;
+
+       disconnect(server);
+
+       return FALSE;
+}
+
 static void new_connection(GIOChannel *io, gpointer user_data)
 {
        struct server *server = user_data;
+       GError *err = NULL;
+       char address[18];
+       const char *addr;
+       guint8 channel;
+       int ret;
+
+       if (server->client_watch != 0) {
+               ofono_info("Client already connected");
+               return;
+       }
+
+       bt_io_get(io, BT_IO_RFCOMM, &err, BT_IO_OPT_DEST, address,
+                                       BT_IO_OPT_CHANNEL, &channel,
+                                       BT_IO_OPT_INVALID);
+       if (err) {
+               ofono_error("%s", err->message);
+               g_error_free(err);
+               return;
+       }
+
+       ofono_info("New connection from: %s, channel %u", address, channel);
+
+       addr = address;
+       ret = bluetooth_send_with_reply(server->adapter,
+                                       BLUEZ_SERVICE_INTERFACE,
+                                       "RequestAuthorization",
+                                       auth_cb, server, NULL, DBUS_TIMEOUT,
+                                       DBUS_TYPE_STRING, &addr,
+                                       DBUS_TYPE_UINT32, &server->handle,
+                                       DBUS_TYPE_INVALID);
+       if (ret < 0) {
+               ofono_error("RequestAuthorization() failed");
+               return;
+       }
+
+       server->client_io = io;
+       server->client_watch = g_io_add_watch(server->client_io,
+                                       G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+                                       client_event, server);
 
-       DBG("%p", server);
+       server->pending_auth = TRUE;
 }
 
 static void add_record_cb(DBusPendingCall *call, gpointer user_data)
-- 
1.7.4.rc3

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to