Open Source Telephony
 help / color / mirror / Atom feed
From: Frederic Danis <frederic.danis@linux.intel.com>
To: ofono@ofono.org
Subject: Re: [PATCH 1/8] bluetooth: add server support
Date: Tue, 01 Feb 2011 15:17:56 +0100	[thread overview]
Message-ID: <4D481614.5090305@linux.intel.com> (raw)
In-Reply-To: <1296507122-10936-1-git-send-email-padovan@profusion.mobi>

[-- Attachment #1: Type: text/plain, Size: 8172 bytes --]

Hello Gustavo,

Le 31/01/2011 21:51, Gustavo F. Padovan a écrit :
> Initial code to have support to listen over a RFCOMM socket for incoming
> connections.
> ---
>   Makefile.am         |    1 +
>   plugins/bluetooth.c |  165 +++++++++++++++++++++++++++++++++++++++++++++++++++
>   plugins/bluetooth.h |   11 ++++
>   3 files changed, 177 insertions(+), 0 deletions(-)
>
> diff --git a/Makefile.am b/Makefile.am
> index a38fcb9..77b1453 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -321,6 +321,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
> diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
> index 93dd7a1..dcf75e6 100644
> --- a/plugins/bluetooth.c
> +++ b/plugins/bluetooth.c
> @@ -35,13 +35,58 @@
>
>   #include<ofono/dbus.h>
>
> +#include<btio.h>
>   #include "bluetooth.h"
>
>   static DBusConnection *connection;
>   static GHashTable *uuid_hash = NULL;
>   static GHashTable *adapter_address_hash = NULL;
> +static GSList *server_list = NULL;
>   static gint bluetooth_refcount;
>
> +struct server {
> +	guint16		service;
> +	gchar		*name;
> +	guint8		channel;
> +	GIOChannel	*io;
> +	char		*adapter;
> +	guint		handle;
> +	ConnectFunc	connect_cb;
> +	gpointer	user_data;
> +};
> +
> +typedef struct {
> +	guint8 b[6];
> +} __attribute__((packed)) bdaddr_t;
> +
> +static void baswap(bdaddr_t *dst, const bdaddr_t *src)
> +{
> +	register unsigned char *d = (unsigned char *) dst;
> +	register const unsigned char *s = (const unsigned char *) src;
> +	register int i;
> +
> +	for (i = 0; i<  6; i++)
> +		d[i] = s[5-i];
> +}
> +
> +static int str2ba(const char *str, bdaddr_t *ba)
> +{
> +	guint8 b[6];
> +	const char *ptr = str;
> +	int i;
> +
> +	for (i = 0; i<  6; i++) {
> +		b[i] = (guint8) strtol(ptr, NULL, 16);
> +		if (i != 5&&  !(ptr = strchr(ptr, ':')))
> +			ptr = ":00:00:00:00:00";
> +		ptr++;
> +	}
> +
> +	baswap(ba, (bdaddr_t *) b);
> +
> +	return 0;
> +}
> +
>   void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
>   				char *buf, int size)
>   {
> @@ -371,6 +416,70 @@ static gboolean property_changed(DBusConnection *connection, DBusMessage *msg,
>   	return TRUE;
>   }
>
> +static void server_stop(gpointer data)
> +{
> +	struct server *server = data;
> +
> +	if (server->handle>  0) {
> +		DBusMessage *msg;
> +
> +		msg = dbus_message_new_method_call(BLUEZ_SERVICE,
> +						server->adapter,
> +						BLUEZ_SERVICE_INTERFACE,
> +						"RemoveRecord");
> +		dbus_message_append_args(msg, DBUS_TYPE_UINT32,&server->handle,
> +						DBUS_TYPE_INVALID);
> +		g_dbus_send_message(connection, msg);
> +
> +		server->handle = 0;
> +	}
> +
> +	if (server->io != NULL) {
> +		g_io_channel_shutdown(server->io, TRUE, NULL);
> +		g_io_channel_unref(server->io);
> +		server->io = NULL;
> +	}
> +
> +	g_free(server->adapter);
> +	server->adapter = NULL;
> +}
> +
> +static void new_connection(GIOChannel *io, gpointer user_data)
> +{
> +	struct server *server = user_data;
> +
> +	DBG("%p", server);
> +}
> +
> +static void server_start(gpointer data, gpointer user_data)
> +{
> +	struct server *server = data;
> +	char *addr, *path = user_data;
> +	bdaddr_t baddr;
> +	GError *err = NULL;
> +
> +	if (server->handle != 0)
> +		return;
> +
> +	addr = g_hash_table_lookup(adapter_address_hash, path);
> +	str2ba(addr,&baddr);
> +	server->io = bt_io_listen(BT_IO_RFCOMM, NULL, new_connection,
> +					server, NULL,&err,
> +					BT_IO_OPT_SOURCE_BDADDR,&baddr,
> +					BT_IO_OPT_CHANNEL, server->channel,
> +					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
> +					BT_IO_OPT_INVALID);
> +	if (server->io == NULL) {
> +		ofono_error("Bluetooth %s register failed: %s",
> +					server->name, err->message);
> +		g_error_free(err);
> +		server_stop(server);
> +		return;
> +	}
> +
> +	server->adapter = g_strdup(path);
> +}
> +
This will not allows to start server on multiple adapters, as the test 
of the SDP Record handle will prevent to bt_io_listen on other adapters.

I do not understand why you pass the adapter address, if it is omitted 
the bt_io_listen will be done for all adapters.

>   static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data)
>   {
>   	const char *path = user_data;
> @@ -395,6 +504,9 @@ static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data)
>   	g_hash_table_insert(adapter_address_hash,
>   				g_strdup(path), g_strdup(addr));
>
> +	if (server_list)
> +		g_slist_foreach(server_list, server_start, (gpointer)path);
> +
>   	for (l = device_list; l; l = l->next) {
>   		const char *device = l->data;
>
> @@ -429,11 +541,26 @@ static gboolean adapter_removed(DBusConnection *connection,
>   				DBusMessage *message, void *user_data)
>   {
>   	const char *path;
> +	GSList *l;
>
>   	if (dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH,&path,
>   				DBUS_TYPE_INVALID) == TRUE)
>   		g_hash_table_remove(adapter_address_hash, path);
>
> +	for (l = server_list; l; l = l->next) {
> +		struct server *server = l->data;
> +
> +		if (!server->adapter)
> +			continue;
> +
> +		if (!g_str_equal(path, server->adapter))
> +			continue;
> +
> +		/* Don't remove handle if the adapter has been removed */
> +		server->handle = 0;
> +		server_stop(server);
> +	}
> +
>   	return TRUE;
>   }
>
> @@ -590,5 +717,43 @@ void bluetooth_unregister_uuid(const char *uuid)
>   	bluetooth_unref();
>   }
>
> +struct server *bluetooth_register_server(guint16 service, char *name,
> +						guint8 channel, ConnectFunc cb,
> +						gpointer user_data)
> +{
> +	struct server *server;
> +
> +	server = g_try_new0(struct server, 1);
> +	if (!server)
> +		return NULL;
> +
> +	bluetooth_ref();
> +
> +	server->service = service;
> +	server->name = g_strdup(name);
> +	server->channel = channel;
> +	server->connect_cb = cb;
> +	server->user_data = user_data;
> +
> +	server_list = g_slist_prepend(server_list, server);
> +
> +	bluetooth_send_with_reply("/", BLUEZ_MANAGER_INTERFACE, "GetProperties",
> +					manager_properties_cb, NULL, NULL, -1,
> +					DBUS_TYPE_INVALID);
> +
> +	return server;
> +}
> +
> +void bluetooth_unregister_server(struct server *server)
> +{
> +	server_list = g_slist_remove(server_list, server);
> +
> +	server_stop(server);
> +	g_free(server->name);
> +	g_free(server);
> +
> +	bluetooth_unref();
> +}
> +
>   OFONO_PLUGIN_DEFINE(bluetooth, "Bluetooth Utils Plugins", VERSION,
>   			OFONO_PLUGIN_PRIORITY_DEFAULT, NULL, NULL)
> diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
> index 42b0d13..f6fc6a6 100644
> --- a/plugins/bluetooth.h
> +++ b/plugins/bluetooth.h
> @@ -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,20 @@ struct bluetooth_profile {
>   	void (*set_alias)(const char *device, const char *);
>   };
>
> +
> +typedef void (*ConnectFunc)(GIOChannel *io, GError *err, gpointer user_data);
> +
> +struct server;
> +
>   int bluetooth_register_uuid(const char *uuid,
>   				struct bluetooth_profile *profile);
>   void bluetooth_unregister_uuid(const char *uuid);
>
> +struct server *bluetooth_register_server(guint16 service, char *name,
> +						guint8 channel, 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);
>


