summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2007-06-29 19:49:47 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2007-06-29 19:49:47 +0000
commitb57f22a505f7c46662bfd5900df38dd68099df2c (patch)
tree7909dc22b6dd93e8b84fb731d6d79ac3247088eb
parent389d6a32fa14abefec394b9ebfa3b2deb51489c7 (diff)
Fix concurrent pending connections, properly checks state machine and lot of code cleanup.
-rw-r--r--audio/headset.c411
1 files changed, 195 insertions, 216 deletions
diff --git a/audio/headset.c b/audio/headset.c
index 2e285aa9..28f6ac1d 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -64,9 +64,10 @@
struct pending_connect {
DBusMessage *msg;
GIOChannel *io;
+ struct ipc_packet *pkt;
guint io_id;
int sock;
- struct ipc_packet *pkt;
+ int err;
};
struct headset {
@@ -87,20 +88,22 @@ struct headset {
headset_type_t type;
headset_state_t state;
- struct pending_connect *pending_connect;
+ GSList *pending;
int sp_gain;
int mic_gain;
};
-static DBusHandlerResult hs_disconnect(DBusConnection *conn, DBusMessage *msg,
- void *data);
static int rfcomm_connect(struct device *device, struct pending_connect *c);
static void pending_connect_free(struct pending_connect *c)
{
- if (c->io)
+ if (c->pkt)
+ unix_send_cfg(c->sock, c->pkt);
+ if (c->io) {
+ g_io_channel_close(c->io);
g_io_channel_unref(c->io);
+ }
if (c->msg)
dbus_message_unref(c->msg);
g_free(c);
@@ -174,13 +177,16 @@ static void close_sco(struct device *device)
{
struct headset *hs = device->headset;
- 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);
+ if (hs->sco) {
+ 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);
+ }
}
static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond,
@@ -280,9 +286,8 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond,
return TRUE;
failed:
- if (hs->sco)
- close_sco(device);
- hs_disconnect(NULL, NULL, device);
+ close_sco(device);
+ headset_close_rfcomm(device);
return FALSE;
}
@@ -299,8 +304,7 @@ static gboolean sco_cb(GIOChannel *chan, GIOCondition cond,
error("Audio connection got disconnected");
- if (hs->sco)
- close_sco(device);
+ close_sco(device);
return FALSE;
}
@@ -329,19 +333,41 @@ static GIOError headset_send(struct headset *hs, const char *str)
return G_IO_ERROR_NONE;
}
+static void pending_connect_ok(struct pending_connect *c, struct device *dev)
+{
+ DBusMessage *reply;
+
+ if (c->msg) {
+ reply = dbus_message_new_method_return(c->msg);
+ if (reply)
+ send_message_and_unref(dev->conn, reply);
+ }
+ else if (c->pkt)
+ headset_get_config(dev, c->sock, c->pkt);
+ pending_connect_free(c);
+}
+
+static void pending_connect_failed(struct pending_connect *c, struct device *dev)
+{
+ if (c->msg)
+ err_connect_failed(dev->conn, c->msg, strerror(c->err));
+ pending_connect_free(c);
+}
+
static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,
struct device *device)
{
struct headset *hs;
+ struct pending_connect *c;
int ret, sk, err, flags;
socklen_t len;
- DBusMessage *reply;
char str[13];
if (cond & G_IO_NVAL)
return FALSE;
hs = device->headset;
+ c = hs->pending->data;
sk = g_io_channel_unix_get_fd(chan);
@@ -362,27 +388,15 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,
info("SCO fd=%d", sk);
hs->sco = chan;
- hs->pending_connect->io = NULL;
+ c->io = NULL;
flags = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
g_io_add_watch(hs->sco, flags, (GIOFunc) sco_cb, device);
- if (hs->pending_connect->msg) {
- reply = dbus_message_new_method_return(hs->pending_connect->msg);
- if (reply)
- send_message_and_unref(device->conn, reply);
- }
- else if (hs->pending_connect->pkt) {
- headset_get_config(device, hs->pending_connect->sock,
- hs->pending_connect->pkt);
- unix_send_cfg(hs->pending_connect->sock,
- hs->pending_connect->pkt);
- }
-
- pending_connect_free(hs->pending_connect);
- hs->pending_connect = NULL;
-
+ 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;
@@ -403,16 +417,9 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
failed:
- if (hs->pending_connect->msg)
- err_connect_failed(device->conn, hs->pending_connect->msg,
- strerror(err));
- if (hs->pending_connect->io)
- g_io_channel_close(hs->pending_connect->io);
- if (hs->pending_connect->pkt)
- unix_send_cfg(hs->pending_connect->sock,
- hs->pending_connect->pkt);
- pending_connect_free(hs->pending_connect);
- hs->pending_connect = NULL;
+ g_slist_foreach(hs->pending, (GFunc)pending_connect_failed, device);
+ g_slist_free(hs->pending);
+ hs->pending = NULL;
hs->state = HEADSET_STATE_CONNECTED;
return FALSE;
@@ -425,6 +432,12 @@ static int sco_connect(struct device *device, struct pending_connect *c)
gboolean do_callback = FALSE;
int sk, err;
+ if (!g_slist_find(hs->pending, c))
+ hs->pending = g_slist_append(hs->pending, c);
+
+ if (hs->state != HEADSET_STATE_CONNECTED)
+ return 0;
+
sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
if (sk < 0) {
err = errno;
@@ -474,7 +487,8 @@ static int sco_connect(struct device *device, struct pending_connect *c)
}
hs->state = HEADSET_STATE_PLAY_IN_PROGRESS;
- hs->pending_connect = c;
+ if (!g_slist_find(hs->pending, c))
+ hs->pending = g_slist_append(hs->pending, c);
if (do_callback)
sco_connect_cb(c->io, G_IO_OUT, device);
@@ -486,6 +500,7 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond,
struct device *device)
{
struct headset *hs;
+ struct pending_connect *c;
char hs_address[18];
int sk, ret, err = 0;
socklen_t len;
@@ -494,6 +509,7 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
hs = device->headset;
+ c = hs->pending->data;
sk = g_io_channel_unix_get_fd(chan);
@@ -512,7 +528,7 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond,
ba2str(&device->dst, hs_address);
hs->rfcomm = chan;
- hs->pending_connect->io = NULL;
+ c->io = NULL;
hs->state = HEADSET_STATE_CONNECTED;
dbus_connection_emit_signal(device->conn, device->path,
@@ -525,39 +541,26 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond,
g_io_add_watch(chan, G_IO_IN | G_IO_ERR | G_IO_HUP| G_IO_NVAL,
(GIOFunc) rfcomm_io_cb, device);
- if (hs->pending_connect->msg) {
- DBusMessage *reply;
-
- reply = dbus_message_new_method_return(hs->pending_connect->msg);
- if (reply)
- send_message_and_unref(device->conn, reply);
- }
- else if (hs->pending_connect->pkt) {
- if (sco_connect(device, hs->pending_connect) < 0)
+ if (c->pkt) {
+ if (sco_connect(device, c) < 0)
goto failed;
return FALSE;
}
- pending_connect_free(hs->pending_connect);
- hs->pending_connect = NULL;
+ g_slist_foreach(hs->pending, (GFunc)pending_connect_ok, device);
+ g_slist_free(hs->pending);
+ hs->pending = NULL;
return FALSE;
failed:
- if (hs->pending_connect->msg)
- err_connect_failed(device->conn, hs->pending_connect->msg,
- strerror(err));
- if (hs->pending_connect->pkt)
- unix_send_cfg(hs->pending_connect->sock,
- hs->pending_connect->pkt);
- if (hs->pending_connect->io)
- g_io_channel_close(hs->pending_connect->io);
+ g_slist_foreach(hs->pending, (GFunc)pending_connect_failed, device);
+ g_slist_free(hs->pending);
+ hs->pending = NULL;
if (hs->rfcomm)
hs->state = HEADSET_STATE_CONNECTED;
else
hs->state = HEADSET_STATE_DISCONNECTED;
- pending_connect_free(hs->pending_connect);
- hs->pending_connect = NULL;
return FALSE;
}
@@ -575,7 +578,7 @@ static void get_record_reply(DBusPendingCall *call, void *data)
struct headset *hs = device->headset;
struct pending_connect *c;
- c = hs->pending_connect;
+ c = hs->pending->data;
reply = dbus_pending_call_steal_reply(call);
@@ -670,8 +673,9 @@ failed:
sdp_record_free(record);
if (reply)
dbus_message_unref(reply);
- pending_connect_free(hs->pending_connect);
- hs->pending_connect = NULL;
+ g_slist_foreach(hs->pending, (GFunc)pending_connect_failed, device);
+ g_slist_free(hs->pending);
+ hs->pending = NULL;
hs->state = HEADSET_STATE_DISCONNECTED;
device_finish_sdp_transaction(device);
}
@@ -689,7 +693,7 @@ static void get_handles_reply(DBusPendingCall *call, void *data)
dbus_uint32_t handle;
int array_len;
- c = hs->pending_connect;
+ c = hs->pending->data;
reply = dbus_pending_call_steal_reply(call);
@@ -771,7 +775,10 @@ failed:
if (msg)
dbus_message_unref(msg);
dbus_message_unref(reply);
- hs_disconnect(NULL, NULL, device);
+ g_slist_foreach(hs->pending, (GFunc)pending_connect_failed, device);
+ g_slist_free(hs->pending);
+ hs->pending = NULL;
+ hs->state = HEADSET_STATE_DISCONNECTED;
}
static int get_handles(struct device *device)
@@ -824,15 +831,18 @@ static int rfcomm_connect(struct device *device, struct pending_connect *c)
int sk, err;
if (c != NULL) {
- hs->pending_connect = c;
- hs->type = hs->hfp_handle ? SVC_HANDSFREE : SVC_HEADSET;
+ if (!g_slist_find(hs->pending, c))
+ hs->pending = g_slist_append(hs->pending, c);
- if (hs->state != HEADSET_STATE_DISCONNECTED)
- return -EBUSY;
+ hs->type = hs->hfp_handle ? SVC_HANDSFREE : SVC_HEADSET;
- if (hs->rfcomm_ch < 0)
+ if (hs->state == HEADSET_STATE_DISCONNECTED)
return get_handles(device);
+ else
+ return 0;
}
+ else
+ c = hs->pending->data;
ba2str(&device->dst, address);
@@ -866,8 +876,8 @@ static int rfcomm_connect(struct device *device, struct pending_connect *c)
bacpy(&addr.rc_bdaddr, &device->dst);
addr.rc_channel = hs->rfcomm_ch;
- hs->pending_connect->io = g_io_channel_unix_new(sk);
- if (!hs->pending_connect->io) {
+ c->io = g_io_channel_unix_new(sk);
+ if (!c->io) {
err = ENOMEM;
error("channel_unix_new failed in rfcomm connect");
goto failed;
@@ -882,17 +892,17 @@ static int rfcomm_connect(struct device *device, struct pending_connect *c)
debug("Connect in progress");
- g_io_add_watch(hs->pending_connect->io, G_IO_OUT | G_IO_NVAL,
+ g_io_add_watch(c->io, G_IO_OUT | G_IO_NVAL,
(GIOFunc) rfcomm_connect_cb, device);
} else {
debug("Connect succeeded with first try");
- rfcomm_connect_cb(hs->pending_connect->io, G_IO_OUT, device);
+ rfcomm_connect_cb(c->io, G_IO_OUT, device);
}
return 0;
failed:
- if (!hs->pending_connect->io && sk >= 0)
+ if (!c->io && sk >= 0)
close(sk);
return -err;
@@ -905,30 +915,23 @@ static DBusHandlerResult hs_stop(DBusConnection *conn, DBusMessage *msg,
struct headset *hs = device->headset;
DBusMessage *reply = NULL;
- if (!hs || !hs->sco)
- return err_not_connected(conn, msg);
-
- if (msg) {
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (hs->state == HEADSET_STATE_PLAY_IN_PROGRESS &&
- hs->pending_connect) {
- g_io_channel_close(hs->pending_connect->io);
- if (hs->pending_connect->msg)
- err_connect_failed(conn, hs->pending_connect->msg,
- strerror(EINTR));
- pending_connect_free(hs->pending_connect);
- hs->pending_connect = NULL;
- hs->state = HEADSET_STATE_CONNECTED;
+ 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:
+ return err_not_connected(conn, msg);
+ break;
}
- close_sco(device);
-
- if (reply)
- send_message_and_unref(conn, reply);
+ send_message_and_unref(conn, reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -945,10 +948,7 @@ static DBusHandlerResult hs_is_playing(DBusConnection *conn, DBusMessage *msg,
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (hs->state == HEADSET_STATE_PLAYING)
- playing = TRUE;
- else
- playing = FALSE;
+ playing = (hs->state == HEADSET_STATE_PLAYING);
dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &playing,
DBUS_TYPE_INVALID);
@@ -966,53 +966,27 @@ static DBusHandlerResult hs_disconnect(DBusConnection *conn, DBusMessage *msg,
DBusMessage *reply = NULL;
char hs_address[18];
- if (msg) {
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
-
- if (hs->state > HEADSET_STATE_CONNECTED)
- hs_stop(NULL, NULL, device);
-
- if (hs->ring_timer) {
- g_source_remove(hs->ring_timer);
- hs->ring_timer = 0;
- }
-
- if (hs->rfcomm) {
- g_io_channel_close(hs->rfcomm);
- g_io_channel_unref(hs->rfcomm);
- hs->rfcomm = NULL;
- }
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (hs->pending_connect) {
- if (hs->pending_connect->io)
- g_io_channel_close(hs->pending_connect->io);
- if (hs->pending_connect->io_id)
- g_source_remove(hs->pending_connect->io_id);
- if (hs->pending_connect->msg)
- err_connect_failed(conn,
- hs->pending_connect->msg,
- strerror(EINTR));
- pending_connect_free(hs->pending_connect);
- hs->pending_connect = NULL;
+ 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:
+ return err_not_connected(conn, msg);
+ break;
}
- hs->state = HEADSET_STATE_DISCONNECTED;
-
ba2str(&device->dst, hs_address);
info("Disconnected from %s, %s", hs_address, device->path);
- dbus_connection_emit_signal(device->conn, device->path,
- AUDIO_HEADSET_INTERFACE,
- "Disconnected", DBUS_TYPE_INVALID);
-
- hs->data_start = 0;
- hs->data_length = 0;
-
- if (reply)
- send_message_and_unref(conn, reply);
+ send_message_and_unref(conn, reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -1047,7 +1021,7 @@ static DBusHandlerResult hs_connect(DBusConnection *conn, DBusMessage *msg,
struct pending_connect *c;
int err;
- if (hs->state > HEADSET_STATE_DISCONNECTED || hs->pending_connect)
+ if (hs->state > HEADSET_STATE_DISCONNECTED)
return err_already_connected(conn, msg);
c = g_try_new0(struct pending_connect, 1);
@@ -1063,8 +1037,7 @@ static DBusHandlerResult hs_connect(DBusConnection *conn, DBusMessage *msg,
return DBUS_HANDLER_RESULT_HANDLED;
error:
- if (c)
- pending_connect_free(c);
+ pending_connect_free(c);
return err_connect_failed(conn, msg, strerror(-err));
}
@@ -1088,11 +1061,9 @@ static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg,
if (hs->state < HEADSET_STATE_CONNECTED)
return err_not_connected(conn, msg);
- if (msg) {
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
if (hs->ring_timer) {
debug("IndicateCall received when already indicating");
@@ -1107,8 +1078,7 @@ static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg,
hs->ring_timer = g_timeout_add(RING_INTERVAL, ring_timer_cb, device);
done:
- if (reply)
- send_message_and_unref(conn, reply);
+ send_message_and_unref(conn, reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -1124,11 +1094,9 @@ static DBusHandlerResult hs_cancel_ringing(DBusConnection *conn,
if (hs->state < HEADSET_STATE_CONNECTED)
return err_not_connected(conn, msg);
- if (msg) {
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- }
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
if (!hs->ring_timer) {
debug("Got CancelRinging method call but ringing is not in progress");
@@ -1139,8 +1107,7 @@ static DBusHandlerResult hs_cancel_ringing(DBusConnection *conn,
hs->ring_timer = 0;
done:
- if (reply)
- send_message_and_unref(conn, reply);
+ send_message_and_unref(conn, reply);
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -1156,10 +1123,7 @@ static DBusHandlerResult hs_play(DBusConnection *conn, DBusMessage *msg,
if (hs->state < HEADSET_STATE_CONNECTED)
return err_not_connected(conn, msg);
- if (hs->state >= HEADSET_STATE_PLAY_IN_PROGRESS || hs->pending_connect)
- return err_already_connected(conn, msg);
-
- if (hs->sco)
+ if (hs->state >= HEADSET_STATE_PLAY_IN_PROGRESS)
return err_already_connected(conn, msg);
c = g_try_new0(struct pending_connect, 1);
@@ -1398,71 +1362,71 @@ void headset_update(void *device, sdp_record_t *record, uint16_t svc)
struct headset *headset_init(void *device, sdp_record_t *record,
uint16_t svc)
{
- struct headset *headset;
+ struct device *dev = (struct device *) device;
+ struct headset *hs;
- headset = g_new0(struct headset, 1);
- headset->rfcomm_ch = -1;
- headset->sp_gain = -1;
- headset->mic_gain = -1;
+ hs = g_new0(struct headset, 1);
+ hs->rfcomm_ch = -1;
+ hs->sp_gain = -1;
+ hs->mic_gain = -1;
if (!record)
goto register_iface;
switch (svc) {
case HANDSFREE_SVCLASS_ID:
- headset->hfp_handle = record->handle;
+ hs->hfp_handle = record->handle;
break;
case HEADSET_SVCLASS_ID:
- headset->hsp_handle = record->handle;
+ hs->hsp_handle = record->handle;
break;
default:
debug("Invalid record passed to headset_init");
- g_free(headset);
+ g_free(hs);
return NULL;
}
- headset_set_channel(headset, record);
+ headset_set_channel(hs, record);
register_iface:
- if (!dbus_connection_register_interface(((struct device *) device)->conn,
- ((struct device *) device)->path,
+ if (!dbus_connection_register_interface(dev->conn, dev->path,
AUDIO_HEADSET_INTERFACE,
headset_methods,
headset_signals, NULL)) {
- g_free(headset);
+ g_free(hs);
return NULL;
}
- return headset;
+ return hs;
}
void headset_free(void *device)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct headset *hs = ((struct device *) device)->headset;
- if (headset->sco) {
- g_io_channel_close(headset->sco);
- g_io_channel_unref(headset->sco);
+ if (hs->sco) {
+ g_io_channel_close(hs->sco);
+ g_io_channel_unref(hs->sco);
}
- if (headset->rfcomm) {
- g_io_channel_close(headset->rfcomm);
- g_io_channel_unref(headset->rfcomm);
+ if (hs->rfcomm) {
+ g_io_channel_close(hs->rfcomm);
+ g_io_channel_unref(hs->rfcomm);
}
- g_free(headset);
- headset = NULL;
+ g_free(hs);
+ hs = NULL;
}
int headset_get_config(void *device, int sock, struct ipc_packet *pkt)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct headset *hs = ((struct device *) device)->headset;
struct ipc_data_cfg *cfg = (struct ipc_data_cfg *) pkt->data;
int err = EINVAL;
struct pending_connect *c;
- if (headset->rfcomm == NULL) {
+ if (hs->rfcomm == NULL) {
c = g_try_new0(struct pending_connect, 1);
if (c == NULL)
goto error;
@@ -1472,7 +1436,7 @@ int headset_get_config(void *device, int sock, struct ipc_packet *pkt)
goto error;
return 0;
}
- else if (headset->sco == NULL) {
+ else if (hs->sco == NULL) {
c = g_try_new0(struct pending_connect, 1);
if (c == NULL)
goto error;
@@ -1483,7 +1447,7 @@ int headset_get_config(void *device, int sock, struct ipc_packet *pkt)
return 0;
}
- cfg->fd = g_io_channel_unix_get_fd(headset->sco);
+ cfg->fd = g_io_channel_unix_get_fd(hs->sco);
cfg->fd_opt = CFG_FD_OPT_READWRITE;
cfg->encoding = 0;
cfg->bitpool = 0;
@@ -1502,58 +1466,73 @@ error:
headset_type_t headset_get_type(void *device)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct headset *hs = ((struct device *) device)->headset;
- return headset->type;
+ return hs->type;
}
void headset_set_type(void *device, headset_type_t type)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct headset *hs = ((struct device *) device)->headset;
- headset->type = type;
+ hs->type = type;
}
int headset_connect_rfcomm(void *device, int sock)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct headset *hs = ((struct device *) device)->headset;
- headset->rfcomm = g_io_channel_unix_new(sock);
+ hs->rfcomm = g_io_channel_unix_new(sock);
- return headset->rfcomm ? 0 : -EINVAL;
+ return hs->rfcomm ? 0 : -EINVAL;
}
int headset_close_rfcomm(void *device)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct device *dev = (struct device *) device;
+ struct headset *hs = dev->headset;
- g_io_channel_close(headset->rfcomm);
- g_io_channel_unref(headset->rfcomm);
- headset->rfcomm = NULL;
+ if (hs->ring_timer) {
+ g_source_remove(hs->ring_timer);
+ hs->ring_timer = 0;
+ }
+ if (hs->rfcomm) {
+ 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;
+ hs->data_length = 0;
return 0;
}
void headset_set_state(void *device, headset_state_t state)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct device *dev = (struct device *) device;
+ struct headset *hs = dev->headset;
switch(state) {
case HEADSET_STATE_DISCONNECTED:
case HEADSET_STATE_CONNECT_IN_PROGRESS:
break;
case HEADSET_STATE_CONNECTED:
- if (headset->rfcomm) {
+ if (hs->rfcomm) {
char hs_address[18];
- g_io_add_watch(headset->rfcomm,
+ 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(((struct device *) device)->conn,
- ((struct device *) device)->path,
+ dbus_connection_emit_signal(dev->conn, dev->path,
AUDIO_HEADSET_INTERFACE,
"Connected",
DBUS_TYPE_INVALID);
@@ -1564,19 +1543,19 @@ void headset_set_state(void *device, headset_state_t state)
break;
}
- headset->state = state;
+ hs->state = state;
}
headset_state_t headset_get_state(void *device)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct headset *hs = ((struct device *) device)->headset;
- return headset->state;
+ return hs->state;
}
int headset_get_channel(void *device)
{
- struct headset *headset = ((struct device *) device)->headset;
+ struct headset *hs = ((struct device *) device)->headset;
- return headset->rfcomm_ch;
+ return hs->rfcomm_ch;
}