summaryrefslogtreecommitdiffstats
path: root/audio/headset.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/headset.c')
-rw-r--r--audio/headset.c124
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;
}