-- 
Frederic Danis                            Open Source Technology Centre
frederic.danis(a)intel.com                              Intel Corporation


  parent reply	other threads:[~2011-02-01 14:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-31 20:51 [PATCH 1/8] bluetooth: add server support Gustavo F. Padovan
2011-01-31 20:51 ` [PATCH 2/8] bluetooth: add support to register Bluetooth Service Gustavo F. Padovan
2011-01-31 20:51   ` [PATCH 3/8] bluetooth: add Request auth code for new connections Gustavo F. Padovan
2011-01-31 20:51     ` [PATCH 4/8] include: add public headed to emulator atom Gustavo F. Padovan
2011-01-31 20:51       ` [PATCH 5/8] emulator: Add emulator atom in oFono Gustavo F. Padovan
2011-01-31 20:52         ` [PATCH 6/8] dun_gw: Add DUN server plugin for oFono Gustavo F. Padovan
2011-01-31 20:52           ` [PATCH 7/8] emulator: Implement dialing up for DUN Gustavo F. Padovan
2011-01-31 20:52             ` [PATCH 8/8] gsmdial: add option for Bluetooth DUN dialing Gustavo F. Padovan
2011-02-01 14:25   ` [PATCH 2/8] bluetooth: add support to register Bluetooth Service Frederic Danis
2011-02-01 14:17 ` Frederic Danis [this message]
2011-02-02 18:21   ` [PATCH 1/8] bluetooth: add server support Gustavo F. Padovan
2011-02-03 15:56     ` Frederic Danis
2011-02-03 16:30       ` Gustavo F. Padovan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D481614.5090305@linux.intel.com \
    --to=frederic.danis@linux.intel.com \
    --cc=ofono@ofono.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox