diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c
index 8c3f564..0a27a00 100644
--- a/obexd/src/bluetooth.c
+++ b/obexd/src/bluetooth.c
static GSList *servers = NULL;
-void bluetooth_servers_foreach(GFunc func, gpointer user_data)
-{
- struct server *server;
- GSList *l;
-
- for (l = servers; l; l = l->next) {
- server = l->data;
- func(server, user_data);
- }
-}
-
static gboolean connect_event(GIOChannel *io, GIOCondition cond, gpointer user_data)
{
struct sockaddr_rc raddr;
return TRUE;
}
-static void server_destroyed(gpointer user_data)
-{
- struct server *server = user_data;
-
- error("Server destroyed");
-
- servers = g_slist_remove(servers, server);
-
- server_free(server);
-}
-
-static gint server_register(guint16 service, const gchar *name, guint8 channel,
- const gchar *folder, gboolean secure,
- gboolean auto_accept, const gchar *capability)
+static gint server_start(struct server *server)
{
struct sockaddr_rc laddr;
- GIOChannel *io;
- struct server *server;
- uint32_t handle;
int err, sk, arg;
sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
goto failed;
}
- if (secure) {
+ if (server->secure) {
int lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
if (setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
memset(&laddr, 0, sizeof(laddr));
laddr.rc_family = AF_BLUETOOTH;
bacpy(&laddr.rc_bdaddr, BDADDR_ANY);
- laddr.rc_channel = channel;
+ laddr.rc_channel = server->channel;
if (bind(sk, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
err = errno;
goto failed;
}
+ server->io = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(server->io, TRUE);
+ server->watch = g_io_add_watch(server->io,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ connect_event, server);
+
+ return 0;
+
+failed:
+ error("Bluetooth server register failed: %s(%d)", strerror(err), err);
+ close(sk);
+
+ return -err;
+}
+
+static gint server_stop(struct server *server)
+{
+ if (!server->io)
+ return -EINVAL;
+
+ if (server->watch) {
+ g_source_remove(server->watch);
+ server->watch = 0;
+ }
+
+ g_io_channel_unref(server->io);
+ server->io = NULL;
+
+ return 0;
+}
+
+static gint server_register(guint16 service, const gchar *name, guint8 channel,
+ const gchar *folder, gboolean secure,
+ gboolean auto_accept, const gchar *capability)
+{
+ struct server *server;
+ uint32_t handle;
+ int err;
+
server = g_malloc0(sizeof(struct server));
server->services = service;
server->name = g_strdup(name);
server->capability = g_strdup(capability);
server->channel = channel;
server->handle = handle;
+ server->secure = secure;
- io = g_io_channel_unix_new(sk);
- g_io_channel_set_close_on_unref(io, TRUE);
- g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- connect_event, server, server_destroyed);
- g_io_channel_unref(io);
+ err = server_start(server);
+ if (err < 0) {
+ server_free(server);
+ return err;
+ }
servers = g_slist_append(servers, server);
register_record(server, NULL);
return 0;
-
-failed:
- error("Bluetooth server register failed: %s(%d)", strerror(err), err);
- close(sk);
-
- return -err;
}
gint bluetooth_init(guint service, const gchar *name, const gchar *folder,
{
return;
}
+
+void bluetooth_start(void)
+{
+ GSList *l;
+
+ for (l = servers; l; l = l->next) {
+ struct server *server = l->data;
+
+ if (server_start(server) < 0)
+ continue;
+
+ register_record(server, NULL);
+ }
+}
+
+void bluetooth_stop(void)
+{
+ GSList *l;
+
+ for (l = servers; l; l = l->next) {
+ struct server *server = l->data;
+
+ server_stop(server);
+ }
+}
diff --git a/obexd/src/bluetooth.h b/obexd/src/bluetooth.h
index 587f9ff..ad110a1 100644
--- a/obexd/src/bluetooth.h
+++ b/obexd/src/bluetooth.h
guint8 channel, gboolean secure, gboolean auto_accept,
const gchar *capability);
void bluetooth_exit(void);
-void bluetooth_servers_foreach(GFunc func, gpointer user_data);
+void bluetooth_start(void);
+void bluetooth_stop(void);
diff --git a/obexd/src/manager.c b/obexd/src/manager.c
index c479fb3..adcadb3 100644
--- a/obexd/src/manager.c
+++ b/obexd/src/manager.c
error("Replied with an error: %s, %s",
derr.name, derr.message);
dbus_error_free(&derr);
+ bluetooth_stop();
goto done;
}
static void name_acquired(DBusConnection *conn, void *user_data)
{
find_adapter_any(NULL);
- bluetooth_servers_foreach(register_record, NULL);
+ bluetooth_start();
}
static void name_released(DBusConnection *conn, void *user_data)
{
g_free(any->path);
any->path = NULL;
+ bluetooth_stop();
}
gboolean manager_init(void)
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index b9c1d67..56a5f37 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
guint32 handle;
uint8_t channel;
gchar *devnode;
+ gboolean secure;
+ GIOChannel *io;
+ guint watch;
};
struct obex_session {