diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2008-03-12 21:22:06 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2008-03-12 21:22:06 +0000 | 
| commit | fbd60c20356e145a30e7fe7f6e91c9e8cf3c73da (patch) | |
| tree | 04670a20e3871693d138049a9de1c3784614db11 /plugins | |
| parent | 88f13920c39806113d88ca13d2542a2380ffa63c (diff) | |
Add RFCOMM listener to echo plugin
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/Makefile.am | 2 | ||||
| -rw-r--r-- | plugins/echo.c | 96 | 
2 files changed, 98 insertions, 0 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 0fb8a135..4e2b76a8 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -7,6 +7,8 @@ libecho_la_SOURCES = echo.c  AM_LDFLAGS = -module -avoid-version -export-symbols-regex bluetooth_plugin_desc +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ +  INCLUDES = -I$(top_builddir)/common -I$(top_builddir)/hcid  MAINTAINERCLEANFILES = Makefile.in diff --git a/plugins/echo.c b/plugins/echo.c index 81999a64..ca8c25d4 100644 --- a/plugins/echo.c +++ b/plugins/echo.c @@ -26,21 +26,117 @@  #endif  #include <errno.h> +#include <unistd.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/rfcomm.h> +#include <bluetooth/sdp.h> +#include <bluetooth/sdp_lib.h> + +#include <glib.h>  #include "plugin.h"  #include "server.h"  #include "logging.h" +static gboolean session_event(GIOChannel *chan, +					GIOCondition cond, gpointer data) +{ +	unsigned char buf[672]; +	gsize len, written; +	GIOError err; + +	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) +		return FALSE; + +	err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len); +	if (err == G_IO_ERROR_AGAIN) +		return TRUE; + +	g_io_channel_write(chan, (const gchar *) buf, len, &written); + +	return TRUE; +} + +static gboolean connect_event(GIOChannel *chan, +					GIOCondition cond, gpointer data) +{ +	GIOChannel *io; +	struct sockaddr_rc addr; +	socklen_t optlen; +	char address[18]; +	int sk, nsk; + +	sk = g_io_channel_unix_get_fd(chan); + +	memset(&addr, 0, sizeof(addr)); +	optlen = sizeof(addr); + +	nsk = accept(sk, (struct sockaddr *) &addr, &optlen); +	if (nsk < 0) +		return TRUE; + +	io = g_io_channel_unix_new(nsk); +	g_io_channel_set_close_on_unref(io, TRUE); + +	ba2str(&addr.rc_bdaddr, address); + +	g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, +							session_event, NULL); + +	return TRUE; +} + +static GIOChannel *setup_rfcomm(uint8_t channel) +{ +	GIOChannel *io; +	struct sockaddr_rc addr; +	int sk; + +	sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); +	if (sk < 0) +		return NULL; + +	memset(&addr, 0, sizeof(addr)); +	addr.rc_family = AF_BLUETOOTH; +	bacpy(&addr.rc_bdaddr, BDADDR_ANY); +	addr.rc_channel = channel; + +	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { +		close(sk); +		return NULL; +	} + +	if (listen(sk, 10) < 0) { +		close(sk); +		return NULL; +	} + +	io = g_io_channel_unix_new(sk); +	g_io_channel_set_close_on_unref(io, TRUE); + +	g_io_add_watch(io, G_IO_IN, connect_event, NULL); + +	return io; +} + +static GIOChannel *chan = NULL; +  static int echo_probe(const char *adapter)  {  	debug("echo probe adapter %s", adapter); +	chan = setup_rfcomm(23); +  	return 0;  }  static void echo_remove(const char *adapter)  {  	debug("echo remove adapter %s", adapter); + +	g_io_channel_unref(chan);  }  static struct bt_server echo_server = {  | 
