diff options
author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-06-29 23:19:36 +0000 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-06-29 23:19:36 +0000 |
commit | df235d1f395b10654024979180c778777bd50c71 (patch) | |
tree | d12a132c9921e5e50a661a73b752b01f71034b28 /audio/headset.c | |
parent | b57f22a505f7c46662bfd5900df38dd68099df2c (diff) |
Handle state machine in a better way and add disconnect code for plugin.
Diffstat (limited to 'audio/headset.c')
-rw-r--r-- | audio/headset.c | 124 |
1 files changed, 53 insertions, 71 deletions
diff --git a/audio/headset.c b/audio/headset.c index 28f6ac1d..ca24e93b 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -181,11 +181,6 @@ static void close_sco(struct device *device) g_io_channel_close(hs->sco); g_io_channel_unref(hs->sco); hs->sco = NULL; - hs->state = HEADSET_STATE_CONNECTED; - dbus_connection_emit_signal(device->conn, device->path, - AUDIO_HEADSET_INTERFACE, - "Stopped", - DBUS_TYPE_INVALID); } } @@ -286,8 +281,7 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, return TRUE; failed: - close_sco(device); - headset_close_rfcomm(device); + headset_set_state(device, HEADSET_STATE_DISCONNECTED); return FALSE; } @@ -304,7 +298,7 @@ static gboolean sco_cb(GIOChannel *chan, GIOCondition cond, error("Audio connection got disconnected"); - close_sco(device); + headset_set_state(device, HEADSET_STATE_CONNECTED); return FALSE; } @@ -359,9 +353,8 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond, { struct headset *hs; struct pending_connect *c; - int ret, sk, err, flags; + int ret, sk, err; socklen_t len; - char str[13]; if (cond & G_IO_NVAL) return FALSE; @@ -390,29 +383,12 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond, hs->sco = chan; c->io = NULL; - flags = G_IO_ERR | G_IO_HUP | G_IO_NVAL; - - g_io_add_watch(hs->sco, flags, (GIOFunc) sco_cb, device); - g_slist_foreach(hs->pending, (GFunc)pending_connect_ok, device); g_slist_free(hs->pending); hs->pending = NULL; fcntl(sk, F_SETFL, 0); - hs->state = HEADSET_STATE_PLAYING; - dbus_connection_emit_signal(device->conn, device->path, - AUDIO_HEADSET_INTERFACE, - "Playing", DBUS_TYPE_INVALID); - - if (hs->sp_gain >= 0) { - snprintf(str, sizeof(str) - 1, "\r\n+VGS=%u\r\n", hs->sp_gain); - headset_send(device->headset, str); - } - - if (hs->mic_gain >= 0) { - snprintf(str, sizeof(str) - 1, "\r\n+VGM=%u\r\n", hs->sp_gain); - headset_send(device->headset, str); - } + headset_set_state(device, HEADSET_STATE_PLAYING); return FALSE; @@ -420,7 +396,7 @@ failed: g_slist_foreach(hs->pending, (GFunc)pending_connect_failed, device); g_slist_free(hs->pending); hs->pending = NULL; - hs->state = HEADSET_STATE_CONNECTED; + headset_set_state(device, HEADSET_STATE_CONNECTED); return FALSE; } @@ -486,7 +462,7 @@ static int sco_connect(struct device *device, struct pending_connect *c) do_callback = TRUE; } - hs->state = HEADSET_STATE_PLAY_IN_PROGRESS; + headset_set_state(device, HEADSET_STATE_PLAY_IN_PROGRESS); if (!g_slist_find(hs->pending, c)) hs->pending = g_slist_append(hs->pending, c); @@ -530,12 +506,8 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond, hs->rfcomm = chan; c->io = NULL; - hs->state = HEADSET_STATE_CONNECTED; - dbus_connection_emit_signal(device->conn, device->path, - AUDIO_HEADSET_INTERFACE, - "Connected", DBUS_TYPE_INVALID); + headset_set_state(device, HEADSET_STATE_CONNECTED); - device_store(device, FALSE); debug("Connected to %s", hs_address); g_io_add_watch(chan, G_IO_IN | G_IO_ERR | G_IO_HUP| G_IO_NVAL, @@ -558,9 +530,9 @@ failed: g_slist_free(hs->pending); hs->pending = NULL; if (hs->rfcomm) - hs->state = HEADSET_STATE_CONNECTED; + headset_set_state(device, HEADSET_STATE_CONNECTED); else - hs->state = HEADSET_STATE_DISCONNECTED; + headset_set_state(device, HEADSET_STATE_DISCONNECTED); return FALSE; } @@ -676,7 +648,7 @@ failed: g_slist_foreach(hs->pending, (GFunc)pending_connect_failed, device); g_slist_free(hs->pending); hs->pending = NULL; - hs->state = HEADSET_STATE_DISCONNECTED; + headset_set_state(device, HEADSET_STATE_DISCONNECTED); device_finish_sdp_transaction(device); } @@ -778,7 +750,7 @@ failed: g_slist_foreach(hs->pending, (GFunc)pending_connect_failed, device); g_slist_free(hs->pending); hs->pending = NULL; - hs->state = HEADSET_STATE_DISCONNECTED; + headset_set_state(device, HEADSET_STATE_DISCONNECTED); } static int get_handles(struct device *device) @@ -809,7 +781,7 @@ static int get_handles(struct device *device) DBUS_TYPE_STRING, &hs_svc, DBUS_TYPE_INVALID); - hs->state = HEADSET_STATE_CONNECT_IN_PROGRESS; + headset_set_state(device, HEADSET_STATE_CONNECT_IN_PROGRESS); if (!dbus_connection_send_with_reply(device->conn, msg, &pending, -1)) { error("Sending GetRemoteServiceHandles failed"); dbus_message_unref(msg); @@ -919,18 +891,10 @@ static DBusHandlerResult hs_stop(DBusConnection *conn, DBusMessage *msg, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - switch(hs->state) { - case HEADSET_STATE_PLAYING: - case HEADSET_STATE_PLAY_IN_PROGRESS: - close_sco(device); - break; - case HEADSET_STATE_CONNECTED: - case HEADSET_STATE_CONNECT_IN_PROGRESS: - case HEADSET_STATE_DISCONNECTED: + if (hs->state < HEADSET_STATE_PLAY_IN_PROGRESS) return err_not_connected(conn, msg); - break; - } + headset_set_state(device, HEADSET_STATE_CONNECTED); send_message_and_unref(conn, reply); return DBUS_HANDLER_RESULT_HANDLED; @@ -970,19 +934,10 @@ static DBusHandlerResult hs_disconnect(DBusConnection *conn, DBusMessage *msg, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - switch(hs->state) { - case HEADSET_STATE_PLAYING: - case HEADSET_STATE_PLAY_IN_PROGRESS: - close_sco(device); - case HEADSET_STATE_CONNECTED: - case HEADSET_STATE_CONNECT_IN_PROGRESS: - headset_close_rfcomm(device); - break; - case HEADSET_STATE_DISCONNECTED: + if (hs->state == HEADSET_STATE_DISCONNECTED) return err_not_connected(conn, msg); - break; - } + headset_set_state(device, HEADSET_STATE_DISCONNECTED); ba2str(&device->dst, hs_address); info("Disconnected from %s, %s", hs_address, device->path); @@ -1500,11 +1455,6 @@ int headset_close_rfcomm(void *device) g_io_channel_close(hs->rfcomm); g_io_channel_unref(hs->rfcomm); hs->rfcomm = NULL; - hs->state = HEADSET_STATE_DISCONNECTED; - dbus_connection_emit_signal(dev->conn, dev->path, - AUDIO_HEADSET_INTERFACE, - "Disconnected", - DBUS_TYPE_INVALID); } hs->data_start = 0; @@ -1517,32 +1467,64 @@ void headset_set_state(void *device, headset_state_t state) { struct device *dev = (struct device *) device; struct headset *hs = dev->headset; + char str[13]; + + if (hs->state == state) + return; switch(state) { case HEADSET_STATE_DISCONNECTED: + close_sco(device); + headset_close_rfcomm(device); + dbus_connection_emit_signal(dev->conn, dev->path, + AUDIO_HEADSET_INTERFACE, + "Disconnected", + DBUS_TYPE_INVALID); + break; case HEADSET_STATE_CONNECT_IN_PROGRESS: break; case HEADSET_STATE_CONNECTED: - if (hs->rfcomm) { - char hs_address[18]; - + if (hs->state < state) { g_io_add_watch(hs->rfcomm, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc) rfcomm_io_cb, device); - ba2str(&((struct device *) device)->dst, hs_address); - dbus_connection_emit_signal(dev->conn, dev->path, AUDIO_HEADSET_INTERFACE, "Connected", DBUS_TYPE_INVALID); } + else { + close_sco(device); + dbus_connection_emit_signal(dev->conn, dev->path, + AUDIO_HEADSET_INTERFACE, + "Stopped", + DBUS_TYPE_INVALID); + } break; case HEADSET_STATE_PLAY_IN_PROGRESS: + break; case HEADSET_STATE_PLAYING: + g_io_add_watch(hs->sco, G_IO_ERR | G_IO_HUP | G_IO_NVAL, + (GIOFunc) sco_cb, device); + + dbus_connection_emit_signal(dev->conn, dev->path, + AUDIO_HEADSET_INTERFACE, + "Playing", DBUS_TYPE_INVALID); + + if (hs->sp_gain >= 0) { + snprintf(str, sizeof(str) - 1, "\r\n+VGS=%u\r\n", hs->sp_gain); + headset_send(hs, str); + } + + if (hs->mic_gain >= 0) { + snprintf(str, sizeof(str) - 1, "\r\n+VGM=%u\r\n", hs->sp_gain); + headset_send(hs, str); + } break; } + debug("State changed %s: %d -> %d", dev->path, hs->state, state); hs->state = state; } |