summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2007-04-13 11:51:00 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2007-04-13 11:51:00 +0000
commit260b175f47f5006b34a8eceda9914f67ef0caa12 (patch)
tree87000802c02956ea2e8ce6689dbe9f32eced060a
parent1a02bbc361299198257ca32969d2d804ee9fb74c (diff)
Cleanup and small fixes
-rw-r--r--audio/headset.c233
-rw-r--r--audio/headset.h6
-rw-r--r--audio/main.c4
-rw-r--r--audio/manager.c41
-rw-r--r--audio/manager.h2
5 files changed, 162 insertions, 124 deletions
diff --git a/audio/headset.c b/audio/headset.c
index a6581df8..b1aad63d 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -166,6 +166,13 @@ static DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg)
return error_reply(conn, msg, "org.bluez.Error.Failed", "Failed");
}
+static gint headset_bda_cmp(gconstpointer headset, gconstpointer bda)
+{
+ const struct headset *hs = headset;
+
+ return bacmp(&hs->bda, bda);
+}
+
static gboolean headset_close_output(struct headset *hs)
{
assert(hs != NULL);
@@ -502,92 +509,6 @@ static void auth_callback(DBusPendingCall *call, void *data)
dbus_message_unref(reply);
}
-static gboolean headset_server_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
-{
- int srv_sk, cli_sk;
- struct sockaddr_rc addr;
- socklen_t size;
- char hs_address[18], *address = hs_address, *path;
- const char *uuid = "";
- struct headset *hs = NULL;
- DBusMessage *auth;
- DBusPendingCall *pending;
-
- if (cond & G_IO_NVAL)
- return FALSE;
-
- if (cond & (G_IO_HUP | G_IO_ERR)) {
- error("Hangup or error on rfcomm server socket");
- g_io_channel_close(chan);
- raise(SIGTERM);
- return FALSE;
- }
-
- srv_sk = g_io_channel_unix_get_fd(chan);
-
- size = sizeof(struct sockaddr_rc);
- cli_sk = accept(srv_sk, (struct sockaddr *) &addr, &size);
- if (cli_sk < 0) {
- error("accept: %s (%d)", strerror(errno), errno);
- return TRUE;
- }
-
- /* This returns an existing path if the headset already exists */
- path = headset_add(&addr.rc_bdaddr);
- if (!path) {
- error("Unable to create a new headset object");
- close(cli_sk);
- return TRUE;
- }
-
- manager_add_headset(path);
-
- if (hs->state > HEADSET_STATE_DISCONNECTED || hs->rfcomm) {
- debug("Refusing new connection since one already exists");
- close(cli_sk);
- return TRUE;
- }
-
- hs->rfcomm = g_io_channel_unix_new(cli_sk);
- if (!hs->rfcomm) {
- error("Allocating new GIOChannel failed!");
- close(cli_sk);
- return TRUE;
- }
-
- auth = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database",
- "RequestAuthorization");
- if (!auth) {
- error("Unable to allocat new RequestAuthorization method call");
- goto failed;
- }
-
- ba2str(&hs->bda, hs_address);
-
- dbus_message_append_args(auth, DBUS_TYPE_STRING, &address,
- DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID);
-
- if (dbus_connection_send_with_reply(connection, auth, &pending, -1) == FALSE) {
- error("Sending of authorization request failed");
- goto failed;
- }
-
- dbus_pending_call_set_notify(pending, auth_callback, hs, NULL);
- dbus_pending_call_unref(pending);
- dbus_message_unref(auth);
-
- return TRUE;
-
-failed:
- if (hs->rfcomm) {
- g_io_channel_close(hs->rfcomm);
- g_io_channel_unref(hs->rfcomm);
- hs->rfcomm = NULL;
- }
-
- return TRUE;
-}
-
static gboolean audio_input_to_sco_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
{
struct headset *hs = data;
@@ -890,13 +811,6 @@ failed:
return -1;
}
-static gint headset_bda_cmp(gconstpointer headset, gconstpointer bda)
-{
- const struct headset *hs = headset;
-
- return bacmp(&hs->bda, bda);
-}
-
static int create_ag_record(sdp_buf_t *buf, uint8_t ch)
{
sdp_list_t *svclass_id, *pfseq, *apseq, *root;
@@ -1619,17 +1533,15 @@ static const DBusObjectPathVTable hs_table = {
.message_function = hs_message,
};
-char *headset_add(const bdaddr_t *bda)
+static struct headset *headset_add_internal(const bdaddr_t *bda)
{
static int headset_uid = 0;
struct headset *hs;
GSList *match;
match = g_slist_find_custom(headsets, bda, headset_bda_cmp);
- if (match) {
- hs = match->data;
- return hs->object_path;
- }
+ if (match)
+ return match->data;
hs = g_try_new0(struct headset, 1);
if (!hs) {
@@ -1651,15 +1563,40 @@ char *headset_add(const bdaddr_t *bda)
headsets = g_slist_append(headsets, hs);
- return g_strdup(hs->object_path);
+ return hs;
}
-void headset_remove(char *path)
+const char *headset_add(const bdaddr_t *bda)
{
struct headset *hs;
- if (!dbus_connection_get_object_path_data(connection, path, (void *)
- &hs))
+ hs = headset_add_internal(bda);
+ if (!hs)
+ return NULL;
+
+ return hs->object_path;
+}
+
+const char *headset_get(const bdaddr_t *bda)
+{
+ GSList *match;
+ struct headset *hs;
+
+ match = g_slist_find_custom(headsets, bda, headset_bda_cmp);
+ if (!match)
+ return NULL;
+
+ hs = match->data;
+
+ return hs->object_path;
+}
+
+void headset_remove(const char *path)
+{
+ struct headset *hs;
+
+ if (!dbus_connection_get_object_path_data(connection, path,
+ (void *) &hs))
return;
if (hs->state > HEADSET_STATE_DISCONNECTED)
@@ -1671,7 +1608,97 @@ void headset_remove(char *path)
headsets = g_slist_remove(headsets, hs);
g_free(hs);
- g_free(path);
+}
+
+static gboolean headset_server_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
+{
+ int srv_sk, cli_sk;
+ struct sockaddr_rc addr;
+ socklen_t size;
+ char hs_address[18], *address = hs_address;
+ const char *uuid = "";
+ struct headset *hs = NULL;
+ DBusMessage *auth;
+ DBusPendingCall *pending;
+ GSList *match;
+
+ if (cond & G_IO_NVAL)
+ return FALSE;
+
+ if (cond & (G_IO_HUP | G_IO_ERR)) {
+ error("Hangup or error on rfcomm server socket");
+ g_io_channel_close(chan);
+ raise(SIGTERM);
+ return FALSE;
+ }
+
+ srv_sk = g_io_channel_unix_get_fd(chan);
+
+ size = sizeof(struct sockaddr_rc);
+ cli_sk = accept(srv_sk, (struct sockaddr *) &addr, &size);
+ if (cli_sk < 0) {
+ error("accept: %s (%d)", strerror(errno), errno);
+ return TRUE;
+ }
+
+ match = g_slist_find_custom(headsets, &addr.rc_bdaddr, headset_bda_cmp);
+ if (!match) {
+ hs = headset_add_internal(&addr.rc_bdaddr);
+ if (!hs) {
+ error("Unable to create a new headset object");
+ close(cli_sk);
+ return TRUE;
+ }
+
+ manager_add_headset(hs->object_path);
+ }
+ else
+ hs = match->data;
+
+ if (hs->state > HEADSET_STATE_DISCONNECTED || hs->rfcomm) {
+ debug("Refusing new connection since one already exists");
+ close(cli_sk);
+ return TRUE;
+ }
+
+ hs->rfcomm = g_io_channel_unix_new(cli_sk);
+ if (!hs->rfcomm) {
+ error("Allocating new GIOChannel failed!");
+ close(cli_sk);
+ return TRUE;
+ }
+
+ auth = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database",
+ "RequestAuthorization");
+ if (!auth) {
+ error("Unable to allocat new RequestAuthorization method call");
+ goto failed;
+ }
+
+ ba2str(&hs->bda, hs_address);
+
+ dbus_message_append_args(auth, DBUS_TYPE_STRING, &address,
+ DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID);
+
+ if (dbus_connection_send_with_reply(connection, auth, &pending, -1) == FALSE) {
+ error("Sending of authorization request failed");
+ goto failed;
+ }
+
+ dbus_pending_call_set_notify(pending, auth_callback, hs, NULL);
+ dbus_pending_call_unref(pending);
+ dbus_message_unref(auth);
+
+ return TRUE;
+
+failed:
+ if (hs->rfcomm) {
+ g_io_channel_close(hs->rfcomm);
+ g_io_channel_unref(hs->rfcomm);
+ hs->rfcomm = NULL;
+ }
+
+ return TRUE;
}
static GIOChannel *server_socket(uint8_t *channel)
diff --git a/audio/headset.h b/audio/headset.h
index 888b53fe..e51236ad 100644
--- a/audio/headset.h
+++ b/audio/headset.h
@@ -29,9 +29,11 @@
#define BUF_SIZE 1024
-char *headset_add(const bdaddr_t *bda);
+const char *headset_get(const bdaddr_t *bda);
-void headset_remove(char *path);
+const char *headset_add(const bdaddr_t *bda);
+
+void headset_remove(const char *path);
int headset_init(DBusConnection *conn);
diff --git a/audio/main.c b/audio/main.c
index 470b26d5..2188e6e7 100644
--- a/audio/main.c
+++ b/audio/main.c
@@ -88,10 +88,10 @@ int main(int argc, char *argv[])
g_main_loop_run(main_loop);
- headset_exit();
-
audio_exit();
+ headset_exit();
+
dbus_connection_unref(conn);
g_main_loop_unref(main_loop);
diff --git a/audio/manager.c b/audio/manager.c
index 07aa7b60..87dd4b01 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -134,24 +134,29 @@ static gboolean unix_event(GIOChannel *chan, GIOCondition cond, gpointer data)
return TRUE;
}
-void manager_add_headset(char *path)
+void manager_add_headset(const char *path)
{
- if (g_slist_find_custom(headsets, path, (GCompareFunc) strcmp))
- return;
+ char *my_path = g_strdup(path);
- headsets = g_slist_append(headsets, path);
+ headsets = g_slist_append(headsets, my_path);
- manager_signal(connection, "HeadsetCreated", path);
+ manager_signal(connection, "HeadsetCreated", my_path);
if (!default_hs) {
- default_hs = path;
- manager_signal(connection, "DefaultHeadsetChanged", path);
+ default_hs = my_path;
+ manager_signal(connection, "DefaultHeadsetChanged", my_path);
}
}
+static void manager_remove_headset(char *path)
+{
+ headset_remove(path);
+ g_free(path);
+}
+
static DBusHandlerResult am_create_headset(DBusMessage *msg)
{
- char *hs_path;
+ const char *hs_path;
const char *address;
bdaddr_t bda;
DBusMessage *reply;
@@ -175,13 +180,16 @@ static DBusHandlerResult am_create_headset(DBusMessage *msg)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
str2ba(address, &bda);
- /* This returns an existing path if the headset already exists */
- hs_path = headset_add(&bda);
- if (!hs_path)
- return error_reply(connection, msg,
- "org.bluez.Error.Failed",
- "Unable to create new headset object");
- manager_add_headset(hs_path);
+
+ hs_path = headset_get(&bda);
+ if (!hs_path) {
+ hs_path = headset_add(&bda);
+ if (!hs_path)
+ return error_reply(connection, msg,
+ "org.bluez.Error.Failed",
+ "Unable to create new headset object");
+ manager_add_headset(hs_path);
+ }
dbus_message_append_args(reply, DBUS_TYPE_STRING, &hs_path,
DBUS_TYPE_INVALID);
@@ -221,6 +229,7 @@ static DBusHandlerResult am_remove_headset(DBusMessage *msg)
path = match->data;
headsets = g_slist_remove(headsets, path);
+ g_free(path);
if (default_hs == path) {
if (!headsets)
@@ -407,7 +416,7 @@ void audio_exit(void)
unix_sock = -1;
if (headsets) {
- g_slist_foreach(headsets, (GFunc) headset_remove, NULL);
+ g_slist_foreach(headsets, (GFunc) manager_remove_headset, NULL);
g_slist_free(headsets);
headsets = NULL;
}
diff --git a/audio/manager.h b/audio/manager.h
index 4b5975a8..aae34101 100644
--- a/audio/manager.h
+++ b/audio/manager.h
@@ -31,7 +31,7 @@
#define HEADSET_PATH_BASE AUDIO_MANAGER_PATH "/headset"
-void manager_add_headset(char *path);
+void manager_add_headset(const char *path);
int audio_init(DBusConnection *conn);