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
[email protected]
http://lists.ofono.org/listinfo/ofono