diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-02-15 08:35:16 +0000 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-02-15 08:35:16 +0000 | 
| commit | 7d163e45e7a5a22f7ac52982587704f6a3370e05 (patch) | |
| tree | b91c18ba3e6b21ad0e145344017dddc3272334c8 /audio/headset.c | |
| parent | c9395045adf8b1a3c4ed7407ec7f492417bc28f0 (diff) | |
More cleanup and fixes
Diffstat (limited to 'audio/headset.c')
| -rw-r--r-- | audio/headset.c | 172 | 
1 files changed, 81 insertions, 91 deletions
| diff --git a/audio/headset.c b/audio/headset.c index 82909701..79c85084 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -94,7 +94,7 @@ struct headset {  	int data_length;  	headset_state_t state; -	struct pending_connect *connect_in_progress; +	struct pending_connect *pending_connect;  };  struct manager { @@ -103,7 +103,6 @@ struct manager {  	GSList *headset_list;  }; -  static DBusConnection *connection = NULL;  static GMainLoop *main_loop = NULL; @@ -279,10 +278,8 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, gpointer data)  	gsize free_space;  	GIOError err; -	if (cond & G_IO_NVAL) { -		g_io_channel_unref(chan); +	if (cond & G_IO_NVAL)  		return FALSE; -	}  	if (cond & (G_IO_ERR | G_IO_HUP))  		goto failed; @@ -368,16 +365,14 @@ static gboolean server_io_cb(GIOChannel *chan, GIOCondition cond, void *data)  	assert(amanager != NULL); -	if (cond & G_IO_NVAL) { -		g_io_channel_unref(chan); +	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); -		amanager->server_sk = NULL; -		return TRUE; +		raise(SIGTERM); +		return FALSE;  	}  	srv_sk = g_io_channel_unix_get_fd(chan); @@ -417,6 +412,7 @@ static gboolean server_io_cb(GIOChannel *chan, GIOCondition cond, void *data)  	}  	g_io_add_watch(hs->rfcomm, G_IO_IN, (GIOFunc) rfcomm_io_cb, hs); +	g_io_channel_unref(hs->rfcomm);  	ba2str(&addr.rc_bdaddr, hs_address); @@ -481,14 +477,13 @@ static gboolean sco_input_to_audio_output_cb(GIOChannel *chan, GIOCondition cond  	gsize bytes_written, total_bytes_written;  	GIOError err; -	if (cond & G_IO_NVAL) { -		g_io_channel_unref(chan); +	if (cond & G_IO_NVAL)  		return FALSE; -	}  	if (cond & (G_IO_HUP | G_IO_ERR)) {  		error("Audio connection got disconnected");  		g_io_channel_close(chan); +		g_io_channel_unref(hs->sco);  		hs->sco = NULL;  		if (hs->audio_output) {  			g_io_channel_close(hs->audio_output); @@ -536,13 +531,11 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,  	DBusMessage *reply;  	socklen_t len; -	assert(hs != NULL && hs->connect_in_progress != NULL &&  -		hs->sco == NULL && hs->state == HEADSET_STATE_PLAY_IN_PROGRESS); - -	if (cond & G_IO_NVAL) { -		g_io_channel_unref(chan); +	if (cond & G_IO_NVAL)  		return FALSE; -	} + +	assert(hs != NULL && hs->pending_connect != NULL &&  +		hs->sco == NULL && hs->state == HEADSET_STATE_PLAY_IN_PROGRESS);  	sk = g_io_channel_unix_get_fd(chan); @@ -562,13 +555,13 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,  	debug("SCO socket opened for headset %s", hs->object_path);  	hs->sco = chan; -	hs->connect_in_progress->io = NULL; +	hs->pending_connect->io = NULL;  	flags = hs->audio_output ? G_IO_IN : 0;  	g_io_add_watch(hs->sco, flags, sco_input_to_audio_output_cb, hs); -	if (hs->connect_in_progress->msg) { -		reply = dbus_message_new_method_return(hs->connect_in_progress->msg); +	if (hs->pending_connect->msg) { +		reply = dbus_message_new_method_return(hs->pending_connect->msg);  		if (reply)  			send_message_and_unref(connection, reply);  	} @@ -577,8 +570,8 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,  	if (hs->audio_input)  		g_io_add_watch(hs->audio_input, G_IO_IN, audio_input_to_sco_cb, hs); -	pending_connect_free(hs->connect_in_progress); -	hs->connect_in_progress = NULL; +	pending_connect_free(hs->pending_connect); +	hs->pending_connect = NULL;  	hs->state = HEADSET_STATE_PLAYING;  	hs_signal(hs, "Playing"); @@ -586,10 +579,12 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,  	return FALSE;  failed: -	if (hs->connect_in_progress) { -		err_connect_failed(hs->connect_in_progress->conn, hs->connect_in_progress->msg, err); -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL; +	if (hs->pending_connect) { +		err_connect_failed(hs->pending_connect->conn, hs->pending_connect->msg, err); +		if (hs->pending_connect->io) +			g_io_channel_close(hs->pending_connect->io); +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;  	}  	assert(hs->rfcomm); @@ -604,15 +599,13 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond, struct he  	int sk, ret, err;  	socklen_t len; -	assert(hs != NULL && hs->connect_in_progress != NULL &&  +	if (cond & G_IO_NVAL) +		return FALSE; + +	assert(hs != NULL && hs->pending_connect != NULL &&   			hs->rfcomm == NULL &&  			hs->state == HEADSET_STATE_CONNECT_IN_PROGRESS); -	if (cond & G_IO_NVAL) { -		g_io_channel_unref(chan); -		return FALSE; -	} -  	sk = g_io_channel_unix_get_fd(chan);  	len = sizeof(ret); @@ -630,6 +623,7 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond, struct he  	ba2str(&hs->bda, hs_address);  	hs->rfcomm = chan; +	hs->pending_connect->io = NULL;  	hs->state = HEADSET_STATE_CONNECTED;  	hs_signal(hs, "Connected"); @@ -638,23 +632,25 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond, struct he  	g_io_add_watch(chan, G_IO_IN, (GIOFunc) rfcomm_io_cb, hs); -	if (hs->connect_in_progress->msg) { +	if (hs->pending_connect->msg) {  		DBusMessage *reply; -		reply = dbus_message_new_method_return(hs->connect_in_progress->msg); +		reply = dbus_message_new_method_return(hs->pending_connect->msg);  		if (reply)  			send_message_and_unref(connection, reply); -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL; +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;  	}  	return FALSE;  failed: -	if (hs->connect_in_progress) { -		err_connect_failed(hs->connect_in_progress->conn, hs->connect_in_progress->msg, err); -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL; +	if (hs->pending_connect) { +		err_connect_failed(hs->pending_connect->conn, hs->pending_connect->msg, err); +		if (hs->pending_connect->io) +			g_io_channel_close(hs->pending_connect->io); +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;  	}  	hs->state = HEADSET_STATE_DISCONNECTED; @@ -668,12 +664,12 @@ static int rfcomm_connect(struct headset *hs, int *err)  	char address[18];  	int sk; -	assert(hs != NULL && hs->connect_in_progress != NULL &&  +	assert(hs != NULL && hs->pending_connect != NULL &&   			hs->state == HEADSET_STATE_CONNECT_IN_PROGRESS);  	ba2str(&hs->bda, address); -	debug("Connecting to %s channel %d", address, hs->connect_in_progress->ch); +	debug("Connecting to %s channel %d", address, hs->pending_connect->ch);  	sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);  	if (sk < 0) { @@ -703,14 +699,13 @@ static int rfcomm_connect(struct headset *hs, int *err)  	memset(&addr, 0, sizeof(addr));  	addr.rc_family = AF_BLUETOOTH;  	bacpy(&addr.rc_bdaddr, &hs->bda); -	addr.rc_channel = hs->connect_in_progress->ch; +	addr.rc_channel = hs->pending_connect->ch; -	hs->connect_in_progress->io = g_io_channel_unix_new(sk); -	if (!hs->connect_in_progress->io) { +	hs->pending_connect->io = g_io_channel_unix_new(sk); +	if (!hs->pending_connect->io) {  		error("channel_unix_new failed in rfcomm connect");  		goto failed;  	} -	g_io_channel_set_close_on_unref(hs->connect_in_progress->io, TRUE);  	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {  		if (!(errno == EAGAIN || errno == EINPROGRESS)) { @@ -722,22 +717,18 @@ static int rfcomm_connect(struct headset *hs, int *err)  		debug("Connect in progress"); -		g_io_add_watch(hs->connect_in_progress->io, G_IO_OUT, (GIOFunc) rfcomm_connect_cb, hs); +		g_io_add_watch(hs->pending_connect->io, G_IO_OUT, (GIOFunc) rfcomm_connect_cb, hs);  	} else {  		debug("Connect succeeded with first try"); -		rfcomm_connect_cb(hs->connect_in_progress->io, G_IO_OUT, hs); +		rfcomm_connect_cb(hs->pending_connect->io, G_IO_OUT, hs);  	}  	return 0;  failed: -	if (hs->connect_in_progress->io) { -		g_io_channel_close(hs->connect_in_progress->io); -		hs->connect_in_progress->io = NULL; -	} else { -		if (sk >= 0) -			close(sk); -	} +	if (!hs->pending_connect->io && sk >= 0) +		close(sk); +  	return -1;  } @@ -932,8 +923,8 @@ static void get_record_reply(DBusPendingCall *call, void *data)  	struct headset *hs = data;  	struct pending_connect *c; -	assert(hs != NULL && hs->connect_in_progress && !hs->rfcomm); -	c = hs->connect_in_progress; +	assert(hs != NULL && hs->pending_connect && !hs->rfcomm); +	c = hs->pending_connect;  	reply = dbus_pending_call_steal_reply(call); @@ -1005,8 +996,8 @@ failed:  		sdp_record_free(record);  	if (reply)  		dbus_message_unref(reply); -	pending_connect_free(hs->connect_in_progress); -	hs->connect_in_progress = NULL; +	pending_connect_free(hs->pending_connect); +	hs->pending_connect = NULL;  	hs->state = HEADSET_STATE_DISCONNECTED;  } @@ -1028,18 +1019,21 @@ static DBusHandlerResult hs_disconnect(struct headset *hs, DBusMessage *msg)  	if (hs->rfcomm) {  		g_io_channel_close(hs->rfcomm); +		g_io_channel_unref(hs->rfcomm);  		hs->rfcomm = NULL;  	} -	if (hs->connect_in_progress) { -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL; +	if (hs->pending_connect) { +		if (hs->pending_connect->io) +			g_io_channel_close(hs->pending_connect->io); +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;  	}  	hs->state = HEADSET_STATE_DISCONNECTED;  	ba2str(&hs->bda, hs_address); -	info("Disconnected from %s, %s", &hs_address, hs->object_path ? hs->object_path : "null"); +	info("Disconnected from %s, %s", &hs_address, hs->object_path);  	hs_signal(hs, "Disconnected"); @@ -1061,8 +1055,8 @@ static void get_handles_reply(DBusPendingCall *call, void *data)  	dbus_uint32_t handle;  	int array_len; -	assert(hs != NULL && hs->connect_in_progress); -	c = hs->connect_in_progress; +	assert(hs != NULL && hs->pending_connect); +	c = hs->pending_connect;  	reply = dbus_pending_call_steal_reply(call); @@ -1158,29 +1152,29 @@ static DBusHandlerResult hs_connect(struct headset *hs, DBusMessage *msg)  		error("This headset has not been audiothorized");  	} -	if (hs->state > HEADSET_STATE_DISCONNECTED || hs->connect_in_progress) { +	if (hs->state > HEADSET_STATE_DISCONNECTED || hs->pending_connect) {  		error("Already connected");  		return DBUS_HANDLER_RESULT_HANDLED;  	} -	hs->connect_in_progress = g_try_new0(struct pending_connect, 1); -	if (!hs->connect_in_progress) { +	hs->pending_connect = g_try_new0(struct pending_connect, 1); +	if (!hs->pending_connect) {  		error("Out of memory when allocating new struct pending_connect");  		return DBUS_HANDLER_RESULT_NEED_MEMORY;  	}  	hs->state = HEADSET_STATE_CONNECT_IN_PROGRESS; -	hs->connect_in_progress->conn = dbus_connection_ref(connection); -	hs->connect_in_progress->msg = msg ? dbus_message_ref(msg) : NULL; +	hs->pending_connect->conn = dbus_connection_ref(connection); +	hs->pending_connect->msg = msg ? dbus_message_ref(msg) : NULL;  	msg = dbus_message_new_method_call("org.bluez", "/org/bluez/hci0",  						"org.bluez.Adapter",  						"GetRemoteServiceHandles");  	if (!msg) {  		error("Could not create a new dbus message"); -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL; +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;  		hs->state = HEADSET_STATE_DISCONNECTED;  		return DBUS_HANDLER_RESULT_NEED_MEMORY;  	} @@ -1193,8 +1187,8 @@ static DBusHandlerResult hs_connect(struct headset *hs, DBusMessage *msg)  	if (!dbus_connection_send_with_reply(connection, msg, &pending, -1)) {  		error("Sending GetRemoteServiceHandles failed"); -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL; +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;  		hs->state = HEADSET_STATE_DISCONNECTED;  		dbus_message_unref(msg);  		return err_connect_failed(connection, msg, EIO); @@ -1318,20 +1312,19 @@ static DBusHandlerResult hs_play(struct headset *hs, DBusMessage *msg)  	if (hs->state < HEADSET_STATE_CONNECTED)  		return err_not_connected(connection, msg); /* FIXME: in progress error? */ -	if (hs->state >= HEADSET_STATE_PLAY_IN_PROGRESS || hs->connect_in_progress) +	if (hs->state >= HEADSET_STATE_PLAY_IN_PROGRESS || hs->pending_connect)  		return err_already_connected(connection, msg);  	if (hs->sco)  		return err_already_connected(connection, msg); -	hs->connect_in_progress = malloc(sizeof(struct pending_connect)); -	if (!hs->connect_in_progress) +	hs->pending_connect = g_try_new0(struct pending_connect, 1); +	if (!hs->pending_connect)  		return DBUS_HANDLER_RESULT_NEED_MEMORY;  	hs->state = HEADSET_STATE_PLAY_IN_PROGRESS; -	memset(hs->connect_in_progress, 0, sizeof(struct pending_connect)); -	c = hs->connect_in_progress; +	c = hs->pending_connect;  	c->conn = dbus_connection_ref(connection);  	c->msg = msg ? dbus_message_ref(msg) : NULL; @@ -1350,8 +1343,6 @@ static DBusHandlerResult hs_play(struct headset *hs, DBusMessage *msg)  		return DBUS_HANDLER_RESULT_NEED_MEMORY;  	} -	g_io_channel_set_close_on_unref(c->io, TRUE); -  	memset(&addr, 0, sizeof(addr));  	addr.sco_family = AF_BLUETOOTH;  	bacpy(&addr.sco_bdaddr, BDADDR_ANY); @@ -1391,9 +1382,9 @@ static DBusHandlerResult hs_play(struct headset *hs, DBusMessage *msg)  	return 0;  failed: -	if (hs->connect_in_progress) { -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL;  +	if (hs->pending_connect) { +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;   	}  	return DBUS_HANDLER_RESULT_HANDLED;  } @@ -1411,9 +1402,10 @@ static DBusHandlerResult hs_stop(struct headset *hs, DBusMessage *msg)  			return DBUS_HANDLER_RESULT_NEED_MEMORY;  	} -	if (hs->state == HEADSET_STATE_PLAY_IN_PROGRESS && hs->connect_in_progress) { -		pending_connect_free(hs->connect_in_progress); -		hs->connect_in_progress = NULL; +	if (hs->state == HEADSET_STATE_PLAY_IN_PROGRESS && hs->pending_connect) { +		g_io_channel_close(hs->pending_connect->io); +		pending_connect_free(hs->pending_connect); +		hs->pending_connect = NULL;  		hs->state = HEADSET_STATE_CONNECTED;  	} @@ -1643,8 +1635,6 @@ gboolean audio_manager_create_headset_server(struct manager *amanager, uint8_t c  		return FALSE;  	} -	g_io_channel_set_close_on_unref(amanager->server_sk, TRUE); -  	g_io_add_watch(amanager->server_sk, G_IO_IN, (GIOFunc) server_io_cb, amanager);  	return TRUE; | 
