bluetooth: Add bluetooth server support
v4 cover bluetooth: Add bluetooth server support
It watches Bluetooth adapter property changes and adds SDP record to listen client connection request.
It supports multiple adapters, servers and client connections.
Frédéric Danis (2):
bluetooth: Add bluetooth server support
bluetooth: Add Bluetooth service authorization support
Makefile.am | 1 + plugins/bluetooth.c | 395 ++++++++++++++++++++++++++++++++++++++++++++++++++- plugins/bluetooth.h | 9 ++ 3 files changed, 402 insertions(+), 3 deletions(-)
PATCH v4 1/2 bluetooth: Add bluetooth server support
--- Makefile.am | 1 + plugins/bluetooth.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++- plugins/bluetooth.h | 9 ++ 3 files changed, 287 insertions(+), 3 deletions(-)
Makefile.am +1 -0
@@ -318,6 +318,7 @@ builtin_sources += plugins/bluetooth.c plugins/bluetooth.h builtin_modules += hfp builtin_sources += plugins/hfp.c plugins/bluetooth.h +builtin_sources += $(btio_sources) builtin_cflags += @BLUEZ_CFLAGS@ builtin_libadd += @BLUEZ_LIBS@ endif
plugins/bluetooth.c +277 -3
338 lines not on this page · raw message
plugins/bluetooth.h +9 -0
@@ -23,6 +23,7 @@#define BLUEZ_MANAGER_INTERFACE BLUEZ_SERVICE ".Manager"#define BLUEZ_ADAPTER_INTERFACE BLUEZ_SERVICE ".Adapter"#define BLUEZ_DEVICE_INTERFACE BLUEZ_SERVICE ".Device" +#define BLUEZ_SERVICE_INTERFACE BLUEZ_SERVICE ".Service"#define DBUS_TIMEOUT 15
@@ -39,10 +40,18 @@ struct bluetooth_profile {void (*set_alias)(const char *device,const char *); }; +struct server ; + +typedef void (*ConnectFunc )(GIOChannel *io,GError *err,gpointer user_data); +int bluetooth_register_uuid (const char *uuid,struct bluetooth_profile *profile);void bluetooth_unregister_uuid (const char *uuid); +struct server *bluetooth_register_server (guint8 channel,const char *sdp_record, +ConnectFunc cb,gpointer user_data); +void bluetooth_unregister_server (struct server *server); +void bluetooth_create_path (const char *dev_addr,const char *adapter_addr,char *buf,int size);
Signature · 1 line
1.7.1
PATCH v4 2/2 bluetooth: Add Bluetooth service authorization support
In reply to Frédéric Danis--- plugins/bluetooth.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 124 insertions(+), 9 deletions(-)
plugins/bluetooth.c +124 -9
@@ -44,6 +44,8 @@ static GHashTable *adapter_address_hash = NULL;static gint bluetooth_refcount;static GSList *server_list =NULL ; +#define TIMEOUT (60*1000)/* Timeout for user response (milliseconds) */ +struct server {guint8 channel;char *sdp_record;
@@ -58,6 +60,7 @@ struct cb_data {struct server *server;char *path;guint source; +GIOChannel *io; }; void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
@@ -495,13 +498,103 @@ static gboolean client_event(GIOChannel *chan, GIOCondition cond, gpointer data)return FALSE; } +static void cancel_authorization (struct cb_data *user_data) +{ +DBusMessage *msg; + +if (user_data->path ==NULL ) +return ; + + msg =dbus_message_new_method_call (BLUEZ_SERVICE , user_data->path, +BLUEZ_SERVICE_INTERFACE , +"CancelAuthorization" ); + +g_dbus_send_message (connection, msg); +} + +static void auth_cb (DBusPendingCall *call,gpointer user_data) +{ +struct cb_data *cb_data = user_data; +struct server *server = cb_data->server; + +DBusMessage *reply =dbus_pending_call_steal_reply (call); +DBusError derr; +GError *err =NULL ; + +dbus_error_init (&derr); + +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 (cb_data); + +dbus_error_free (&derr); + +dbus_message_unref (reply); + + goto failed; + } + +dbus_message_unref (reply); + +ofono_info ("RequestAuthorization succeeded" ); + +if (!bt_io_accept (cb_data->io, server->connect_cb, server->user_data, +NULL , &err)) { +ofono_error ("%s" , err->message); +g_error_free (err); + goto failed; + } + +g_source_remove (cb_data->source); + server->client_list =g_slist_remove (server->client_list, + (void *) cb_data->source); + + cb_data->source =g_io_add_watch (cb_data->io, +G_IO_HUP |G_IO_ERR |G_IO_NVAL , + client_event, cb_data); + server->client_list =g_slist_prepend (server->client_list, + (void *)cb_data->source); + +return ; + +failed: +g_source_remove (cb_data->source); + server->client_list =g_slist_remove (server->client_list, + (void *) cb_data->source); + +cb_data_destroy (cb_data); +} + +static gboolean auth_watch (GIOChannel *io,GIOCondition cond, +gpointer user_data) +{ +struct cb_data *cb_data = user_data; +struct server *server = cb_data->server; + +cancel_authorization (cb_data); + server->client_list =g_slist_remove (server->client_list, + (void *) cb_data->source); + +cb_data_destroy (cb_data); + +return FALSE; +} +static void confirm_event (GIOChannel *io,gpointer user_data) {struct server *server = user_data;struct cb_data *client_data; +guint handle; +const char *addr; +int ret;GError *err =NULL ;char laddress[18 ], raddress[18 ];guint8 channel; +GHashTableIter iter; +gpointer key, value; bt_io_get(io, BT_IO_RFCOMM, &err, BT_IO_OPT_SOURCE, laddress, BT_IO_OPT_DEST, raddress,
@@ -516,14 +609,6 @@ static void confirm_event(GIOChannel *io, gpointer user_data)ofono_info ("New connection for %s on channel %u from: %s," , laddress, channel, raddress); -if (!bt_io_accept (io, server->connect_cb, server->user_data, -NULL , &err)) { -ofono_error ("%s" , err->message); -g_error_free (err); -g_io_channel_unref (io); -return ; - } - client_data = g_try_new0(struct cb_data, 1);if (client_data ==NULL ) {ofono_error ("Unable to allocate client cb_data structure" );
@@ -531,9 +616,39 @@ static void confirm_event(GIOChannel *io, gpointer user_data) } client_data->server = server; + +g_hash_table_iter_init (&iter, adapter_address_hash); + +while (g_hash_table_iter_next (&iter, &key, &value)) { +if (g_strcmp0 (laddress, value) ==0 ) { + client_data->path =g_strdup (key); +DBG ("adapter path : %s" , client_data->path); +break ; + } + } + + client_data->io = io; + + handle = (guint )g_hash_table_lookup (server->adapter_hash, + client_data->path); + addr = raddress; + ret =bluetooth_send_with_reply (client_data->path, +BLUEZ_SERVICE_INTERFACE , +"RequestAuthorization" , + auth_cb, client_data,NULL ,TIMEOUT , +DBUS_TYPE_STRING , &addr, +DBUS_TYPE_UINT32 , &handle, +DBUS_TYPE_INVALID ); +if (ret <0 ) { +ofono_error ("Request Bluetooth authorization failed" ); +return ; + } + +ofono_info ("RequestAuthorization(%s, 0x%x)" , raddress, handle); + client_data->source =g_io_add_watch (io,G_IO_HUP |G_IO_ERR |G_IO_NVAL , - client_event, client_data); + auth_watch, client_data); server->client_list =g_slist_prepend (server->client_list, (void *)client_data->source); }
Signature · 1 line
1.7.1