diff options
| -rw-r--r-- | audio/headset.c | 64 | ||||
| -rw-r--r-- | audio/headset.h | 4 | ||||
| -rw-r--r-- | audio/manager.c | 38 | 
3 files changed, 54 insertions, 52 deletions
diff --git a/audio/headset.c b/audio/headset.c index 2120a60f..e923fd68 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -404,6 +404,9 @@ static void pending_connect_finalize(struct audio_device *dev)  	struct headset *hs = dev->headset;  	struct pending_connect *p = hs->pending; +	if (p == NULL) +		return; +  	g_slist_foreach(p->callbacks, (GFunc) pending_connect_complete, dev);  	g_slist_foreach(p->callbacks, (GFunc) g_free, NULL); @@ -1228,7 +1231,7 @@ static gboolean sco_cb(GIOChannel *chan, GIOCondition cond,  	return FALSE;  } -static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) +void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)  {  	struct audio_device *dev = user_data;  	struct headset *hs = dev->headset; @@ -1240,9 +1243,25 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)  		goto failed;  	} +	/* For HFP telephony isn't ready just disconnect */ +	if (hs->hfp_active && !ag.telephony_ready) { +		error("Unable to accept HFP connection since the telephony " +				"subsystem isn't initialized"); +		goto failed; +	} + +	if (hs->tmp_rfcomm) { +		hs->rfcomm = hs->tmp_rfcomm; +		hs->tmp_rfcomm = NULL; +	} else +		hs->rfcomm = g_io_channel_ref(chan); +  	ba2str(&dev->dst, hs_address); -	hs->rfcomm = g_io_channel_ref(chan); -	p->io = NULL; + +	if (p) +		p->io = NULL; +	else +		hs->auto_dc = FALSE;  	if (server_is_enabled(&dev->src, HANDSFREE_SVCLASS_ID) &&  			hs->hfp_handle != 0) @@ -1261,14 +1280,14 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)  	headset_set_state(dev, HEADSET_STATE_CONNECTED); -	if (p->target_state == HEADSET_STATE_PLAYING) { +	if (p && p->target_state == HEADSET_STATE_PLAYING) {  		p->err = sco_connect(dev, NULL, NULL, NULL);  		if (p->err < 0)  			goto failed;  		return;  	} -	if (p->msg) { +	if (p && p->msg) {  		DBusMessage *reply = dbus_message_new_method_return(p->msg);  		g_dbus_send_message(dev->conn, reply);  	} @@ -1414,7 +1433,7 @@ static int rfcomm_connect(struct audio_device *dev, headset_stream_cb_t cb,  	debug("%s: Connecting to %s channel %d", dev->path, address,  		hs->rfcomm_ch); -	io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, dev, +	io = bt_io_connect(BT_IO_RFCOMM, headset_connect_cb, dev,  				NULL, &err,  				BT_IO_OPT_SOURCE_BDADDR, &dev->src,  				BT_IO_OPT_DEST_BDADDR, &dev->dst, @@ -2280,6 +2299,13 @@ void set_hfp_active(struct audio_device *dev, gboolean active)  	hs->hfp_active = active;  } +GIOChannel *headset_get_rfcomm(struct audio_device *dev) +{ +	struct headset *hs = dev->headset; + +	return hs->tmp_rfcomm; +} +  int headset_connect_rfcomm(struct audio_device *dev, GIOChannel *io)  {  	struct headset *hs = dev->headset; @@ -2329,32 +2355,6 @@ static int headset_close_rfcomm(struct audio_device *dev)  	return 0;  } -void headset_set_authorized(struct audio_device *dev) -{ -	struct headset *hs = dev->headset; - -	/* For HFP telephony isn't ready just disconnect */ -	if (hs->hfp_active && !ag.telephony_ready) { -		error("Unable to accept HFP connection since the telephony " -				"subsystem isn't initialized"); -		headset_set_state(dev, HEADSET_STATE_DISCONNECTED); -		return; -	} - -	hs->rfcomm = hs->tmp_rfcomm; -	hs->tmp_rfcomm = NULL; - -	g_io_add_watch(hs->rfcomm, -			G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, -			(GIOFunc) rfcomm_io_cb, dev); - -	hs->auto_dc = FALSE; - -	/* For HSP (no special SLC setup) move to CONNECTED state */ -	if (!hs->hfp_active) -		headset_set_state(dev, HEADSET_STATE_CONNECTED); -} -  void headset_set_state(struct audio_device *dev, headset_state_t state)  {  	struct headset *hs = dev->headset; diff --git a/audio/headset.h b/audio/headset.h index 0c9eb669..a36c9125 100644 --- a/audio/headset.h +++ b/audio/headset.h @@ -42,6 +42,10 @@ typedef enum {  typedef void (*headset_stream_cb_t) (struct audio_device *dev, void *user_data); +void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data); + +GIOChannel *headset_get_rfcomm(struct audio_device *dev); +  struct headset *headset_init(struct audio_device *dev, uint16_t svc,  				const char *uuidstr); diff --git a/audio/manager.c b/audio/manager.c index 1eb17907..35f9c6e5 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -403,6 +403,8 @@ static void auth_cb(DBusError *derr, void *user_data)  {  	struct audio_device *device = user_data;  	const char *uuid; +	GError *err = NULL; +	GIOChannel *io;  	if (get_hfp_active(device))  		uuid = HFP_AG_UUID; @@ -411,20 +413,21 @@ static void auth_cb(DBusError *derr, void *user_data)  	if (derr && dbus_error_is_set(derr)) {  		error("Access denied: %s", derr->message); -  		headset_set_state(device, HEADSET_STATE_DISCONNECTED); -	} else { -		char hs_address[18]; +		return; +	} -		ba2str(&device->dst, hs_address); -		debug("Accepted headset connection from %s for %s", -						hs_address, device->path); +	io = headset_get_rfcomm(device); -		headset_set_authorized(device); +	if (!bt_io_accept(io, headset_connect_cb, device, NULL, &err)) { +		error("bt_io_accept: %s", err->message); +		g_error_free(err); +		headset_set_state(device, HEADSET_STATE_DISCONNECTED); +		return;  	}  } -static void ag_io_cb(GIOChannel *chan, GError *err, gpointer data) +static void ag_confirm(GIOChannel *chan, gpointer data)  {  	const char *server_uuid, *remote_uuid;  	uint16_t svclass; @@ -432,22 +435,17 @@ static void ag_io_cb(GIOChannel *chan, GError *err, gpointer data)  	gboolean hfp_active;  	bdaddr_t src, dst;  	int perr; -	GError *gerr = NULL; +	GError *err = NULL;  	uint8_t ch; -	if (err) { -		error("%s", err->message); -		return; -	} - -	bt_io_get(chan, BT_IO_RFCOMM, &gerr, +	bt_io_get(chan, BT_IO_RFCOMM, &err,  			BT_IO_OPT_SOURCE_BDADDR, &src,  			BT_IO_OPT_DEST_BDADDR, &dst,  			BT_IO_OPT_CHANNEL, &ch,  			BT_IO_OPT_INVALID); -	if (gerr) { -		error("%s", gerr->message); -		g_clear_error(&gerr); +	if (err) { +		error("%s", err->message); +		g_clear_error(&err);  		goto drop;  	} @@ -533,7 +531,7 @@ static int headset_server_init(struct audio_adapter *adapter)  			master = tmp;  	} -	io =  bt_io_listen(BT_IO_RFCOMM, ag_io_cb, NULL, adapter, NULL, &err, +	io =  bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err,  				BT_IO_OPT_SOURCE_BDADDR, &adapter->src,  				BT_IO_OPT_CHANNEL, chan,  				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, @@ -564,7 +562,7 @@ static int headset_server_init(struct audio_adapter *adapter)  	chan = DEFAULT_HF_AG_CHANNEL; -	io = bt_io_listen(BT_IO_RFCOMM, ag_io_cb, NULL, adapter, NULL, &err, +	io = bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err,  				BT_IO_OPT_SOURCE_BDADDR, &adapter->src,  				BT_IO_OPT_CHANNEL, chan,  				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,  | 
