All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/13] android/handsfree: Define proper type for device structure
@ 2014-10-08  7:12 Szymon Janc
  2014-10-08  7:12 ` [PATCH 02/13] android/handsfree: Make init, cleanup and state functions static less Szymon Janc
                   ` (11 more replies)
  0 siblings, 12 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 6c7c061..df3cb42 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -110,22 +110,7 @@ struct hfp_codec {
 	bool remote_supported;
 };
 
-static const struct indicator inds_defaults[] = {
-		{ "service",   0, 1, 0, false, true },
-		{ "call",      0, 1, 0, true, true },
-		{ "callsetup", 0, 3, 0, true, true },
-		{ "callheld",  0, 2, 0, true, true },
-		{ "signal",    0, 5, 0, false, true },
-		{ "roam",      0, 1, 0, false, true },
-		{ "battchg",   0, 5, 0, false, true },
-};
-
-static const struct hfp_codec codecs_defaults[] = {
-	{ CODEC_ID_CVSD, true, false},
-	{ CODEC_ID_MSBC, false, false},
-};
-
-static struct {
+struct hf_device {
 	bdaddr_t bdaddr;
 	uint8_t state;
 	uint8_t audio_state;
@@ -152,7 +137,24 @@ static struct {
 
 	GIOChannel *sco;
 	guint sco_watch;
-} device;
+};
+
+static const struct indicator inds_defaults[] = {
+		{ "service",   0, 1, 0, false, true },
+		{ "call",      0, 1, 0, true, true },
+		{ "callsetup", 0, 3, 0, true, true },
+		{ "callheld",  0, 2, 0, true, true },
+		{ "signal",    0, 5, 0, false, true },
+		{ "roam",      0, 1, 0, false, true },
+		{ "battchg",   0, 5, 0, false, true },
+};
+
+static const struct hfp_codec codecs_defaults[] = {
+	{ CODEC_ID_CVSD, true, false},
+	{ CODEC_ID_MSBC, false, false},
+};
+
+static struct hf_device device;
 
 static uint32_t hfp_ag_features = 0;
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 02/13] android/handsfree: Make init, cleanup and state functions static less
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 03/13] android/handsfree: Pass device as user data to AT handlers Szymon Janc
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 122 ++++++++++++++++++++++++++--------------------------
 1 file changed, 60 insertions(+), 62 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index df3cb42..7fa8cfd 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -171,102 +171,102 @@ static GIOChannel *hsp_server = NULL;
 
 static GIOChannel *sco_server = NULL;
 
-static void device_set_state(uint8_t state)
+static void set_state(struct hf_device *dev, uint8_t state)
 {
 	struct hal_ev_handsfree_conn_state ev;
 	char address[18];
 
-	if (device.state == state)
+	if (dev->state == state)
 		return;
 
-	device.state = state;
+	dev->state = state;
 
-	ba2str(&device.bdaddr, address);
+	ba2str(&dev->bdaddr, address);
 	DBG("device %s state %u", address, state);
 
-	bdaddr2android(&device.bdaddr, ev.bdaddr);
+	bdaddr2android(&dev->bdaddr, ev.bdaddr);
 	ev.state = state;
 
 	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 				HAL_EV_HANDSFREE_CONN_STATE, sizeof(ev), &ev);
 }
 
-static void device_set_audio_state(uint8_t state)
+static void set_audio_state(struct hf_device *dev, uint8_t state)
 {
 	struct hal_ev_handsfree_audio_state ev;
 	char address[18];
 
-	if (device.audio_state == state)
+	if (dev->audio_state == state)
 		return;
 
-	device.audio_state = state;
+	dev->audio_state = state;
 
-	ba2str(&device.bdaddr, address);
+	ba2str(&dev->bdaddr, address);
 	DBG("device %s audio state %u", address, state);
 
-	bdaddr2android(&device.bdaddr, ev.bdaddr);
+	bdaddr2android(&dev->bdaddr, ev.bdaddr);
 	ev.state = state;
 
 	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 				HAL_EV_HANDSFREE_AUDIO_STATE, sizeof(ev), &ev);
 }
 
-static void init_codecs(void)
+static void init_codecs(struct hf_device *dev)
 {
-	memcpy(device.codecs, codecs_defaults, sizeof(device.codecs));
+	memcpy(dev->codecs, codecs_defaults, sizeof(dev->codecs));
 
 	if (hfp_ag_features & HFP_AG_FEAT_CODEC)
-		device.codecs[MSBC_OFFSET].local_supported = true;
+		dev->codecs[MSBC_OFFSET].local_supported = true;
 }
 
-static void device_init(const bdaddr_t *bdaddr)
+static void device_init(struct hf_device *dev, const bdaddr_t *bdaddr)
 {
-	bacpy(&device.bdaddr, bdaddr);
+	bacpy(&dev->bdaddr, bdaddr);
 
-	device.setup_state = HAL_HANDSFREE_CALL_STATE_IDLE;
+	dev->setup_state = HAL_HANDSFREE_CALL_STATE_IDLE;
 
-	memcpy(device.inds, inds_defaults, sizeof(device.inds));
+	memcpy(dev->inds, inds_defaults, sizeof(dev->inds));
 
-	init_codecs();
+	init_codecs(dev);
 
-	device_set_state(HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
+	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
 }
 
-static void device_cleanup(void)
+static void device_cleanup(struct hf_device *dev)
 {
-	if (device.gw) {
-		hfp_gw_unref(device.gw);
-		device.gw = NULL;
+	if (dev->gw) {
+		hfp_gw_unref(dev->gw);
+		dev->gw = NULL;
 	}
 
-	device_set_state(HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);
+	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);
 
-	if (device.sco_watch) {
-		g_source_remove(device.sco_watch);
-		device.sco_watch = 0;
+	if (dev->sco_watch) {
+		g_source_remove(dev->sco_watch);
+		dev->sco_watch = 0;
 	}
 
-	if (device.sco) {
-		g_io_channel_shutdown(device.sco, TRUE, NULL);
-		g_io_channel_unref(device.sco);
-		device.sco = NULL;
+	if (dev->sco) {
+		g_io_channel_shutdown(dev->sco, TRUE, NULL);
+		g_io_channel_unref(dev->sco);
+		dev->sco = NULL;
 	}
 
-	if (device.ring) {
-		g_source_remove(device.ring);
-		device.ring = 0;
+	if (dev->ring) {
+		g_source_remove(dev->ring);
+		dev->ring = 0;
 	}
 
-	device_set_audio_state(HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
+	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
 
-	memset(&device, 0, sizeof(device));
+	memset(dev, 0, sizeof(*dev));
 }
 
 static void disconnect_watch(void *user_data)
 {
 	DBG("");
 
-	device_cleanup();
+	device_cleanup(&device);
 }
 
 static void at_cmd_unknown(const char *command, void *user_data)
@@ -833,7 +833,7 @@ static gboolean sco_watch_cb(GIOChannel *chan, GIOCondition cond,
 
 	device.sco_watch = 0;
 
-	device_set_audio_state(HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
+	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
 
 	return FALSE;
 }
@@ -868,12 +868,10 @@ done:
 static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	if (err) {
-		uint8_t status;
-
 		error("handsfree: audio connect failed (%s)", err->message);
 
-		status = HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
-		device_set_audio_state(status);
+		set_audio_state(&device,
+				HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
 
 		if (!(device.features & HFP_HF_FEAT_CODEC))
 			return;
@@ -893,7 +891,7 @@ static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	device.sco_watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
 							sco_watch_cb, NULL);
 
-	device_set_audio_state(HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED);
+	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED);
 }
 
 static bool connect_sco(void)
@@ -926,7 +924,7 @@ static bool connect_sco(void)
 
 	g_io_channel_unref(io);
 
-	device_set_audio_state(HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
+	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
 
 	return true;
 }
@@ -1101,7 +1099,7 @@ static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 			return;
 
 		register_post_slc_at();
-		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
+		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	case HFP_GW_CMD_TYPE_TEST:
 	case HFP_GW_CMD_TYPE_READ:
@@ -1225,7 +1223,7 @@ static void at_cmd_chld(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
 
 		register_post_slc_at();
-		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
+		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_COMMAND:
@@ -1259,7 +1257,7 @@ static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 			goto failed;
 
 		/* set codecs to defaults */
-		init_codecs();
+		init_codecs(&device);
 		device.negotiated_codec = 0;
 
 		/*
@@ -1337,18 +1335,18 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 	if (device.hsp) {
 		register_post_slc_at();
-		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
-		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
+		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
+		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	}
 
 	register_slc_at();
-	device_set_state(HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
+	set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
 	return;
 
 failed:
 	g_io_channel_shutdown(chan, TRUE, NULL);
-	device_cleanup();
+	device_cleanup(&device);
 }
 
 static void confirm_cb(GIOChannel *chan, gpointer data)
@@ -1374,11 +1372,11 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
 		goto drop;
 	}
 
-	device_init(&bdaddr);
+	device_init(&device, &bdaddr);
 
 	if (!bt_io_accept(chan, connect_cb, NULL, NULL, NULL)) {
 		error("handsfree: failed to accept connection");
-		device_cleanup();
+		device_cleanup(&device);
 		goto drop;
 	}
 
@@ -1460,7 +1458,7 @@ static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	device_cleanup();
+	device_cleanup(&device);
 }
 
 static int sdp_search_hsp(void)
@@ -1547,7 +1545,7 @@ static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	device_cleanup();
+	device_cleanup(&device);
 }
 
 static int sdp_search_hfp(void)
@@ -1580,13 +1578,13 @@ static void handle_connect(const void *buf, uint16_t len)
 	ba2str(&bdaddr, addr);
 	DBG("connecting to %s", addr);
 
-	device_init(&bdaddr);
+	device_init(&device, &bdaddr);
 
 	/* prefer HFP over HSP */
 	ret = hfp_server ? sdp_search_hfp() : sdp_search_hsp();
 	if (ret < 0) {
 		error("handsfree: SDP search failed");
-		device_cleanup();
+		device_cleanup(&device);
 		status = HAL_STATUS_FAILED;
 		goto failed;
 	}
@@ -1621,9 +1619,9 @@ static void handle_disconnect(const void *buf, uint16_t len)
 	}
 
 	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
-		device_cleanup();
+		device_cleanup(&device);
 	} else {
-		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
+		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
 		hfp_gw_disconnect(device.gw);
 	}
 
@@ -1639,7 +1637,7 @@ static bool disconnect_sco(void)
 	if (!device.sco)
 		return false;
 
-	device_set_audio_state(HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING);
+	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING);
 
 	if (device.sco_watch) {
 		g_source_remove(device.sco_watch);
@@ -1650,7 +1648,7 @@ static bool disconnect_sco(void)
 	g_io_channel_unref(device.sco);
 	device.sco = NULL;
 
-	device_set_audio_state(HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
+	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
 	return true;
 }
 
@@ -2340,7 +2338,7 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
 		goto drop;
 	}
 
-	device_set_audio_state(HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
+	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
 	return;
 
 drop:
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 03/13] android/handsfree: Pass device as user data to AT handlers
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
  2014-10-08  7:12 ` [PATCH 02/13] android/handsfree: Make init, cleanup and state functions static less Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 04/13] android/handsfree: Pass device to connection handling functions Szymon Janc
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 264 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 150 insertions(+), 114 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 7fa8cfd..d49d13b 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -271,12 +271,13 @@ static void disconnect_watch(void *user_data)
 
 static void at_cmd_unknown(const char *command, void *user_data)
 {
+	struct hf_device *dev = user_data;
 	uint8_t buf[IPC_MTU];
 	struct hal_ev_handsfree_unknown_at *ev = (void *) buf;
 
-	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) {
-		hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
-		hfp_gw_disconnect(device.gw);
+	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) {
+		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
+		hfp_gw_disconnect(dev->gw);
 		return;
 	}
 
@@ -285,7 +286,7 @@ static void at_cmd_unknown(const char *command, void *user_data)
 	memcpy(ev->buf, command, ev->len);
 
 	if (ev->len > IPC_MTU - sizeof(*ev)) {
-		hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 		return;
 	}
 
@@ -296,6 +297,7 @@ static void at_cmd_unknown(const char *command, void *user_data)
 static void at_cmd_vgm(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_volume ev;
 	unsigned int val;
 
@@ -316,7 +318,7 @@ static void at_cmd_vgm(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 				HAL_EV_HANDSFREE_VOLUME, sizeof(ev), &ev);
 
 		/* Framework is not replying with result for AT+VGM */
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -324,12 +326,13 @@ static void at_cmd_vgm(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_vgs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_volume ev;
 	unsigned int val;
 
@@ -350,7 +353,7 @@ static void at_cmd_vgs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 				HAL_EV_HANDSFREE_VOLUME, sizeof(ev), &ev);
 
 		/* Framework is not replying with result for AT+VGS */
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -358,12 +361,13 @@ static void at_cmd_vgs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_cops(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	switch (type) {
@@ -377,7 +381,7 @@ static void at_cmd_cops(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		if (hfp_gw_result_has_next(result))
 			break;
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -388,12 +392,13 @@ static void at_cmd_cops(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_bia(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val, i, def;
 	bool tmp[IND_COUNT];
 
@@ -402,12 +407,12 @@ static void at_cmd_bia(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
 		for (i = 0; i < IND_COUNT; i++)
-			tmp[i] = device.inds[i].active;
+			tmp[i] = dev->inds[i].active;
 
 		i = 0;
 
 		do {
-			def = (i < IND_COUNT) ? device.inds[i].active : 0;
+			def = (i < IND_COUNT) ? dev->inds[i].active : 0;
 
 			if (!hfp_gw_result_get_number_default(result, &val, def))
 				goto failed;
@@ -416,15 +421,15 @@ static void at_cmd_bia(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 				goto failed;
 
 			if (i < IND_COUNT) {
-				tmp[i] = val || device.inds[i].always_active;
+				tmp[i] = val || dev->inds[i].always_active;
 				i++;
 			}
 		} while (hfp_gw_result_has_next(result));
 
 		for (i = 0; i < IND_COUNT; i++)
-			device.inds[i].active = tmp[i];
+			dev->inds[i].active = tmp[i];
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_TEST:
 	case HFP_GW_CMD_TYPE_READ:
@@ -433,12 +438,14 @@ static void at_cmd_bia(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	}
 
 failed:
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_a(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	switch (type) {
@@ -450,7 +457,7 @@ static void at_cmd_a(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 					HAL_EV_HANDSFREE_ANSWER, 0, NULL);
 
 		/* Framework is not replying with result for ATA */
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_SET:
 	case HFP_GW_CMD_TYPE_READ:
@@ -458,12 +465,13 @@ static void at_cmd_a(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_d(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	char buf[IPC_MTU];
 	struct hal_ev_handsfree_dial *ev = (void *) buf;
 	int cnt;
@@ -501,12 +509,13 @@ static void at_cmd_d(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_ccwa(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	DBG("");
@@ -519,9 +528,9 @@ static void at_cmd_ccwa(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		if (hfp_gw_result_has_next(result))
 			break;
 
-		device.ccwa_enabled = val;
+		dev->ccwa_enabled = val;
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -529,12 +538,14 @@ static void at_cmd_ccwa(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_chup(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	switch (type) {
@@ -546,7 +557,7 @@ static void at_cmd_chup(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 					HAL_EV_HANDSFREE_HANGUP, 0, NULL);
 
 		/* Framework is not replying with result for AT+CHUP */
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -554,12 +565,14 @@ static void at_cmd_chup(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_clcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	switch (type) {
@@ -576,12 +589,13 @@ static void at_cmd_clcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_cmee(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	DBG("");
@@ -594,9 +608,9 @@ static void at_cmd_cmee(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		if (hfp_gw_result_has_next(result))
 			break;
 
-		device.cmee_enabled = val;
+		dev->cmee_enabled = val;
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -604,12 +618,13 @@ static void at_cmd_cmee(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_clip(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	DBG("");
@@ -622,9 +637,9 @@ static void at_cmd_clip(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		if (hfp_gw_result_has_next(result))
 			break;
 
-		device.clip_enabled = val;
+		dev->clip_enabled = val;
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -632,12 +647,13 @@ static void at_cmd_clip(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_vts(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_dtmf ev;
 	char str[2];
 
@@ -662,7 +678,7 @@ static void at_cmd_vts(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 					HAL_EV_HANDSFREE_DTMF, sizeof(ev), &ev);
 
 		/* Framework is not replying with result for AT+VTS */
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -670,12 +686,14 @@ static void at_cmd_vts(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_cnum(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	switch (type) {
@@ -692,22 +710,25 @@ static void at_cmd_cnum(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_binp(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	/* TODO */
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_bldn(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_dial ev;
 
 	DBG("");
@@ -728,12 +749,13 @@ static void at_cmd_bldn(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_bvra(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_vr_state ev;
 	unsigned int val;
 
@@ -761,12 +783,13 @@ static void at_cmd_bvra(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_nrec(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_nrec ev;
 	unsigned int val;
 
@@ -791,7 +814,7 @@ static void at_cmd_nrec(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 					HAL_EV_HANDSFREE_NREC, sizeof(ev), &ev);
 
 		/* Framework is not replying with result for AT+NREC */
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -799,27 +822,31 @@ static void at_cmd_nrec(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_bsir(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	/* TODO */
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_btrh(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	/* TODO */
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static gboolean sco_watch_cb(GIOChannel *chan, GIOCondition cond,
@@ -932,20 +959,22 @@ static bool connect_sco(void)
 static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (!(device.features & HFP_HF_FEAT_CODEC))
+		if (!(dev->features & HFP_HF_FEAT_CODEC))
 			break;
 
 		if (hfp_gw_result_has_next(result))
 			break;
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
 		/* we haven't negotiated codec, start selection */
-		if (!device.negotiated_codec) {
+		if (!dev->negotiated_codec) {
 			select_codec(0);
 			return;
 		}
@@ -953,7 +982,7 @@ static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		 * we try connect to negotiated codec. If it fails, and it isn't
 		 * CVSD codec, try connect CVSD
 		 */
-		if (!connect_sco() && device.negotiated_codec != CODEC_ID_CVSD)
+		if (!connect_sco() && dev->negotiated_codec != CODEC_ID_CVSD)
 			select_codec(CODEC_ID_CVSD);
 
 		return;
@@ -963,12 +992,13 @@ static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_bcs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	DBG("");
@@ -982,15 +1012,15 @@ static void at_cmd_bcs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 			break;
 
 		/* Remote replied with other codec. Reply with error */
-		if (device.proposed_codec != val) {
-			device.proposed_codec = 0;
+		if (dev->proposed_codec != val) {
+			dev->proposed_codec = 0;
 			break;
 		}
 
-		device.proposed_codec = 0;
-		device.negotiated_codec = val;
+		dev->proposed_codec = 0;
+		dev->negotiated_codec = val;
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
 		/* Connect sco with negotiated parameters */
 		connect_sco();
@@ -1001,12 +1031,13 @@ static void at_cmd_bcs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_ckpd(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	DBG("");
@@ -1022,7 +1053,7 @@ static void at_cmd_ckpd(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 				HAL_EV_HANDSFREE_HSP_KEY_PRESS, 0, NULL);
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -1030,44 +1061,45 @@ static void at_cmd_ckpd(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void register_post_slc_at(void)
 {
 	if (device.hsp) {
-		hfp_gw_register(device.gw, at_cmd_ckpd, "+CKPD", NULL, NULL);
-		hfp_gw_register(device.gw, at_cmd_vgs, "+VGS", NULL, NULL);
-		hfp_gw_register(device.gw, at_cmd_vgm, "+VGM", NULL, NULL);
+		hfp_gw_register(device.gw, at_cmd_ckpd, "+CKPD", &device, NULL);
+		hfp_gw_register(device.gw, at_cmd_vgs, "+VGS", &device, NULL);
+		hfp_gw_register(device.gw, at_cmd_vgm, "+VGM", &device, NULL);
 		return;
 	}
 
-	hfp_gw_register(device.gw, at_cmd_a, "A", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_d, "D", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_ccwa, "+CCWA", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_chup, "+CHUP", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_clcc, "+CLCC", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_cops, "+COPS", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_cmee, "+CMEE", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_clip, "+CLIP", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_vts, "+VTS", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_cnum, "+CNUM", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_bia, "+BIA", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_binp, "+BINP", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_bldn, "+BLDN", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_bvra, "+BVRA", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_nrec, "+NREC", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_vgs, "+VGS", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_vgm, "+VGM", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_bsir, "+BSIR", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_btrh, "+BTRH", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_bcc, "+BCC", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_bcs, "+BCS", NULL, NULL);
+	hfp_gw_register(device.gw, at_cmd_a, "A", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_d, "D", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_ccwa, "+CCWA", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_chup, "+CHUP", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_clcc, "+CLCC", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_cops, "+COPS", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_cmee, "+CMEE", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_clip, "+CLIP", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_vts, "+VTS", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_cnum, "+CNUM", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_bia, "+BIA", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_binp, "+BINP", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_bldn, "+BLDN", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_bvra, "+BVRA", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_nrec, "+NREC", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_vgs, "+VGS", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_vgm, "+VGM", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_bsir, "+BSIR", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_btrh, "+BTRH", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_bcc, "+BCC", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_bcs, "+BCS", &device, NULL);
 }
 
 static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	switch (type) {
@@ -1091,15 +1123,15 @@ static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		if (hfp_gw_result_has_next(result))
 			break;
 
-		device.indicators_enabled = val;
+		dev->indicators_enabled = val;
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
-		if (device.features & HFP_HF_FEAT_3WAY)
+		if (dev->features & HFP_HF_FEAT_3WAY)
 			return;
 
 		register_post_slc_at();
-		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
+		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	case HFP_GW_CMD_TYPE_TEST:
 	case HFP_GW_CMD_TYPE_READ:
@@ -1107,12 +1139,13 @@ static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	char *buf, *ptr;
 	int len;
 	unsigned int i;
@@ -1124,15 +1157,15 @@ static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		 * If device supports Codec Negotiation, AT+BAC should be
 		 * received first
 		 */
-		if ((device.features & HFP_HF_FEAT_CODEC) &&
-				!device.codecs[CVSD_OFFSET].remote_supported)
+		if ((dev->features & HFP_HF_FEAT_CODEC) &&
+				!dev->codecs[CVSD_OFFSET].remote_supported)
 			break;
 
 		len = strlen("+CIND:") + 1;
 
 		for (i = 0; i < IND_COUNT; i++) {
 			len += strlen("(\"\",(X,X)),");
-			len += strlen(device.inds[i].name);
+			len += strlen(dev->inds[i].name);
 		}
 
 		buf = g_malloc(len);
@@ -1141,17 +1174,17 @@ static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 		for (i = 0; i < IND_COUNT; i++) {
 			ptr += sprintf(ptr, "(\"%s\",(%d%c%d)),",
-					device.inds[i].name,
-					device.inds[i].min,
-					device.inds[i].max == 1 ? ',' : '-',
-					device.inds[i].max);
+					dev->inds[i].name,
+					dev->inds[i].min,
+					dev->inds[i].max == 1 ? ',' : '-',
+					dev->inds[i].max);
 		}
 
 		ptr--;
 		*ptr = '\0';
 
-		hfp_gw_send_info(device.gw, "%s", buf);
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_info(dev->gw, "%s", buf);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
 		g_free(buf);
 		return;
@@ -1164,12 +1197,13 @@ static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int feat;
 
 	switch (type) {
@@ -1181,10 +1215,10 @@ static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 			break;
 
 		/* TODO verify features */
-		device.features = feat;
+		dev->features = feat;
 
-		hfp_gw_send_info(device.gw, "+BRSF: %u", hfp_ag_features);
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_info(dev->gw, "+BRSF: %u", hfp_ag_features);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -1192,12 +1226,13 @@ static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void at_cmd_chld(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_chld ev;
 	unsigned int val;
 
@@ -1219,18 +1254,18 @@ static void at_cmd_chld(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 					HAL_EV_HANDSFREE_CHLD, sizeof(ev), &ev);
 		return;
 	case HFP_GW_CMD_TYPE_TEST:
-		hfp_gw_send_info(device.gw, "+CHLD: (%s)", HFP_AG_CHLD);
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_info(dev->gw, "+CHLD: (%s)", HFP_AG_CHLD);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
 		register_post_slc_at();
-		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
+		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_COMMAND:
 		break;
 	}
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static struct hfp_codec *find_codec_by_type(uint8_t type)
@@ -1247,18 +1282,19 @@ static struct hfp_codec *find_codec_by_type(uint8_t type)
 static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
+	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	DBG("");
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!(device.features & HFP_HF_FEAT_CODEC))
+		if (!(dev->features & HFP_HF_FEAT_CODEC))
 			goto failed;
 
 		/* set codecs to defaults */
-		init_codecs(&device);
-		device.negotiated_codec = 0;
+		init_codecs(dev);
+		dev->negotiated_codec = 0;
 
 		/*
 		 * At least CVSD mandatory codec must exist
@@ -1268,13 +1304,13 @@ static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 							val != CODEC_ID_CVSD)
 			goto failed;
 
-		device.codecs[CVSD_OFFSET].remote_supported = true;
+		dev->codecs[CVSD_OFFSET].remote_supported = true;
 
 		if (hfp_gw_result_get_number(result, &val)) {
 			if (val != CODEC_ID_MSBC)
 				goto failed;
 
-			device.codecs[MSBC_OFFSET].remote_supported = true;
+			dev->codecs[MSBC_OFFSET].remote_supported = true;
 		}
 
 		while (hfp_gw_result_has_next(result)) {
@@ -1290,9 +1326,9 @@ static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 			codec->remote_supported = true;
 		}
 
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
-		if (device.proposed_codec)
+		if (dev->proposed_codec)
 			select_codec(0);
 		return;
 	case HFP_GW_CMD_TYPE_TEST:
@@ -1302,16 +1338,16 @@ static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	}
 
 failed:
-	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
 static void register_slc_at(void)
 {
-	hfp_gw_register(device.gw, at_cmd_brsf, "+BRSF", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_cind, "+CIND", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_cmer, "+CMER", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_chld, "+CHLD", NULL, NULL);
-	hfp_gw_register(device.gw, at_cmd_bac, "+BAC", NULL, NULL);
+	hfp_gw_register(device.gw, at_cmd_brsf, "+BRSF", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_cind, "+CIND", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_cmer, "+CMER", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_chld, "+CHLD", &device, NULL);
+	hfp_gw_register(device.gw, at_cmd_bac, "+BAC", &device, NULL);
 }
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 04/13] android/handsfree: Pass device to connection handling functions
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
  2014-10-08  7:12 ` [PATCH 02/13] android/handsfree: Make init, cleanup and state functions static less Szymon Janc
  2014-10-08  7:12 ` [PATCH 03/13] android/handsfree: Pass device as user data to AT handlers Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 05/13] android/handsfree: Pass device pointer when registering AT commands Szymon Janc
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 56 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 26 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index d49d13b..e66fa84 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -1352,6 +1352,8 @@ static void register_slc_at(void)
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
 	if (err) {
@@ -1359,30 +1361,30 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		goto failed;
 	}
 
-	device.gw = hfp_gw_new(g_io_channel_unix_get_fd(chan));
-	if (!device.gw)
+	dev->gw = hfp_gw_new(g_io_channel_unix_get_fd(chan));
+	if (!dev->gw)
 		goto failed;
 
 	g_io_channel_set_close_on_unref(chan, FALSE);
 
-	hfp_gw_set_close_on_unref(device.gw, true);
-	hfp_gw_set_command_handler(device.gw, at_cmd_unknown, NULL, NULL);
-	hfp_gw_set_disconnect_handler(device.gw, disconnect_watch, NULL, NULL);
+	hfp_gw_set_close_on_unref(dev->gw, true);
+	hfp_gw_set_command_handler(dev->gw, at_cmd_unknown, NULL, NULL);
+	hfp_gw_set_disconnect_handler(dev->gw, disconnect_watch, NULL, NULL);
 
-	if (device.hsp) {
+	if (dev->hsp) {
 		register_post_slc_at();
-		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
-		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
+		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
+		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	}
 
 	register_slc_at();
-	set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
+	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
 	return;
 
 failed:
 	g_io_channel_shutdown(chan, TRUE, NULL);
-	device_cleanup(&device);
+	device_cleanup(dev);
 }
 
 static void confirm_cb(GIOChannel *chan, gpointer data)
@@ -1410,7 +1412,7 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
 
 	device_init(&device, &bdaddr);
 
-	if (!bt_io_accept(chan, connect_cb, NULL, NULL, NULL)) {
+	if (!bt_io_accept(chan, connect_cb, &device, NULL, NULL)) {
 		error("handsfree: failed to accept connection");
 		device_cleanup(&device);
 		goto drop;
@@ -1425,6 +1427,7 @@ drop:
 
 static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
 {
+	struct hf_device *dev = data;
 	sdp_list_t *protos, *classes;
 	GError *gerr = NULL;
 	GIOChannel *io;
@@ -1476,9 +1479,9 @@ static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		goto fail;
 	}
 
-	io = bt_io_connect(connect_cb, NULL, NULL, &gerr,
+	io = bt_io_connect(connect_cb, dev, NULL, &gerr,
 				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
-				BT_IO_OPT_DEST_BDADDR, &device.bdaddr,
+				BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 				BT_IO_OPT_CHANNEL, channel,
 				BT_IO_OPT_INVALID);
@@ -1488,27 +1491,28 @@ static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		goto fail;
 	}
 
-	device.hsp = true;
+	dev->hsp = true;
 
 	g_io_channel_unref(io);
 	return;
 
 fail:
-	device_cleanup(&device);
+	device_cleanup(dev);
 }
 
-static int sdp_search_hsp(void)
+static int sdp_search_hsp(struct hf_device *dev)
 {
 	uuid_t uuid;
 
 	sdp_uuid16_create(&uuid, HEADSET_SVCLASS_ID);
 
-	return bt_search_service(&adapter_addr, &device.bdaddr, &uuid,
-					sdp_hsp_search_cb, NULL, NULL, 0);
+	return bt_search_service(&adapter_addr, &dev->bdaddr, &uuid,
+					sdp_hsp_search_cb, dev, NULL, 0);
 }
 
 static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
 {
+	struct hf_device *dev = data;
 	sdp_list_t *protos, *classes;
 	GError *gerr = NULL;
 	GIOChannel *io;
@@ -1526,7 +1530,7 @@ static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	if (!recs || !recs->data) {
 		info("handsfree: no HFP SDP records found, trying HSP");
 
-		if (sdp_search_hsp() < 0) {
+		if (sdp_search_hsp(dev) < 0) {
 			error("handsfree: HSP SDP search failed");
 			goto fail;
 		}
@@ -1565,9 +1569,9 @@ static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		goto fail;
 	}
 
-	io = bt_io_connect(connect_cb, NULL, NULL, &gerr,
+	io = bt_io_connect(connect_cb, dev, NULL, &gerr,
 				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
-				BT_IO_OPT_DEST_BDADDR, &device.bdaddr,
+				BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 				BT_IO_OPT_CHANNEL, channel,
 				BT_IO_OPT_INVALID);
@@ -1581,17 +1585,17 @@ static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	device_cleanup(&device);
+	device_cleanup(dev);
 }
 
-static int sdp_search_hfp(void)
+static int sdp_search_hfp(struct hf_device *dev)
 {
 	uuid_t uuid;
 
 	sdp_uuid16_create(&uuid, HANDSFREE_SVCLASS_ID);
 
-	return bt_search_service(&adapter_addr, &device.bdaddr, &uuid,
-					sdp_hfp_search_cb, NULL, NULL, 0);
+	return bt_search_service(&adapter_addr, &dev->bdaddr, &uuid,
+					sdp_hfp_search_cb, dev, NULL, 0);
 }
 
 static void handle_connect(const void *buf, uint16_t len)
@@ -1617,7 +1621,7 @@ static void handle_connect(const void *buf, uint16_t len)
 	device_init(&device, &bdaddr);
 
 	/* prefer HFP over HSP */
-	ret = hfp_server ? sdp_search_hfp() : sdp_search_hsp();
+	ret = hfp_server ? sdp_search_hfp(&device) : sdp_search_hsp(&device);
 	if (ret < 0) {
 		error("handsfree: SDP search failed");
 		device_cleanup(&device);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 05/13] android/handsfree: Pass device pointer when registering AT commands
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (2 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 04/13] android/handsfree: Pass device to connection handling functions Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 06/13] android/handsfree: Pass device pointer to codec handling functions Szymon Janc
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 74 ++++++++++++++++++++++++++---------------------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index e66fa84..f5b5169 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -1064,36 +1064,36 @@ static void at_cmd_ckpd(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
-static void register_post_slc_at(void)
+static void register_post_slc_at(struct hf_device *dev)
 {
-	if (device.hsp) {
-		hfp_gw_register(device.gw, at_cmd_ckpd, "+CKPD", &device, NULL);
-		hfp_gw_register(device.gw, at_cmd_vgs, "+VGS", &device, NULL);
-		hfp_gw_register(device.gw, at_cmd_vgm, "+VGM", &device, NULL);
+	if (dev->hsp) {
+		hfp_gw_register(dev->gw, at_cmd_ckpd, "+CKPD", dev, NULL);
+		hfp_gw_register(dev->gw, at_cmd_vgs, "+VGS", dev, NULL);
+		hfp_gw_register(dev->gw, at_cmd_vgm, "+VGM", dev, NULL);
 		return;
 	}
 
-	hfp_gw_register(device.gw, at_cmd_a, "A", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_d, "D", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_ccwa, "+CCWA", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_chup, "+CHUP", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_clcc, "+CLCC", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_cops, "+COPS", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_cmee, "+CMEE", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_clip, "+CLIP", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_vts, "+VTS", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_cnum, "+CNUM", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_bia, "+BIA", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_binp, "+BINP", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_bldn, "+BLDN", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_bvra, "+BVRA", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_nrec, "+NREC", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_vgs, "+VGS", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_vgm, "+VGM", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_bsir, "+BSIR", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_btrh, "+BTRH", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_bcc, "+BCC", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_bcs, "+BCS", &device, NULL);
+	hfp_gw_register(dev->gw, at_cmd_a, "A", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_d, "D", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_ccwa, "+CCWA", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_chup, "+CHUP", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_clcc, "+CLCC", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_cops, "+COPS", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_cmee, "+CMEE", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_clip, "+CLIP", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_vts, "+VTS", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_cnum, "+CNUM", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_bia, "+BIA", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_binp, "+BINP", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_bldn, "+BLDN", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_bvra, "+BVRA", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_nrec, "+NREC", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_vgs, "+VGS", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_vgm, "+VGM", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_bsir, "+BSIR", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_btrh, "+BTRH", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_bcc, "+BCC", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_bcs, "+BCS", dev, NULL);
 }
 
 static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
@@ -1130,7 +1130,7 @@ static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		if (dev->features & HFP_HF_FEAT_3WAY)
 			return;
 
-		register_post_slc_at();
+		register_post_slc_at(dev);
 		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	case HFP_GW_CMD_TYPE_TEST:
@@ -1257,7 +1257,7 @@ static void at_cmd_chld(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		hfp_gw_send_info(dev->gw, "+CHLD: (%s)", HFP_AG_CHLD);
 		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
-		register_post_slc_at();
+		register_post_slc_at(dev);
 		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
@@ -1341,13 +1341,13 @@ failed:
 	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
-static void register_slc_at(void)
+static void register_slc_at(struct hf_device *dev)
 {
-	hfp_gw_register(device.gw, at_cmd_brsf, "+BRSF", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_cind, "+CIND", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_cmer, "+CMER", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_chld, "+CHLD", &device, NULL);
-	hfp_gw_register(device.gw, at_cmd_bac, "+BAC", &device, NULL);
+	hfp_gw_register(dev->gw, at_cmd_brsf, "+BRSF", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_cind, "+CIND", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_cmer, "+CMER", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_chld, "+CHLD", dev, NULL);
+	hfp_gw_register(dev->gw, at_cmd_bac, "+BAC", dev, NULL);
 }
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
@@ -1368,17 +1368,17 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	g_io_channel_set_close_on_unref(chan, FALSE);
 
 	hfp_gw_set_close_on_unref(dev->gw, true);
-	hfp_gw_set_command_handler(dev->gw, at_cmd_unknown, NULL, NULL);
+	hfp_gw_set_command_handler(dev->gw, at_cmd_unknown, dev, NULL);
 	hfp_gw_set_disconnect_handler(dev->gw, disconnect_watch, NULL, NULL);
 
 	if (dev->hsp) {
-		register_post_slc_at();
+		register_post_slc_at(dev);
 		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
 		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	}
 
-	register_slc_at();
+	register_slc_at(dev);
 	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
 	return;
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 06/13] android/handsfree: Pass device pointer to codec handling functions
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (3 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 05/13] android/handsfree: Pass device pointer when registering AT commands Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 07/13] android/handsfree: Pass device to SCO " Szymon Janc
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index f5b5169..7c8020c 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -865,7 +865,7 @@ static gboolean sco_watch_cb(GIOChannel *chan, GIOCondition cond,
 	return FALSE;
 }
 
-static void select_codec(uint8_t codec_type)
+static void select_codec(struct hf_device *dev, uint8_t codec_type)
 {
 	uint8_t type = CODEC_ID_CVSD;
 	int i;
@@ -876,20 +876,20 @@ static void select_codec(uint8_t codec_type)
 	}
 
 	for (i = CODECS_COUNT - 1; i >= CVSD_OFFSET; i--) {
-		if (!device.codecs[i].local_supported)
+		if (!dev->codecs[i].local_supported)
 			continue;
 
-		if (!device.codecs[i].remote_supported)
+		if (!dev->codecs[i].remote_supported)
 			continue;
 
-		type = device.codecs[i].type;
+		type = dev->codecs[i].type;
 		break;
 	}
 
 done:
-	device.proposed_codec = type;
+	dev->proposed_codec = type;
 
-	hfp_gw_send_info(device.gw, "+BCS: %u", type);
+	hfp_gw_send_info(dev->gw, "+BCS: %u", type);
 }
 
 static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
@@ -906,7 +906,7 @@ static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		/* If other failed, try connecting with CVSD */
 		if (device.negotiated_codec != CODEC_ID_CVSD) {
 			info("handsfree: trying fallback with CVSD");
-			select_codec(CODEC_ID_CVSD);
+			select_codec(&device, CODEC_ID_CVSD);
 		}
 
 		return;
@@ -975,7 +975,7 @@ static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 		/* we haven't negotiated codec, start selection */
 		if (!dev->negotiated_codec) {
-			select_codec(0);
+			select_codec(dev, 0);
 			return;
 		}
 		/*
@@ -983,7 +983,7 @@ static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		 * CVSD codec, try connect CVSD
 		 */
 		if (!connect_sco() && dev->negotiated_codec != CODEC_ID_CVSD)
-			select_codec(CODEC_ID_CVSD);
+			select_codec(dev, CODEC_ID_CVSD);
 
 		return;
 	case HFP_GW_CMD_TYPE_READ:
@@ -1268,13 +1268,13 @@ static void at_cmd_chld(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
 }
 
-static struct hfp_codec *find_codec_by_type(uint8_t type)
+static struct hfp_codec *find_codec_by_type(struct hf_device *dev, uint8_t type)
 {
 	int i;
 
 	for (i = 0; i < CODECS_COUNT; i++)
-		if (type == device.codecs[i].type)
-			return &device.codecs[i];
+		if (type == dev->codecs[i].type)
+			return &dev->codecs[i];
 
 	return NULL;
 }
@@ -1319,7 +1319,7 @@ static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 			if (!hfp_gw_result_get_number(result, &val))
 				goto failed;
 
-			codec = find_codec_by_type(val);
+			codec = find_codec_by_type(dev, val);
 			if (!codec)
 				continue;
 
@@ -1329,7 +1329,7 @@ static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
 		if (dev->proposed_codec)
-			select_codec(0);
+			select_codec(dev, 0);
 		return;
 	case HFP_GW_CMD_TYPE_TEST:
 	case HFP_GW_CMD_TYPE_READ:
@@ -1699,7 +1699,7 @@ static bool connect_audio(void)
 
 	/* we haven't negotiated codec, start selection */
 	if ((device.features & HFP_HF_FEAT_CODEC) && !device.negotiated_codec) {
-		select_codec(0);
+		select_codec(&device, 0);
 		return true;
 	}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 07/13] android/handsfree: Pass device to SCO handling functions
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (4 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 06/13] android/handsfree: Pass device pointer to codec handling functions Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 08/13] android/handsfree: Move clip into device structure Szymon Janc
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 7c8020c..d83f0a2 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -852,15 +852,17 @@ static void at_cmd_btrh(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 static gboolean sco_watch_cb(GIOChannel *chan, GIOCondition cond,
 							gpointer user_data)
 {
-	g_io_channel_shutdown(device.sco, TRUE, NULL);
-	g_io_channel_unref(device.sco);
-	device.sco = NULL;
+	struct hf_device *dev = user_data;
+
+	g_io_channel_shutdown(dev->sco, TRUE, NULL);
+	g_io_channel_unref(dev->sco);
+	dev->sco = NULL;
 
 	DBG("");
 
-	device.sco_watch = 0;
+	dev->sco_watch = 0;
 
-	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
+	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
 
 	return FALSE;
 }
@@ -894,19 +896,20 @@ done:
 
 static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
+	struct hf_device *dev = user_data;
+
 	if (err) {
 		error("handsfree: audio connect failed (%s)", err->message);
 
-		set_audio_state(&device,
-				HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
+		set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
 
-		if (!(device.features & HFP_HF_FEAT_CODEC))
+		if (!(dev->features & HFP_HF_FEAT_CODEC))
 			return;
 
 		/* If other failed, try connecting with CVSD */
-		if (device.negotiated_codec != CODEC_ID_CVSD) {
+		if (dev->negotiated_codec != CODEC_ID_CVSD) {
 			info("handsfree: trying fallback with CVSD");
-			select_codec(&device, CODEC_ID_CVSD);
+			select_codec(dev, CODEC_ID_CVSD);
 		}
 
 		return;
@@ -914,11 +917,11 @@ static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 	g_io_channel_set_close_on_unref(chan, TRUE);
 
-	device.sco = g_io_channel_ref(chan);
-	device.sco_watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-							sco_watch_cb, NULL);
+	dev->sco = g_io_channel_ref(chan);
+	dev->sco_watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							sco_watch_cb, dev);
 
-	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED);
+	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED);
 }
 
 static bool connect_sco(void)
@@ -937,7 +940,7 @@ static bool connect_sco(void)
 	else
 		voice_settings = BT_VOICE_CVSD_16BIT;
 
-	io = bt_io_connect(connect_sco_cb, NULL, NULL, &gerr,
+	io = bt_io_connect(connect_sco_cb, &device, NULL, &gerr,
 				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
 				BT_IO_OPT_DEST_BDADDR, &device.bdaddr,
 				BT_IO_OPT_VOICE, voice_settings,
@@ -2373,7 +2376,7 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
 		goto drop;
 	}
 
-	if (!bt_io_accept(chan, connect_sco_cb, NULL, NULL, NULL)) {
+	if (!bt_io_accept(chan, connect_sco_cb, &device, NULL, NULL)) {
 		error("handsfree: failed to accept audio connection");
 		goto drop;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 08/13] android/handsfree: Move clip into device structure
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (5 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 07/13] android/handsfree: Pass device to SCO " Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  8:06   ` Andrei Emeltchenko
  2014-10-08  7:12 ` [PATCH 09/13] android/handsfree: Pass device to SCO handling functions Szymon Janc
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index d83f0a2..e7b8a6e 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -131,6 +131,7 @@ struct hf_device {
 	struct hfp_codec codecs[CODECS_COUNT];
 
 	guint ring;
+	char *clip;
 	bool hsp;
 
 	struct hfp_gw *gw;
@@ -255,6 +256,11 @@ static void device_cleanup(struct hf_device *dev)
 	if (dev->ring) {
 		g_source_remove(dev->ring);
 		dev->ring = 0;
+
+		if (dev->clip) {
+			g_free(dev->clip);
+			dev->clip = NULL;
+		}
 	}
 
 	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
@@ -2018,12 +2024,12 @@ done:
 
 static gboolean ring_cb(gpointer user_data)
 {
-	char *clip = user_data;
+	struct hf_device *dev = user_data;
 
-	hfp_gw_send_info(device.gw, "RING");
+	hfp_gw_send_info(dev->gw, "RING");
 
-	if (device.clip_enabled && clip)
-		hfp_gw_send_info(device.gw, "%s", clip);
+	if (dev->clip_enabled && dev->clip)
+		hfp_gw_send_info(dev->gw, "%s", dev->clip);
 
 	return TRUE;
 }
@@ -2065,7 +2071,7 @@ static void phone_state_waiting(int num_active, int num_held, uint8_t type,
 static void phone_state_incoming(int num_active, int num_held, uint8_t type,
 					const uint8_t *number, int number_len)
 {
-	char *clip, *num;
+	char *num;
 
 	if (device.setup_state == HAL_HANDSFREE_CALL_STATE_INCOMING) {
 		if (device.num_active != num_active ||
@@ -2096,19 +2102,20 @@ static void phone_state_incoming(int num_active, int num_held, uint8_t type,
 	num = number_len ? (char *) number : "";
 
 	if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+')
-		clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type);
+		device.clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type);
 	else
-		clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type);
+		device.clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type);
 
 	/* send first RING */
-	ring_cb(clip);
+	ring_cb(&device);
 
 	device.ring = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
 							RING_TIMEOUT, ring_cb,
-							clip, g_free);
-
-	if (!device.ring)
-		g_free(clip);
+							&device, NULL);
+	if (!device.ring) {
+		g_free(device.clip);
+		device.clip = NULL;
+	}
 }
 
 static void phone_state_idle(int num_active, int num_held)
@@ -2116,6 +2123,11 @@ static void phone_state_idle(int num_active, int num_held)
 	if (device.ring) {
 		g_source_remove(device.ring);
 		device.ring = 0;
+
+		if (device.clip) {
+			g_free(device.clip);
+			device.clip = NULL;
+		}
 	}
 
 	switch (device.setup_state) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 09/13] android/handsfree: Pass device to SCO handling functions
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (6 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 08/13] android/handsfree: Move clip into device structure Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  8:10   ` Andrei Emeltchenko
  2014-10-08  7:12 ` [PATCH 10/13] android/handsfree: Pass device object to disconnect watch Szymon Janc
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 60 ++++++++++++++++++++++++++---------------------------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index e7b8a6e..c41748b 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -930,25 +930,25 @@ static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED);
 }
 
-static bool connect_sco(void)
+static bool connect_sco(struct hf_device *dev)
 {
 	GIOChannel *io;
 	GError *gerr = NULL;
 	uint16_t voice_settings;
 
-	if (device.sco)
+	if (dev->sco)
 		return false;
 
-	if (!(device.features & HFP_HF_FEAT_CODEC))
+	if (!(dev->features & HFP_HF_FEAT_CODEC))
 		voice_settings = 0;
-	else if (device.negotiated_codec != CODEC_ID_CVSD)
+	else if (dev->negotiated_codec != CODEC_ID_CVSD)
 		voice_settings = BT_VOICE_TRANSPARENT;
 	else
 		voice_settings = BT_VOICE_CVSD_16BIT;
 
-	io = bt_io_connect(connect_sco_cb, &device, NULL, &gerr,
+	io = bt_io_connect(connect_sco_cb, dev, NULL, &gerr,
 				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
-				BT_IO_OPT_DEST_BDADDR, &device.bdaddr,
+				BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
 				BT_IO_OPT_VOICE, voice_settings,
 				BT_IO_OPT_INVALID);
 
@@ -960,7 +960,7 @@ static bool connect_sco(void)
 
 	g_io_channel_unref(io);
 
-	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
+	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
 
 	return true;
 }
@@ -991,7 +991,7 @@ static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		 * we try connect to negotiated codec. If it fails, and it isn't
 		 * CVSD codec, try connect CVSD
 		 */
-		if (!connect_sco() && dev->negotiated_codec != CODEC_ID_CVSD)
+		if (!connect_sco(dev) && dev->negotiated_codec != CODEC_ID_CVSD)
 			select_codec(dev, CODEC_ID_CVSD);
 
 		return;
@@ -1032,7 +1032,7 @@ static void at_cmd_bcs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
 		/* Connect sco with negotiated parameters */
-		connect_sco();
+		connect_sco(dev);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
 	case HFP_GW_CMD_TYPE_TEST:
@@ -1681,38 +1681,38 @@ failed:
 					HAL_OP_HANDSFREE_DISCONNECT, status);
 }
 
-static bool disconnect_sco(void)
+static bool disconnect_sco(struct hf_device *dev)
 {
-	if (!device.sco)
+	if (!dev->sco)
 		return false;
 
-	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING);
+	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING);
 
-	if (device.sco_watch) {
-		g_source_remove(device.sco_watch);
-		device.sco_watch = 0;
+	if (dev->sco_watch) {
+		g_source_remove(dev->sco_watch);
+		dev->sco_watch = 0;
 	}
 
-	g_io_channel_shutdown(device.sco, TRUE, NULL);
-	g_io_channel_unref(device.sco);
-	device.sco = NULL;
+	g_io_channel_shutdown(dev->sco, TRUE, NULL);
+	g_io_channel_unref(dev->sco);
+	dev->sco = NULL;
 
-	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
+	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
 	return true;
 }
 
-static bool connect_audio(void)
+static bool connect_audio(struct hf_device *dev)
 {
-	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED)
+	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED)
 		return false;
 
 	/* we haven't negotiated codec, start selection */
-	if ((device.features & HFP_HF_FEAT_CODEC) && !device.negotiated_codec) {
-		select_codec(&device, 0);
+	if ((dev->features & HFP_HF_FEAT_CODEC) && !dev->negotiated_codec) {
+		select_codec(dev, 0);
 		return true;
 	}
 
-	return connect_sco();
+	return connect_sco(dev);
 }
 
 static void handle_connect_audio(const void *buf, uint16_t len)
@@ -1731,7 +1731,7 @@ static void handle_connect_audio(const void *buf, uint16_t len)
 		goto done;
 	}
 
-	status = connect_audio() ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
+	status = connect_audio(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
 
 done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -1754,7 +1754,7 @@ static void handle_disconnect_audio(const void *buf, uint16_t len)
 		goto done;
 	}
 
-	status = disconnect_sco() ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
+	status = disconnect_sco(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
 
 done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -2042,7 +2042,7 @@ static void phone_state_dialing(int num_active, int num_held)
 		update_indicator(IND_CALLHELD, 2);
 
 	if (device.num_active == 0 && device.num_held == 0)
-		connect_audio();
+		connect_audio(&device);
 }
 
 static void phone_state_alerting(int num_active, int num_held)
@@ -2136,7 +2136,7 @@ static void phone_state_idle(int num_active, int num_held)
 			update_indicator(IND_CALL, 1);
 
 			if (device.num_active == 0 && device.num_held == 0)
-				connect_audio();
+				connect_audio(&device);
 		}
 
 		if (num_held > device.num_held)
@@ -2180,9 +2180,9 @@ static void phone_state_idle(int num_active, int num_held)
 			 * was no call setup change this means that there were
 			 * calls present when headset was connected.
 			 */
-			connect_audio();
+			connect_audio(&device);
 		} else if (num_active == 0 && num_held == 0) {
-			disconnect_sco();
+			disconnect_sco(&device);
 		}
 
 		update_indicator(IND_CALLHELD,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 10/13] android/handsfree: Pass device object to disconnect watch
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (7 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 09/13] android/handsfree: Pass device to SCO handling functions Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 11/13] android/handsfree: Pass device to phone state and indicators functions Szymon Janc
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index c41748b..0b57822 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -270,9 +270,11 @@ static void device_cleanup(struct hf_device *dev)
 
 static void disconnect_watch(void *user_data)
 {
+	struct hf_device *dev = user_data;
+
 	DBG("");
 
-	device_cleanup(&device);
+	device_cleanup(dev);
 }
 
 static void at_cmd_unknown(const char *command, void *user_data)
@@ -1378,7 +1380,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 	hfp_gw_set_close_on_unref(dev->gw, true);
 	hfp_gw_set_command_handler(dev->gw, at_cmd_unknown, dev, NULL);
-	hfp_gw_set_disconnect_handler(dev->gw, disconnect_watch, NULL, NULL);
+	hfp_gw_set_disconnect_handler(dev->gw, disconnect_watch, dev, NULL);
 
 	if (dev->hsp) {
 		register_post_slc_at(dev);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 11/13] android/handsfree: Pass device to phone state and indicators functions
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (8 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 10/13] android/handsfree: Pass device object to disconnect watch Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  7:12 ` [PATCH 12/13] android/handsfree: Add helper for getting device Szymon Janc
  2014-10-08  7:12 ` [PATCH 13/13] android/handsfree: Make remote device non-static Szymon Janc
  11 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 172 +++++++++++++++++++++++++++-------------------------
 1 file changed, 89 insertions(+), 83 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 0b57822..60aa504 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -1826,23 +1826,23 @@ static void handle_volume_control(const void *buf, uint16_t len)
 				HAL_OP_HANDSFREE_VOLUME_CONTROL, status);
 }
 
-static void update_indicator(int ind, uint8_t val)
+static void update_indicator(struct hf_device *dev, int ind, uint8_t val)
 {
-	DBG("ind=%u new=%u old=%u", ind, val, device.inds[ind].val);
+	DBG("ind=%u new=%u old=%u", ind, val, dev->inds[ind].val);
 
-	if (device.inds[ind].val == val)
+	if (dev->inds[ind].val == val)
 		return;
 
-	device.inds[ind].val = val;
+	dev->inds[ind].val = val;
 
-	if (!device.indicators_enabled)
+	if (!dev->indicators_enabled)
 		return;
 
-	if (!device.inds[ind].active)
+	if (!dev->inds[ind].active)
 		return;
 
 	/* indicator numbers in CIEV start from 1 */
-	hfp_gw_send_info(device.gw, "+CIEV: %u,%u", ind + 1, val);
+	hfp_gw_send_info(dev->gw, "+CIEV: %u,%u", ind + 1, val);
 }
 
 static void handle_device_status_notif(const void *buf, uint16_t len)
@@ -1851,10 +1851,10 @@ static void handle_device_status_notif(const void *buf, uint16_t len)
 
 	DBG("");
 
-	update_indicator(IND_SERVICE, cmd->state);
-	update_indicator(IND_ROAM, cmd->type);
-	update_indicator(IND_SIGNAL, cmd->signal);
-	update_indicator(IND_BATTCHG, cmd->battery);
+	update_indicator(&device, IND_SERVICE, cmd->state);
+	update_indicator(&device, IND_ROAM, cmd->type);
+	update_indicator(&device, IND_SIGNAL, cmd->signal);
+	update_indicator(&device, IND_BATTCHG, cmd->battery);
 
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 					HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
@@ -2036,171 +2036,176 @@ static gboolean ring_cb(gpointer user_data)
 	return TRUE;
 }
 
-static void phone_state_dialing(int num_active, int num_held)
+static void phone_state_dialing(struct hf_device *dev, int num_active,
+								int num_held)
 {
-	update_indicator(IND_CALLSETUP, 2);
+	update_indicator(dev, IND_CALLSETUP, 2);
 
 	if (num_active == 0 && num_held > 0)
-		update_indicator(IND_CALLHELD, 2);
+		update_indicator(dev, IND_CALLHELD, 2);
 
-	if (device.num_active == 0 && device.num_held == 0)
-		connect_audio(&device);
+	if (dev->num_active == 0 && dev->num_held == 0)
+		connect_audio(dev);
 }
 
-static void phone_state_alerting(int num_active, int num_held)
+static void phone_state_alerting(struct hf_device *dev, int num_active,
+								int num_held)
 {
-	update_indicator(IND_CALLSETUP, 3);
+	update_indicator(dev, IND_CALLSETUP, 3);
 }
 
-static void phone_state_waiting(int num_active, int num_held, uint8_t type,
+static void phone_state_waiting(struct hf_device *dev, int num_active,
+					int num_held, uint8_t type,
 					const uint8_t *number, int number_len)
 {
 	char *num;
 
-	if (!device.ccwa_enabled)
+	if (!dev->ccwa_enabled)
 		return;
 
 	num = number_len ? (char *) number : "";
 
 	if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+')
-		hfp_gw_send_info(device.gw, "+CCWA: \"+%s\",%u", num, type);
+		hfp_gw_send_info(dev->gw, "+CCWA: \"+%s\",%u", num, type);
 	else
-		hfp_gw_send_info(device.gw, "+CCWA: \"%s\",%u", num, type);
+		hfp_gw_send_info(dev->gw, "+CCWA: \"%s\",%u", num, type);
 
-	update_indicator(IND_CALLSETUP, 1);
+	update_indicator(dev, IND_CALLSETUP, 1);
 }
 
-static void phone_state_incoming(int num_active, int num_held, uint8_t type,
+static void phone_state_incoming(struct hf_device *dev, int num_active,
+					int num_held, uint8_t type,
 					const uint8_t *number, int number_len)
 {
 	char *num;
 
-	if (device.setup_state == HAL_HANDSFREE_CALL_STATE_INCOMING) {
-		if (device.num_active != num_active ||
-						device.num_held != num_held) {
+	if (dev->setup_state == HAL_HANDSFREE_CALL_STATE_INCOMING) {
+		if (dev->num_active != num_active ||
+						dev->num_held != num_held) {
 			/*
 			 * calls changed while waiting call ie. due to
 			 * termination of active call
 			 */
-			update_indicator(IND_CALLHELD,
+			update_indicator(dev, IND_CALLHELD,
 					num_held ? (num_active ? 1 : 2) : 0);
-			update_indicator(IND_CALL, !!(num_active + num_held));
+			update_indicator(dev, IND_CALL,
+						!!(num_active + num_held));
 		}
 
 		return;
 	}
 
-	if (device.call_hanging_up)
+	if (dev->call_hanging_up)
 		return;
 
 	if (num_active > 0 || num_held > 0) {
-		phone_state_waiting(num_active, num_held, type, number,
+		phone_state_waiting(dev, num_active, num_held, type, number,
 								number_len);
 		return;
 	}
 
-	update_indicator(IND_CALLSETUP, 1);
+	update_indicator(dev, IND_CALLSETUP, 1);
 
 	num = number_len ? (char *) number : "";
 
 	if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+')
-		device.clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type);
+		dev->clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type);
 	else
-		device.clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type);
+		dev->clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type);
 
 	/* send first RING */
-	ring_cb(&device);
+	ring_cb(dev);
 
-	device.ring = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+	dev->ring = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
 							RING_TIMEOUT, ring_cb,
-							&device, NULL);
-	if (!device.ring) {
-		g_free(device.clip);
-		device.clip = NULL;
+							dev, NULL);
+	if (!dev->ring) {
+		g_free(dev->clip);
+		dev->clip = NULL;
 	}
 }
 
-static void phone_state_idle(int num_active, int num_held)
+static void phone_state_idle(struct hf_device *dev, int num_active,
+								int num_held)
 {
-	if (device.ring) {
-		g_source_remove(device.ring);
-		device.ring = 0;
+	if (dev->ring) {
+		g_source_remove(dev->ring);
+		dev->ring = 0;
 
-		if (device.clip) {
-			g_free(device.clip);
-			device.clip = NULL;
+		if (dev->clip) {
+			g_free(dev->clip);
+			dev->clip = NULL;
 		}
 	}
 
-	switch (device.setup_state) {
+	switch (dev->setup_state) {
 	case HAL_HANDSFREE_CALL_STATE_INCOMING:
-		if (num_active > device.num_active) {
-			update_indicator(IND_CALL, 1);
+		if (num_active > dev->num_active) {
+			update_indicator(dev, IND_CALL, 1);
 
-			if (device.num_active == 0 && device.num_held == 0)
-				connect_audio(&device);
+			if (dev->num_active == 0 && dev->num_held == 0)
+				connect_audio(dev);
 		}
 
-		if (num_held > device.num_held)
-			update_indicator(IND_CALLHELD, 1);
+		if (num_held > dev->num_held)
+			update_indicator(dev, IND_CALLHELD, 1);
 
-		update_indicator(IND_CALLSETUP, 0);
+		update_indicator(dev, IND_CALLSETUP, 0);
 
-		if (num_active == device.num_active &&
-						num_held == device.num_held)
-			device.call_hanging_up = true;
+		if (num_active == dev->num_active && num_held == dev->num_held)
+			dev->call_hanging_up = true;
 
 		break;
 	case HAL_HANDSFREE_CALL_STATE_DIALING:
 	case HAL_HANDSFREE_CALL_STATE_ALERTING:
-		if (num_active > device.num_active)
-			update_indicator(IND_CALL, 1);
+		if (num_active > dev->num_active)
+			update_indicator(dev, IND_CALL, 1);
 
-		update_indicator(IND_CALLHELD,
+		update_indicator(dev, IND_CALLHELD,
 					num_held ? (num_active ? 1 : 2) : 0);
 
-		update_indicator(IND_CALLSETUP, 0);
+		update_indicator(dev, IND_CALLSETUP, 0);
 		break;
 	case HAL_HANDSFREE_CALL_STATE_IDLE:
 
-		if (device.call_hanging_up) {
-			device.call_hanging_up = false;
+		if (dev->call_hanging_up) {
+			dev->call_hanging_up = false;
 			return;
 		}
 
 		/* check if calls swapped */
 		if (num_held != 0 && num_active != 0 &&
-				device.num_active == num_held &&
-				device.num_held == num_active) {
+				dev->num_active == num_held &&
+				dev->num_held == num_active) {
 			/* TODO better way for forcing indicator */
-			device.inds[IND_CALLHELD].val = 0;
+			dev->inds[IND_CALLHELD].val = 0;
 		} else if ((num_active > 0 || num_held > 0) &&
-						device.num_active == 0 &&
-						device.num_held == 0) {
+						dev->num_active == 0 &&
+						dev->num_held == 0) {
 			/*
 			 * If number of active or held calls change but there
 			 * was no call setup change this means that there were
 			 * calls present when headset was connected.
 			 */
-			connect_audio(&device);
+			connect_audio(dev);
 		} else if (num_active == 0 && num_held == 0) {
-			disconnect_sco(&device);
+			disconnect_sco(dev);
 		}
 
-		update_indicator(IND_CALLHELD,
+		update_indicator(dev, IND_CALLHELD,
 					num_held ? (num_active ? 1 : 2) : 0);
-		update_indicator(IND_CALL, !!(num_active + num_held));
-		update_indicator(IND_CALLSETUP, 0);
+		update_indicator(dev, IND_CALL, !!(num_active + num_held));
+		update_indicator(dev, IND_CALLSETUP, 0);
 
 		/* If call was terminated due to carrier lost send NO CARRIER */
 		if (num_active == 0 && num_held == 0 &&
-				device.inds[IND_SERVICE].val == 0 &&
-				(device.num_active > 0 || device.num_held > 0))
-			hfp_gw_send_info(device.gw, "NO CARRIER");
+				dev->inds[IND_SERVICE].val == 0 &&
+				(dev->num_active > 0 || dev->num_held > 0))
+			hfp_gw_send_info(dev->gw, "NO CARRIER");
 
 		break;
 	default:
-		DBG("unhandled state %u", device.setup_state);
+		DBG("unhandled state %u", dev->setup_state);
 		break;
 	}
 }
@@ -2222,17 +2227,18 @@ static void handle_phone_state_change(const void *buf, uint16_t len)
 
 	switch (cmd->state) {
 	case HAL_HANDSFREE_CALL_STATE_DIALING:
-		phone_state_dialing(cmd->num_active, cmd->num_held);
+		phone_state_dialing(&device, cmd->num_active, cmd->num_held);
 		break;
 	case HAL_HANDSFREE_CALL_STATE_ALERTING:
-		phone_state_alerting(cmd->num_active, cmd->num_held);
+		phone_state_alerting(&device, cmd->num_active, cmd->num_held);
 		break;
 	case HAL_HANDSFREE_CALL_STATE_INCOMING:
-		phone_state_incoming(cmd->num_active, cmd->num_held, cmd->type,
-						cmd->number, cmd->number_len);
+		phone_state_incoming(&device, cmd->num_active, cmd->num_held,
+						cmd->type, cmd->number,
+						cmd->number_len);
 		break;
 	case HAL_HANDSFREE_CALL_STATE_IDLE:
-		phone_state_idle(cmd->num_active, cmd->num_held);
+		phone_state_idle(&device, cmd->num_active, cmd->num_held);
 		break;
 	default:
 		DBG("unhandled new state %u (current state %u)", cmd->state,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 12/13] android/handsfree: Add helper for getting device
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (9 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 11/13] android/handsfree: Pass device to phone state and indicators functions Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  8:23   ` Andrei Emeltchenko
  2014-10-08  7:12 ` [PATCH 13/13] android/handsfree: Make remote device non-static Szymon Janc
  11 siblings, 1 reply; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

For now this is just dummy to minime use of global static device.
---
 android/handsfree.c | 321 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 238 insertions(+), 83 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 60aa504..58eade4 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -172,6 +172,32 @@ static GIOChannel *hsp_server = NULL;
 
 static GIOChannel *sco_server = NULL;
 
+static struct hf_device *find_default_device(void)
+{
+	/* TODO should be replaced by find_device() eventually */
+
+	return &device;
+}
+
+static struct hf_device *find_device(const bdaddr_t *bdaddr)
+{
+	if (bacmp(&device.bdaddr, bdaddr))
+		return NULL;
+
+	return &device;
+}
+
+static struct hf_device *get_device(const bdaddr_t *bdaddr)
+{
+	struct hf_device *dev;
+
+	dev = find_device(bdaddr);
+	if (dev)
+		return dev;
+
+	return &device;
+}
+
 static void set_state(struct hf_device *dev, uint8_t state)
 {
 	struct hal_ev_handsfree_conn_state ev;
@@ -1403,6 +1429,7 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
 	char address[18];
 	bdaddr_t bdaddr;
 	GError *err = NULL;
+	struct hf_device *dev;
 
 	bt_io_get(chan, &err,
 			BT_IO_OPT_DEST, address,
@@ -1416,20 +1443,26 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
 
 	DBG("incoming connect from %s", address);
 
-	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
+	dev = get_device(&bdaddr);
+	if (!dev) {
+		error("handsfree: Failed to get device object for %s", address);
+		goto drop;
+	}
+
+	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
 		info("handsfree: refusing connection from %s", address);
 		goto drop;
 	}
 
-	device_init(&device, &bdaddr);
+	device_init(dev, &bdaddr);
 
-	if (!bt_io_accept(chan, connect_cb, &device, NULL, NULL)) {
+	if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) {
 		error("handsfree: failed to accept connection");
-		device_cleanup(&device);
+		device_cleanup(dev);
 		goto drop;
 	}
 
-	device.hsp = GPOINTER_TO_INT(data);
+	dev->hsp = GPOINTER_TO_INT(data);
 	return;
 
 drop:
@@ -1612,6 +1645,7 @@ static int sdp_search_hfp(struct hf_device *dev)
 static void handle_connect(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_connect *cmd = buf;
+	struct hf_device *dev;
 	char addr[18];
 	uint8_t status;
 	bdaddr_t bdaddr;
@@ -1619,23 +1653,34 @@ static void handle_connect(const void *buf, uint16_t len)
 
 	DBG("");
 
-	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
+	dev = find_default_device();
+	if (dev) {
 		status = HAL_STATUS_FAILED;
 		goto failed;
 	}
 
 	android2bdaddr(&cmd->bdaddr, &bdaddr);
+	dev = get_device(&bdaddr);
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
 
 	ba2str(&bdaddr, addr);
 	DBG("connecting to %s", addr);
 
-	device_init(&device, &bdaddr);
+	device_init(dev, &bdaddr);
 
 	/* prefer HFP over HSP */
-	ret = hfp_server ? sdp_search_hfp(&device) : sdp_search_hsp(&device);
+	ret = hfp_server ? sdp_search_hfp(dev) : sdp_search_hsp(dev);
 	if (ret < 0) {
 		error("handsfree: SDP search failed");
-		device_cleanup(&device);
+		device_cleanup(dev);
 		status = HAL_STATUS_FAILED;
 		goto failed;
 	}
@@ -1650,6 +1695,7 @@ failed:
 static void handle_disconnect(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_disconnect *cmd = buf;
+	struct hf_device *dev;
 	bdaddr_t bdaddr;
 	uint8_t status;
 
@@ -1657,23 +1703,28 @@ static void handle_disconnect(const void *buf, uint16_t len)
 
 	android2bdaddr(cmd->bdaddr, &bdaddr);
 
-	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED ||
-			bacmp(&device.bdaddr, &bdaddr)) {
+	dev = find_device(&bdaddr);
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
 		status = HAL_STATUS_FAILED;
 		goto failed;
 
 	}
 
-	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
+	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
 		status = HAL_STATUS_SUCCESS;
 		goto failed;
 	}
 
-	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
-		device_cleanup(&device);
+	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
+		device_cleanup(dev);
 	} else {
-		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
-		hfp_gw_disconnect(device.gw);
+		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
+		hfp_gw_disconnect(dev->gw);
 	}
 
 	status = HAL_STATUS_SUCCESS;
@@ -1720,6 +1771,7 @@ static bool connect_audio(struct hf_device *dev)
 static void handle_connect_audio(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_connect_audio *cmd = buf;
+	struct hf_device *dev;
 	bdaddr_t bdaddr;
 	uint8_t status;
 
@@ -1727,13 +1779,18 @@ static void handle_connect_audio(const void *buf, uint16_t len)
 
 	android2bdaddr(cmd->bdaddr, &bdaddr);
 
-	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED ||
-			bacmp(&device.bdaddr, &bdaddr)) {
+	dev = find_device(&bdaddr);
+	if (!dev) {
 		status = HAL_STATUS_FAILED;
 		goto done;
 	}
 
-	status = connect_audio(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
+	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	status = connect_audio(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
 
 done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -1743,6 +1800,7 @@ done:
 static void handle_disconnect_audio(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_disconnect_audio *cmd = buf;
+	struct hf_device *dev;
 	bdaddr_t bdaddr;
 	uint8_t status;
 
@@ -1750,13 +1808,18 @@ static void handle_disconnect_audio(const void *buf, uint16_t len)
 
 	android2bdaddr(cmd->bdaddr, &bdaddr);
 
-	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED ||
-			bacmp(&device.bdaddr, &bdaddr)) {
+	dev = find_device(&bdaddr);
+	if (!dev) {
 		status = HAL_STATUS_FAILED;
 		goto done;
 	}
 
-	status = disconnect_sco(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
+	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	status = disconnect_sco(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
 
 done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -1765,34 +1828,50 @@ done:
 
 static void handle_start_vr(const void *buf, uint16_t len)
 {
+	struct hf_device *dev;
 	uint8_t status;
 
 	DBG("");
 
-	if (device.features & HFP_HF_FEAT_VR) {
-		hfp_gw_send_info(device.gw, "+BVRA: 1");
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (dev->features & HFP_HF_FEAT_VR) {
+		hfp_gw_send_info(dev->gw, "+BVRA: 1");
 		status = HAL_STATUS_SUCCESS;
 	} else {
 		status = HAL_STATUS_FAILED;
 	}
 
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 					HAL_OP_HANDSFREE_START_VR, status);
 }
 
 static void handle_stop_vr(const void *buf, uint16_t len)
 {
+	struct hf_device *dev;
 	uint8_t status;
 
 	DBG("");
 
-	if (device.features & HFP_HF_FEAT_VR) {
-		hfp_gw_send_info(device.gw, "+BVRA: 0");
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (dev->features & HFP_HF_FEAT_VR) {
+		hfp_gw_send_info(dev->gw, "+BVRA: 0");
 		status = HAL_STATUS_SUCCESS;
 	} else {
 		status = HAL_STATUS_FAILED;
 	}
 
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 				HAL_OP_HANDSFREE_STOP_VR, status);
 }
@@ -1800,20 +1879,27 @@ static void handle_stop_vr(const void *buf, uint16_t len)
 static void handle_volume_control(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_volume_control *cmd = buf;
+	struct hf_device *dev;
 	uint8_t status, volume;
 
 	DBG("type=%u volume=%u", cmd->type, cmd->volume);
 
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
 	volume = cmd->volume > 15 ? 15 : cmd->volume;
 
 	switch (cmd->type) {
 	case HAL_HANDSFREE_VOLUME_TYPE_MIC:
-		hfp_gw_send_info(device.gw, "+VGM: %u", volume);
+		hfp_gw_send_info(dev->gw, "+VGM: %u", volume);
 
 		status = HAL_STATUS_SUCCESS;
 		break;
 	case HAL_HANDSFREE_VOLUME_TYPE_SPEAKER:
-		hfp_gw_send_info(device.gw, "+VGS: %u", volume);
+		hfp_gw_send_info(dev->gw, "+VGS: %u", volume);
 
 		status = HAL_STATUS_SUCCESS;
 		break;
@@ -1822,6 +1908,7 @@ static void handle_volume_control(const void *buf, uint16_t len)
 		break;
 	}
 
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 				HAL_OP_HANDSFREE_VOLUME_CONTROL, status);
 }
@@ -1848,22 +1935,34 @@ static void update_indicator(struct hf_device *dev, int ind, uint8_t val)
 static void handle_device_status_notif(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_device_status_notif *cmd = buf;
+	struct hf_device *dev;
+	uint8_t status;
 
 	DBG("");
 
-	update_indicator(&device, IND_SERVICE, cmd->state);
-	update_indicator(&device, IND_ROAM, cmd->type);
-	update_indicator(&device, IND_SIGNAL, cmd->signal);
-	update_indicator(&device, IND_BATTCHG, cmd->battery);
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	update_indicator(dev, IND_SERVICE, cmd->state);
+	update_indicator(dev, IND_ROAM, cmd->type);
+	update_indicator(dev, IND_SIGNAL, cmd->signal);
+	update_indicator(dev, IND_BATTCHG, cmd->battery);
 
+	status = HAL_STATUS_SUCCESS;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
-					HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
-					HAL_STATUS_SUCCESS);
+				HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF, status);
 }
 
 static void handle_cops(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_cops_response *cmd = buf;
+	struct hf_device *dev;
+	uint8_t status;
 
 	if (len != sizeof(*cmd) + cmd->len ||
 			(cmd->len != 0 && cmd->buf[cmd->len - 1] != '\0')) {
@@ -1874,13 +1973,22 @@ static void handle_cops(const void *buf, uint16_t len)
 
 	DBG("");
 
-	hfp_gw_send_info(device.gw, "+COPS: 0,0,\"%.16s\"",
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	hfp_gw_send_info(dev->gw, "+COPS: 0,0,\"%.16s\"",
 					cmd->len ? (char *) cmd->buf : "");
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
+
+	status = HAL_STATUS_SUCCESS;
 
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
-			HAL_OP_HANDSFREE_COPS_RESPONSE, HAL_STATUS_SUCCESS);
+				HAL_OP_HANDSFREE_COPS_RESPONSE, status);
 }
 
 static unsigned int get_callsetup(uint8_t state)
@@ -1900,38 +2008,51 @@ static unsigned int get_callsetup(uint8_t state)
 static void handle_cind(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_cind_response *cmd = buf;
+	struct hf_device *dev;
+	uint8_t status;
 
 	DBG("");
 
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
 	/* HAL doesn't provide indicators values so need to convert here */
-	device.inds[IND_SERVICE].val = cmd->svc;
-	device.inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held);
-	device.inds[IND_CALLSETUP].val = get_callsetup(cmd->state);
-	device.inds[IND_CALLHELD].val = cmd->num_held ?
+	dev->inds[IND_SERVICE].val = cmd->svc;
+	dev->inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held);
+	dev->inds[IND_CALLSETUP].val = get_callsetup(cmd->state);
+	dev->inds[IND_CALLHELD].val = cmd->num_held ?
 						(cmd->num_active ? 1 : 2) : 0;
-	device.inds[IND_SIGNAL].val = cmd->signal;
-	device.inds[IND_ROAM].val = cmd->roam;
-	device.inds[IND_BATTCHG].val = cmd->batt_chg;
+	dev->inds[IND_SIGNAL].val = cmd->signal;
+	dev->inds[IND_ROAM].val = cmd->roam;
+	dev->inds[IND_BATTCHG].val = cmd->batt_chg;
 
 	/* Order must match indicators_defaults table */
-	hfp_gw_send_info(device.gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
-						device.inds[IND_SERVICE].val,
-						device.inds[IND_CALL].val,
-						device.inds[IND_CALLSETUP].val,
-						device.inds[IND_CALLHELD].val,
-						device.inds[IND_SIGNAL].val,
-						device.inds[IND_ROAM].val,
-						device.inds[IND_BATTCHG].val);
+	hfp_gw_send_info(dev->gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
+						dev->inds[IND_SERVICE].val,
+						dev->inds[IND_CALL].val,
+						dev->inds[IND_CALLSETUP].val,
+						dev->inds[IND_CALLHELD].val,
+						dev->inds[IND_SIGNAL].val,
+						dev->inds[IND_ROAM].val,
+						dev->inds[IND_BATTCHG].val);
 
-	hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
+	status = HAL_STATUS_SUCCESS;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
-			HAL_OP_HANDSFREE_CIND_RESPONSE, HAL_STATUS_SUCCESS);
+				HAL_OP_HANDSFREE_CIND_RESPONSE, status);
 }
 
 static void handle_formatted_at_resp(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_formatted_at_response *cmd = buf;
+	struct hf_device *dev;
+	uint8_t status;
 
 	DBG("");
 
@@ -1942,33 +2063,53 @@ static void handle_formatted_at_resp(const void *buf, uint16_t len)
 		return;
 	}
 
-	hfp_gw_send_info(device.gw, "%s", cmd->len ? (char *) cmd->buf : "");
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
 
+	hfp_gw_send_info(dev->gw, "%s", cmd->len ? (char *) cmd->buf : "");
+
+	status = HAL_STATUS_SUCCESS;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
-					HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
-					HAL_STATUS_SUCCESS);
+			HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE, status);
 }
 
 static void handle_at_resp(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_at_response *cmd = buf;
+	struct hf_device *dev;
+	uint8_t status;
 
 	DBG("");
 
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
 	if (cmd->response == HAL_HANDSFREE_AT_RESPONSE_OK)
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
-	else if (device.cmee_enabled)
-		hfp_gw_send_error(device.gw, cmd->error);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
+	else if (dev->cmee_enabled)
+		hfp_gw_send_error(dev->gw, cmd->error);
 	else
-		hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
+
+	status = HAL_STATUS_SUCCESS;
 
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
-			HAL_OP_HANDSFREE_AT_RESPONSE, HAL_STATUS_SUCCESS);
+					HAL_OP_HANDSFREE_AT_RESPONSE, status);
 }
 
 static void handle_clcc_resp(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_clcc_response *cmd = buf;
+	struct hf_device *dev;
 	uint8_t status;
 	char *number;
 
@@ -1981,8 +2122,14 @@ static void handle_clcc_resp(const void *buf, uint16_t len)
 
 	DBG("");
 
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
 	if (!cmd->index) {
-		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 
 		status = HAL_STATUS_SUCCESS;
 		goto done;
@@ -1999,13 +2146,13 @@ static void handle_clcc_resp(const void *buf, uint16_t len)
 	case HAL_HANDSFREE_CALL_STATE_ALERTING:
 		if (cmd->type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL &&
 							number[0] != '+')
-			hfp_gw_send_info(device.gw,
+			hfp_gw_send_info(dev->gw,
 					"+CLCC: %u,%u,%u,%u,%u,\"+%s\",%u",
 					cmd->index, cmd->dir, cmd->state,
 					cmd->mode, cmd->mpty, number,
 					cmd->type);
 		else
-			hfp_gw_send_info(device.gw,
+			hfp_gw_send_info(dev->gw,
 					"+CLCC: %u,%u,%u,%u,%u,\"%s\",%u",
 					cmd->index, cmd->dir, cmd->state,
 					cmd->mode, cmd->mpty, number,
@@ -2213,6 +2360,7 @@ static void phone_state_idle(struct hf_device *dev, int num_active,
 static void handle_phone_state_change(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_phone_state_change *cmd = buf;
+	struct hf_device *dev;
 	uint8_t status;
 
 	if (len != sizeof(*cmd) + cmd->number_len || (cmd->number_len != 0 &&
@@ -2225,32 +2373,38 @@ static void handle_phone_state_change(const void *buf, uint16_t len)
 	DBG("active=%u hold=%u state=%u", cmd->num_active, cmd->num_held,
 								cmd->state);
 
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
 	switch (cmd->state) {
 	case HAL_HANDSFREE_CALL_STATE_DIALING:
-		phone_state_dialing(&device, cmd->num_active, cmd->num_held);
+		phone_state_dialing(dev, cmd->num_active, cmd->num_held);
 		break;
 	case HAL_HANDSFREE_CALL_STATE_ALERTING:
-		phone_state_alerting(&device, cmd->num_active, cmd->num_held);
+		phone_state_alerting(dev, cmd->num_active, cmd->num_held);
 		break;
 	case HAL_HANDSFREE_CALL_STATE_INCOMING:
-		phone_state_incoming(&device, cmd->num_active, cmd->num_held,
+		phone_state_incoming(dev, cmd->num_active, cmd->num_held,
 						cmd->type, cmd->number,
 						cmd->number_len);
 		break;
 	case HAL_HANDSFREE_CALL_STATE_IDLE:
-		phone_state_idle(&device, cmd->num_active, cmd->num_held);
+		phone_state_idle(dev, cmd->num_active, cmd->num_held);
 		break;
 	default:
 		DBG("unhandled new state %u (current state %u)", cmd->state,
-							device.setup_state);
+							dev->setup_state);
 
 		status = HAL_STATUS_FAILED;
 		goto failed;
 	}
 
-	device.num_active = cmd->num_active;
-	device.num_held = cmd->num_held;
-	device.setup_state = cmd->state;
+	dev->num_active = cmd->num_active;
+	dev->num_held = cmd->num_held;
+	dev->setup_state = cmd->state;
 
 	status = HAL_STATUS_SUCCESS;
 
@@ -2374,9 +2528,7 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
 	char address[18];
 	bdaddr_t bdaddr;
 	GError *err = NULL;
-
-	if (device.sco)
-		goto drop;
+	struct hf_device *dev;
 
 	bt_io_get(chan, &err,
 			BT_IO_OPT_DEST, address,
@@ -2390,18 +2542,19 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
 
 	DBG("incoming SCO connection from %s", address);
 
-	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED ||
-			bacmp(&device.bdaddr, &bdaddr)) {
+	dev = find_device(&bdaddr);
+	if (!dev || dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED ||
+								dev->sco) {
 		error("handsfree: audio connection from %s rejected", address);
 		goto drop;
 	}
 
-	if (!bt_io_accept(chan, connect_sco_cb, &device, NULL, NULL)) {
+	if (!bt_io_accept(chan, connect_sco_cb, dev, NULL, NULL)) {
 		error("handsfree: failed to accept audio connection");
 		goto drop;
 	}
 
-	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
+	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
 	return;
 
 drop:
@@ -2633,21 +2786,23 @@ static void bt_sco_get_fd(const void *buf, uint16_t len)
 	int fd;
 	GError *err;
 	struct sco_rsp_get_fd rsp;
+	struct hf_device *dev;
 
 	DBG("");
 
-	if (!device.sco)
+	dev = find_default_device();
+	if (!dev || !dev->sco)
 		goto failed;
 
 	err = NULL;
-	if (!bt_io_get(device.sco, &err, BT_IO_OPT_MTU, &rsp.mtu,
+	if (!bt_io_get(dev->sco, &err, BT_IO_OPT_MTU, &rsp.mtu,
 							BT_IO_OPT_INVALID)) {
 		error("Unable to get MTU: %s\n", err->message);
 		g_clear_error(&err);
 		goto failed;
 	}
 
-	fd = g_io_channel_unix_get_fd(device.sco);
+	fd = g_io_channel_unix_get_fd(dev->sco);
 
 	DBG("fd %d mtu %u", fd, rsp.mtu);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 13/13] android/handsfree: Make remote device non-static
  2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
                   ` (10 preceding siblings ...)
  2014-10-08  7:12 ` [PATCH 12/13] android/handsfree: Add helper for getting device Szymon Janc
@ 2014-10-08  7:12 ` Szymon Janc
  2014-10-08  8:30   ` Andrei Emeltchenko
  11 siblings, 1 reply; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  7:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Remote device object is now created on-demand instead of being static.
---
 android/handsfree.c | 144 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 86 insertions(+), 58 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 58eade4..2e617f6 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -37,6 +37,8 @@
 #include "src/sdp-client.h"
 #include "src/uuid-helper.h"
 #include "src/shared/hfp.h"
+#include "src/shared/queue.h"
+#include "src/shared/util.h"
 #include "btio/btio.h"
 #include "hal-msg.h"
 #include "ipc-common.h"
@@ -155,7 +157,7 @@ static const struct hfp_codec codecs_defaults[] = {
 	{ CODEC_ID_MSBC, false, false},
 };
 
-static struct hf_device device;
+static struct queue *devices = NULL;
 
 static uint32_t hfp_ag_features = 0;
 
@@ -172,32 +174,6 @@ static GIOChannel *hsp_server = NULL;
 
 static GIOChannel *sco_server = NULL;
 
-static struct hf_device *find_default_device(void)
-{
-	/* TODO should be replaced by find_device() eventually */
-
-	return &device;
-}
-
-static struct hf_device *find_device(const bdaddr_t *bdaddr)
-{
-	if (bacmp(&device.bdaddr, bdaddr))
-		return NULL;
-
-	return &device;
-}
-
-static struct hf_device *get_device(const bdaddr_t *bdaddr)
-{
-	struct hf_device *dev;
-
-	dev = find_device(bdaddr);
-	if (dev)
-		return dev;
-
-	return &device;
-}
-
 static void set_state(struct hf_device *dev, uint8_t state)
 {
 	struct hal_ev_handsfree_conn_state ev;
@@ -246,28 +222,38 @@ static void init_codecs(struct hf_device *dev)
 		dev->codecs[MSBC_OFFSET].local_supported = true;
 }
 
-static void device_init(struct hf_device *dev, const bdaddr_t *bdaddr)
+static struct hf_device *device_create(const bdaddr_t *bdaddr)
 {
-	bacpy(&dev->bdaddr, bdaddr);
+	struct hf_device *dev;
 
+	dev = new0(struct hf_device, 1);
+	if (!dev)
+		return NULL;
+
+	bacpy(&dev->bdaddr, bdaddr);
 	dev->setup_state = HAL_HANDSFREE_CALL_STATE_IDLE;
+	dev->state = HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
+	dev->audio_state = HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
 
 	memcpy(dev->inds, inds_defaults, sizeof(dev->inds));
 
 	init_codecs(dev);
 
-	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
+	if (!queue_push_head(devices, dev)) {
+		free(dev);
+		return NULL;
+	}
+
+	return dev;
 }
 
-static void device_cleanup(struct hf_device *dev)
+static void device_destroy(struct hf_device *dev)
 {
 	if (dev->gw) {
 		hfp_gw_unref(dev->gw);
 		dev->gw = NULL;
 	}
 
-	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);
-
 	if (dev->sco_watch) {
 		g_source_remove(dev->sco_watch);
 		dev->sco_watch = 0;
@@ -290,8 +276,45 @@ static void device_cleanup(struct hf_device *dev)
 	}
 
 	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
+	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);
+
+	queue_remove(devices, dev);
+	free(dev);
+}
+
+static struct hf_device *find_default_device(void)
+{
+	/* TODO should be replaced by find_device() eventually */
+
+	return queue_peek_head(devices);
+}
 
-	memset(dev, 0, sizeof(*dev));
+static bool match_by_bdaddr(const void *data, const void *match_data)
+{
+	const struct hf_device *dev = data;
+	const bdaddr_t *addr = match_data;
+
+	return !bacmp(&dev->bdaddr, addr);
+}
+
+static struct hf_device *find_device(const bdaddr_t *bdaddr)
+{
+	return queue_find(devices, match_by_bdaddr, bdaddr);
+}
+
+static struct hf_device *get_device(const bdaddr_t *bdaddr)
+{
+	struct hf_device *dev;
+
+	dev = find_device(bdaddr);
+	if (dev)
+		return dev;
+
+	/* TODO For now allow only 1 remote device */
+	if (!queue_isempty(devices))
+		return NULL;
+
+	return device_create(bdaddr);
 }
 
 static void disconnect_watch(void *user_data)
@@ -300,7 +323,7 @@ static void disconnect_watch(void *user_data)
 
 	DBG("");
 
-	device_cleanup(dev);
+	device_destroy(dev);
 }
 
 static void at_cmd_unknown(const char *command, void *user_data)
@@ -1421,7 +1444,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 failed:
 	g_io_channel_shutdown(chan, TRUE, NULL);
-	device_cleanup(dev);
+	device_destroy(dev);
 }
 
 static void confirm_cb(GIOChannel *chan, gpointer data)
@@ -1454,15 +1477,16 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
 		goto drop;
 	}
 
-	device_init(dev, &bdaddr);
-
 	if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) {
 		error("handsfree: failed to accept connection");
-		device_cleanup(dev);
+		device_destroy(dev);
 		goto drop;
 	}
 
 	dev->hsp = GPOINTER_TO_INT(data);
+
+	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
+
 	return;
 
 drop:
@@ -1541,7 +1565,7 @@ static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	device_cleanup(dev);
+	device_destroy(dev);
 }
 
 static int sdp_search_hsp(struct hf_device *dev)
@@ -1629,7 +1653,7 @@ static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	return;
 
 fail:
-	device_cleanup(dev);
+	device_destroy(dev);
 }
 
 static int sdp_search_hfp(struct hf_device *dev)
@@ -1653,13 +1677,8 @@ static void handle_connect(const void *buf, uint16_t len)
 
 	DBG("");
 
-	dev = find_default_device();
-	if (dev) {
-		status = HAL_STATUS_FAILED;
-		goto failed;
-	}
-
 	android2bdaddr(&cmd->bdaddr, &bdaddr);
+
 	dev = get_device(&bdaddr);
 	if (!dev) {
 		status = HAL_STATUS_FAILED;
@@ -1674,17 +1693,17 @@ static void handle_connect(const void *buf, uint16_t len)
 	ba2str(&bdaddr, addr);
 	DBG("connecting to %s", addr);
 
-	device_init(dev, &bdaddr);
-
 	/* prefer HFP over HSP */
 	ret = hfp_server ? sdp_search_hfp(dev) : sdp_search_hsp(dev);
 	if (ret < 0) {
 		error("handsfree: SDP search failed");
-		device_cleanup(dev);
+		device_destroy(dev);
 		status = HAL_STATUS_FAILED;
 		goto failed;
 	}
 
+	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
+
 	status = HAL_STATUS_SUCCESS;
 
 failed:
@@ -1712,7 +1731,6 @@ static void handle_disconnect(const void *buf, uint16_t len)
 	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
 		status = HAL_STATUS_FAILED;
 		goto failed;
-
 	}
 
 	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
@@ -1721,7 +1739,7 @@ static void handle_disconnect(const void *buf, uint16_t len)
 	}
 
 	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
-		device_cleanup(dev);
+		device_destroy(dev);
 	} else {
 		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
 		hfp_gw_disconnect(dev->gw);
@@ -2849,13 +2867,15 @@ bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 
 	bacpy(&adapter_addr, addr);
 
-	if (!enable_hsp_ag())
+	devices = queue_new();
+	if (!devices)
 		return false;
 
-	if (!enable_sco_server()) {
-		cleanup_hsp_ag();
-		return false;
-	}
+	if (!enable_hsp_ag())
+		goto failed_queue;
+
+	if (!enable_sco_server())
+		goto failed_hsp;
 
 	if (mode == HAL_MODE_HANDSFREE_HSP_ONLY)
 		goto done;
@@ -2868,9 +2888,14 @@ bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 	if (enable_hfp_ag())
 		goto done;
 
-	cleanup_hsp_ag();
 	disable_sco_server();
 	hfp_ag_features = 0;
+failed_hsp:
+	cleanup_hsp_ag();
+failed_queue:
+	queue_destroy(devices, NULL);
+	devices = NULL;
+
 	return false;
 
 done:
@@ -2896,4 +2921,7 @@ void bt_handsfree_unregister(void)
 	disable_sco_server();
 
 	hfp_ag_features = 0;
+
+	queue_destroy(devices, (queue_destroy_func_t) device_destroy);
+	devices = NULL;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 08/13] android/handsfree: Move clip into device structure
  2014-10-08  7:12 ` [PATCH 08/13] android/handsfree: Move clip into device structure Szymon Janc
@ 2014-10-08  8:06   ` Andrei Emeltchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andrei Emeltchenko @ 2014-10-08  8:06 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Wed, Oct 08, 2014 at 09:12:18AM +0200, Szymon Janc wrote:
> ---
>  android/handsfree.c | 36 ++++++++++++++++++++++++------------
>  1 file changed, 24 insertions(+), 12 deletions(-)

This one would benefit from small commit msg.

> 
> diff --git a/android/handsfree.c b/android/handsfree.c
> index d83f0a2..e7b8a6e 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -131,6 +131,7 @@ struct hf_device {
>  	struct hfp_codec codecs[CODECS_COUNT];
>  
>  	guint ring;
> +	char *clip;
>  	bool hsp;
>  
>  	struct hfp_gw *gw;
> @@ -255,6 +256,11 @@ static void device_cleanup(struct hf_device *dev)
>  	if (dev->ring) {
>  		g_source_remove(dev->ring);
>  		dev->ring = 0;
> +
> +		if (dev->clip) {
> +			g_free(dev->clip);
> +			dev->clip = NULL;

Is this needed? apparently there is memset(dev,0,) after that.

Best regards 
Andrei Emeltchenko 

> +		}
>  	}
>  
>  	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
> @@ -2018,12 +2024,12 @@ done:
>  
>  static gboolean ring_cb(gpointer user_data)
>  {
> -	char *clip = user_data;
> +	struct hf_device *dev = user_data;
>  
> -	hfp_gw_send_info(device.gw, "RING");
> +	hfp_gw_send_info(dev->gw, "RING");
>  
> -	if (device.clip_enabled && clip)
> -		hfp_gw_send_info(device.gw, "%s", clip);
> +	if (dev->clip_enabled && dev->clip)
> +		hfp_gw_send_info(dev->gw, "%s", dev->clip);
>  
>  	return TRUE;
>  }
> @@ -2065,7 +2071,7 @@ static void phone_state_waiting(int num_active, int num_held, uint8_t type,
>  static void phone_state_incoming(int num_active, int num_held, uint8_t type,
>  					const uint8_t *number, int number_len)
>  {
> -	char *clip, *num;
> +	char *num;
>  
>  	if (device.setup_state == HAL_HANDSFREE_CALL_STATE_INCOMING) {
>  		if (device.num_active != num_active ||
> @@ -2096,19 +2102,20 @@ static void phone_state_incoming(int num_active, int num_held, uint8_t type,
>  	num = number_len ? (char *) number : "";
>  
>  	if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+')
> -		clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type);
> +		device.clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type);
>  	else
> -		clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type);
> +		device.clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type);
>  
>  	/* send first RING */
> -	ring_cb(clip);
> +	ring_cb(&device);
>  
>  	device.ring = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
>  							RING_TIMEOUT, ring_cb,
> -							clip, g_free);
> -
> -	if (!device.ring)
> -		g_free(clip);
> +							&device, NULL);
> +	if (!device.ring) {
> +		g_free(device.clip);
> +		device.clip = NULL;
> +	}
>  }
>  
>  static void phone_state_idle(int num_active, int num_held)
> @@ -2116,6 +2123,11 @@ static void phone_state_idle(int num_active, int num_held)
>  	if (device.ring) {
>  		g_source_remove(device.ring);
>  		device.ring = 0;
> +
> +		if (device.clip) {
> +			g_free(device.clip);
> +			device.clip = NULL;
> +		}
>  	}
>  
>  	switch (device.setup_state) {
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 09/13] android/handsfree: Pass device to SCO handling functions
  2014-10-08  7:12 ` [PATCH 09/13] android/handsfree: Pass device to SCO handling functions Szymon Janc
@ 2014-10-08  8:10   ` Andrei Emeltchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andrei Emeltchenko @ 2014-10-08  8:10 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Wed, Oct 08, 2014 at 09:12:19AM +0200, Szymon Janc wrote:
> ---
>  android/handsfree.c | 60 ++++++++++++++++++++++++++---------------------------
>  1 file changed, 30 insertions(+), 30 deletions(-)

The same subject as patch 07, maybe they need to be merged?

Best regards 
Andrei Emeltchenko 

> 
> diff --git a/android/handsfree.c b/android/handsfree.c
> index e7b8a6e..c41748b 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -930,25 +930,25 @@ static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
>  	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED);
>  }
>  
> -static bool connect_sco(void)
> +static bool connect_sco(struct hf_device *dev)
>  {
>  	GIOChannel *io;
>  	GError *gerr = NULL;
>  	uint16_t voice_settings;
>  
> -	if (device.sco)
> +	if (dev->sco)
>  		return false;
>  
> -	if (!(device.features & HFP_HF_FEAT_CODEC))
> +	if (!(dev->features & HFP_HF_FEAT_CODEC))
>  		voice_settings = 0;
> -	else if (device.negotiated_codec != CODEC_ID_CVSD)
> +	else if (dev->negotiated_codec != CODEC_ID_CVSD)
>  		voice_settings = BT_VOICE_TRANSPARENT;
>  	else
>  		voice_settings = BT_VOICE_CVSD_16BIT;
>  
> -	io = bt_io_connect(connect_sco_cb, &device, NULL, &gerr,
> +	io = bt_io_connect(connect_sco_cb, dev, NULL, &gerr,
>  				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
> -				BT_IO_OPT_DEST_BDADDR, &device.bdaddr,
> +				BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
>  				BT_IO_OPT_VOICE, voice_settings,
>  				BT_IO_OPT_INVALID);
>  
> @@ -960,7 +960,7 @@ static bool connect_sco(void)
>  
>  	g_io_channel_unref(io);
>  
> -	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
> +	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
>  
>  	return true;
>  }
> @@ -991,7 +991,7 @@ static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
>  		 * we try connect to negotiated codec. If it fails, and it isn't
>  		 * CVSD codec, try connect CVSD
>  		 */
> -		if (!connect_sco() && dev->negotiated_codec != CODEC_ID_CVSD)
> +		if (!connect_sco(dev) && dev->negotiated_codec != CODEC_ID_CVSD)
>  			select_codec(dev, CODEC_ID_CVSD);
>  
>  		return;
> @@ -1032,7 +1032,7 @@ static void at_cmd_bcs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
>  		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
>  
>  		/* Connect sco with negotiated parameters */
> -		connect_sco();
> +		connect_sco(dev);
>  		return;
>  	case HFP_GW_CMD_TYPE_READ:
>  	case HFP_GW_CMD_TYPE_TEST:
> @@ -1681,38 +1681,38 @@ failed:
>  					HAL_OP_HANDSFREE_DISCONNECT, status);
>  }
>  
> -static bool disconnect_sco(void)
> +static bool disconnect_sco(struct hf_device *dev)
>  {
> -	if (!device.sco)
> +	if (!dev->sco)
>  		return false;
>  
> -	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING);
> +	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING);
>  
> -	if (device.sco_watch) {
> -		g_source_remove(device.sco_watch);
> -		device.sco_watch = 0;
> +	if (dev->sco_watch) {
> +		g_source_remove(dev->sco_watch);
> +		dev->sco_watch = 0;
>  	}
>  
> -	g_io_channel_shutdown(device.sco, TRUE, NULL);
> -	g_io_channel_unref(device.sco);
> -	device.sco = NULL;
> +	g_io_channel_shutdown(dev->sco, TRUE, NULL);
> +	g_io_channel_unref(dev->sco);
> +	dev->sco = NULL;
>  
> -	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
> +	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
>  	return true;
>  }
>  
> -static bool connect_audio(void)
> +static bool connect_audio(struct hf_device *dev)
>  {
> -	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED)
> +	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED)
>  		return false;
>  
>  	/* we haven't negotiated codec, start selection */
> -	if ((device.features & HFP_HF_FEAT_CODEC) && !device.negotiated_codec) {
> -		select_codec(&device, 0);
> +	if ((dev->features & HFP_HF_FEAT_CODEC) && !dev->negotiated_codec) {
> +		select_codec(dev, 0);
>  		return true;
>  	}
>  
> -	return connect_sco();
> +	return connect_sco(dev);
>  }
>  
>  static void handle_connect_audio(const void *buf, uint16_t len)
> @@ -1731,7 +1731,7 @@ static void handle_connect_audio(const void *buf, uint16_t len)
>  		goto done;
>  	}
>  
> -	status = connect_audio() ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> +	status = connect_audio(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
>  
>  done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> @@ -1754,7 +1754,7 @@ static void handle_disconnect_audio(const void *buf, uint16_t len)
>  		goto done;
>  	}
>  
> -	status = disconnect_sco() ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> +	status = disconnect_sco(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
>  
>  done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> @@ -2042,7 +2042,7 @@ static void phone_state_dialing(int num_active, int num_held)
>  		update_indicator(IND_CALLHELD, 2);
>  
>  	if (device.num_active == 0 && device.num_held == 0)
> -		connect_audio();
> +		connect_audio(&device);
>  }
>  
>  static void phone_state_alerting(int num_active, int num_held)
> @@ -2136,7 +2136,7 @@ static void phone_state_idle(int num_active, int num_held)
>  			update_indicator(IND_CALL, 1);
>  
>  			if (device.num_active == 0 && device.num_held == 0)
> -				connect_audio();
> +				connect_audio(&device);
>  		}
>  
>  		if (num_held > device.num_held)
> @@ -2180,9 +2180,9 @@ static void phone_state_idle(int num_active, int num_held)
>  			 * was no call setup change this means that there were
>  			 * calls present when headset was connected.
>  			 */
> -			connect_audio();
> +			connect_audio(&device);
>  		} else if (num_active == 0 && num_held == 0) {
> -			disconnect_sco();
> +			disconnect_sco(&device);
>  		}
>  
>  		update_indicator(IND_CALLHELD,
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 12/13] android/handsfree: Add helper for getting device
  2014-10-08  7:12 ` [PATCH 12/13] android/handsfree: Add helper for getting device Szymon Janc
@ 2014-10-08  8:23   ` Andrei Emeltchenko
  2014-10-08  9:44     ` Szymon Janc
  0 siblings, 1 reply; 18+ messages in thread
From: Andrei Emeltchenko @ 2014-10-08  8:23 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Wed, Oct 08, 2014 at 09:12:22AM +0200, Szymon Janc wrote:
> For now this is just dummy to minime use of global static device.
> ---
>  android/handsfree.c | 321 ++++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 238 insertions(+), 83 deletions(-)
> 
> diff --git a/android/handsfree.c b/android/handsfree.c
> index 60aa504..58eade4 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -172,6 +172,32 @@ static GIOChannel *hsp_server = NULL;
>  
>  static GIOChannel *sco_server = NULL;
>  
> +static struct hf_device *find_default_device(void)
> +{
> +	/* TODO should be replaced by find_device() eventually */
> +
> +	return &device;
> +}
> +
> +static struct hf_device *find_device(const bdaddr_t *bdaddr)
> +{
> +	if (bacmp(&device.bdaddr, bdaddr))
> +		return NULL;
> +
> +	return &device;
> +}
> +
> +static struct hf_device *get_device(const bdaddr_t *bdaddr)
> +{
> +	struct hf_device *dev;
> +
> +	dev = find_device(bdaddr);
> +	if (dev)
> +		return dev;
> +
> +	return &device;
> +}

I think it is better to create list with one element and write code which
might be useful later. Name find_device as cmp_device and use some list
function.

Best regards 
Andrei Emeltchenko 

> +
>  static void set_state(struct hf_device *dev, uint8_t state)
>  {
>  	struct hal_ev_handsfree_conn_state ev;
> @@ -1403,6 +1429,7 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
>  	char address[18];
>  	bdaddr_t bdaddr;
>  	GError *err = NULL;
> +	struct hf_device *dev;
>  
>  	bt_io_get(chan, &err,
>  			BT_IO_OPT_DEST, address,
> @@ -1416,20 +1443,26 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
>  
>  	DBG("incoming connect from %s", address);
>  
> -	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> +	dev = get_device(&bdaddr);
> +	if (!dev) {
> +		error("handsfree: Failed to get device object for %s", address);
> +		goto drop;
> +	}
> +
> +	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
>  		info("handsfree: refusing connection from %s", address);
>  		goto drop;
>  	}
>  
> -	device_init(&device, &bdaddr);
> +	device_init(dev, &bdaddr);
>  
> -	if (!bt_io_accept(chan, connect_cb, &device, NULL, NULL)) {
> +	if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) {
>  		error("handsfree: failed to accept connection");
> -		device_cleanup(&device);
> +		device_cleanup(dev);
>  		goto drop;
>  	}
>  
> -	device.hsp = GPOINTER_TO_INT(data);
> +	dev->hsp = GPOINTER_TO_INT(data);
>  	return;
>  
>  drop:
> @@ -1612,6 +1645,7 @@ static int sdp_search_hfp(struct hf_device *dev)
>  static void handle_connect(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_connect *cmd = buf;
> +	struct hf_device *dev;
>  	char addr[18];
>  	uint8_t status;
>  	bdaddr_t bdaddr;
> @@ -1619,23 +1653,34 @@ static void handle_connect(const void *buf, uint16_t len)
>  
>  	DBG("");
>  
> -	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> +	dev = find_default_device();
> +	if (dev) {
>  		status = HAL_STATUS_FAILED;
>  		goto failed;
>  	}
>  
>  	android2bdaddr(&cmd->bdaddr, &bdaddr);
> +	dev = get_device(&bdaddr);
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto failed;
> +	}
> +
> +	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> +		status = HAL_STATUS_FAILED;
> +		goto failed;
> +	}
>  
>  	ba2str(&bdaddr, addr);
>  	DBG("connecting to %s", addr);
>  
> -	device_init(&device, &bdaddr);
> +	device_init(dev, &bdaddr);
>  
>  	/* prefer HFP over HSP */
> -	ret = hfp_server ? sdp_search_hfp(&device) : sdp_search_hsp(&device);
> +	ret = hfp_server ? sdp_search_hfp(dev) : sdp_search_hsp(dev);
>  	if (ret < 0) {
>  		error("handsfree: SDP search failed");
> -		device_cleanup(&device);
> +		device_cleanup(dev);
>  		status = HAL_STATUS_FAILED;
>  		goto failed;
>  	}
> @@ -1650,6 +1695,7 @@ failed:
>  static void handle_disconnect(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_disconnect *cmd = buf;
> +	struct hf_device *dev;
>  	bdaddr_t bdaddr;
>  	uint8_t status;
>  
> @@ -1657,23 +1703,28 @@ static void handle_disconnect(const void *buf, uint16_t len)
>  
>  	android2bdaddr(cmd->bdaddr, &bdaddr);
>  
> -	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED ||
> -			bacmp(&device.bdaddr, &bdaddr)) {
> +	dev = find_device(&bdaddr);
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto failed;
> +	}
> +
> +	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
>  		status = HAL_STATUS_FAILED;
>  		goto failed;
>  
>  	}
>  
> -	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
> +	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
>  		status = HAL_STATUS_SUCCESS;
>  		goto failed;
>  	}
>  
> -	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
> -		device_cleanup(&device);
> +	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
> +		device_cleanup(dev);
>  	} else {
> -		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
> -		hfp_gw_disconnect(device.gw);
> +		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
> +		hfp_gw_disconnect(dev->gw);
>  	}
>  
>  	status = HAL_STATUS_SUCCESS;
> @@ -1720,6 +1771,7 @@ static bool connect_audio(struct hf_device *dev)
>  static void handle_connect_audio(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_connect_audio *cmd = buf;
> +	struct hf_device *dev;
>  	bdaddr_t bdaddr;
>  	uint8_t status;
>  
> @@ -1727,13 +1779,18 @@ static void handle_connect_audio(const void *buf, uint16_t len)
>  
>  	android2bdaddr(cmd->bdaddr, &bdaddr);
>  
> -	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED ||
> -			bacmp(&device.bdaddr, &bdaddr)) {
> +	dev = find_device(&bdaddr);
> +	if (!dev) {
>  		status = HAL_STATUS_FAILED;
>  		goto done;
>  	}
>  
> -	status = connect_audio(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> +	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
> +	status = connect_audio(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
>  
>  done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> @@ -1743,6 +1800,7 @@ done:
>  static void handle_disconnect_audio(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_disconnect_audio *cmd = buf;
> +	struct hf_device *dev;
>  	bdaddr_t bdaddr;
>  	uint8_t status;
>  
> @@ -1750,13 +1808,18 @@ static void handle_disconnect_audio(const void *buf, uint16_t len)
>  
>  	android2bdaddr(cmd->bdaddr, &bdaddr);
>  
> -	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED ||
> -			bacmp(&device.bdaddr, &bdaddr)) {
> +	dev = find_device(&bdaddr);
> +	if (!dev) {
>  		status = HAL_STATUS_FAILED;
>  		goto done;
>  	}
>  
> -	status = disconnect_sco(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> +	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
> +	status = disconnect_sco(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
>  
>  done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> @@ -1765,34 +1828,50 @@ done:
>  
>  static void handle_start_vr(const void *buf, uint16_t len)
>  {
> +	struct hf_device *dev;
>  	uint8_t status;
>  
>  	DBG("");
>  
> -	if (device.features & HFP_HF_FEAT_VR) {
> -		hfp_gw_send_info(device.gw, "+BVRA: 1");
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
> +	if (dev->features & HFP_HF_FEAT_VR) {
> +		hfp_gw_send_info(dev->gw, "+BVRA: 1");
>  		status = HAL_STATUS_SUCCESS;
>  	} else {
>  		status = HAL_STATUS_FAILED;
>  	}
>  
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
>  					HAL_OP_HANDSFREE_START_VR, status);
>  }
>  
>  static void handle_stop_vr(const void *buf, uint16_t len)
>  {
> +	struct hf_device *dev;
>  	uint8_t status;
>  
>  	DBG("");
>  
> -	if (device.features & HFP_HF_FEAT_VR) {
> -		hfp_gw_send_info(device.gw, "+BVRA: 0");
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
> +	if (dev->features & HFP_HF_FEAT_VR) {
> +		hfp_gw_send_info(dev->gw, "+BVRA: 0");
>  		status = HAL_STATUS_SUCCESS;
>  	} else {
>  		status = HAL_STATUS_FAILED;
>  	}
>  
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
>  				HAL_OP_HANDSFREE_STOP_VR, status);
>  }
> @@ -1800,20 +1879,27 @@ static void handle_stop_vr(const void *buf, uint16_t len)
>  static void handle_volume_control(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_volume_control *cmd = buf;
> +	struct hf_device *dev;
>  	uint8_t status, volume;
>  
>  	DBG("type=%u volume=%u", cmd->type, cmd->volume);
>  
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
>  	volume = cmd->volume > 15 ? 15 : cmd->volume;
>  
>  	switch (cmd->type) {
>  	case HAL_HANDSFREE_VOLUME_TYPE_MIC:
> -		hfp_gw_send_info(device.gw, "+VGM: %u", volume);
> +		hfp_gw_send_info(dev->gw, "+VGM: %u", volume);
>  
>  		status = HAL_STATUS_SUCCESS;
>  		break;
>  	case HAL_HANDSFREE_VOLUME_TYPE_SPEAKER:
> -		hfp_gw_send_info(device.gw, "+VGS: %u", volume);
> +		hfp_gw_send_info(dev->gw, "+VGS: %u", volume);
>  
>  		status = HAL_STATUS_SUCCESS;
>  		break;
> @@ -1822,6 +1908,7 @@ static void handle_volume_control(const void *buf, uint16_t len)
>  		break;
>  	}
>  
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
>  				HAL_OP_HANDSFREE_VOLUME_CONTROL, status);
>  }
> @@ -1848,22 +1935,34 @@ static void update_indicator(struct hf_device *dev, int ind, uint8_t val)
>  static void handle_device_status_notif(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_device_status_notif *cmd = buf;
> +	struct hf_device *dev;
> +	uint8_t status;
>  
>  	DBG("");
>  
> -	update_indicator(&device, IND_SERVICE, cmd->state);
> -	update_indicator(&device, IND_ROAM, cmd->type);
> -	update_indicator(&device, IND_SIGNAL, cmd->signal);
> -	update_indicator(&device, IND_BATTCHG, cmd->battery);
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
> +	update_indicator(dev, IND_SERVICE, cmd->state);
> +	update_indicator(dev, IND_ROAM, cmd->type);
> +	update_indicator(dev, IND_SIGNAL, cmd->signal);
> +	update_indicator(dev, IND_BATTCHG, cmd->battery);
>  
> +	status = HAL_STATUS_SUCCESS;
> +
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> -					HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
> -					HAL_STATUS_SUCCESS);
> +				HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF, status);
>  }
>  
>  static void handle_cops(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_cops_response *cmd = buf;
> +	struct hf_device *dev;
> +	uint8_t status;
>  
>  	if (len != sizeof(*cmd) + cmd->len ||
>  			(cmd->len != 0 && cmd->buf[cmd->len - 1] != '\0')) {
> @@ -1874,13 +1973,22 @@ static void handle_cops(const void *buf, uint16_t len)
>  
>  	DBG("");
>  
> -	hfp_gw_send_info(device.gw, "+COPS: 0,0,\"%.16s\"",
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
> +	hfp_gw_send_info(dev->gw, "+COPS: 0,0,\"%.16s\"",
>  					cmd->len ? (char *) cmd->buf : "");
>  
> -	hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> +	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
> +
> +	status = HAL_STATUS_SUCCESS;
>  
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> -			HAL_OP_HANDSFREE_COPS_RESPONSE, HAL_STATUS_SUCCESS);
> +				HAL_OP_HANDSFREE_COPS_RESPONSE, status);
>  }
>  
>  static unsigned int get_callsetup(uint8_t state)
> @@ -1900,38 +2008,51 @@ static unsigned int get_callsetup(uint8_t state)
>  static void handle_cind(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_cind_response *cmd = buf;
> +	struct hf_device *dev;
> +	uint8_t status;
>  
>  	DBG("");
>  
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
>  	/* HAL doesn't provide indicators values so need to convert here */
> -	device.inds[IND_SERVICE].val = cmd->svc;
> -	device.inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held);
> -	device.inds[IND_CALLSETUP].val = get_callsetup(cmd->state);
> -	device.inds[IND_CALLHELD].val = cmd->num_held ?
> +	dev->inds[IND_SERVICE].val = cmd->svc;
> +	dev->inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held);
> +	dev->inds[IND_CALLSETUP].val = get_callsetup(cmd->state);
> +	dev->inds[IND_CALLHELD].val = cmd->num_held ?
>  						(cmd->num_active ? 1 : 2) : 0;
> -	device.inds[IND_SIGNAL].val = cmd->signal;
> -	device.inds[IND_ROAM].val = cmd->roam;
> -	device.inds[IND_BATTCHG].val = cmd->batt_chg;
> +	dev->inds[IND_SIGNAL].val = cmd->signal;
> +	dev->inds[IND_ROAM].val = cmd->roam;
> +	dev->inds[IND_BATTCHG].val = cmd->batt_chg;
>  
>  	/* Order must match indicators_defaults table */
> -	hfp_gw_send_info(device.gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
> -						device.inds[IND_SERVICE].val,
> -						device.inds[IND_CALL].val,
> -						device.inds[IND_CALLSETUP].val,
> -						device.inds[IND_CALLHELD].val,
> -						device.inds[IND_SIGNAL].val,
> -						device.inds[IND_ROAM].val,
> -						device.inds[IND_BATTCHG].val);
> +	hfp_gw_send_info(dev->gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
> +						dev->inds[IND_SERVICE].val,
> +						dev->inds[IND_CALL].val,
> +						dev->inds[IND_CALLSETUP].val,
> +						dev->inds[IND_CALLHELD].val,
> +						dev->inds[IND_SIGNAL].val,
> +						dev->inds[IND_ROAM].val,
> +						dev->inds[IND_BATTCHG].val);
>  
> -	hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> +	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
>  
> +	status = HAL_STATUS_SUCCESS;
> +
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> -			HAL_OP_HANDSFREE_CIND_RESPONSE, HAL_STATUS_SUCCESS);
> +				HAL_OP_HANDSFREE_CIND_RESPONSE, status);
>  }
>  
>  static void handle_formatted_at_resp(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_formatted_at_response *cmd = buf;
> +	struct hf_device *dev;
> +	uint8_t status;
>  
>  	DBG("");
>  
> @@ -1942,33 +2063,53 @@ static void handle_formatted_at_resp(const void *buf, uint16_t len)
>  		return;
>  	}
>  
> -	hfp_gw_send_info(device.gw, "%s", cmd->len ? (char *) cmd->buf : "");
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
>  
> +	hfp_gw_send_info(dev->gw, "%s", cmd->len ? (char *) cmd->buf : "");
> +
> +	status = HAL_STATUS_SUCCESS;
> +
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> -					HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
> -					HAL_STATUS_SUCCESS);
> +			HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE, status);
>  }
>  
>  static void handle_at_resp(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_at_response *cmd = buf;
> +	struct hf_device *dev;
> +	uint8_t status;
>  
>  	DBG("");
>  
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
>  	if (cmd->response == HAL_HANDSFREE_AT_RESPONSE_OK)
> -		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> -	else if (device.cmee_enabled)
> -		hfp_gw_send_error(device.gw, cmd->error);
> +		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
> +	else if (dev->cmee_enabled)
> +		hfp_gw_send_error(dev->gw, cmd->error);
>  	else
> -		hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
> +		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
> +
> +	status = HAL_STATUS_SUCCESS;
>  
> +done:
>  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> -			HAL_OP_HANDSFREE_AT_RESPONSE, HAL_STATUS_SUCCESS);
> +					HAL_OP_HANDSFREE_AT_RESPONSE, status);
>  }
>  
>  static void handle_clcc_resp(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_clcc_response *cmd = buf;
> +	struct hf_device *dev;
>  	uint8_t status;
>  	char *number;
>  
> @@ -1981,8 +2122,14 @@ static void handle_clcc_resp(const void *buf, uint16_t len)
>  
>  	DBG("");
>  
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto done;
> +	}
> +
>  	if (!cmd->index) {
> -		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> +		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
>  
>  		status = HAL_STATUS_SUCCESS;
>  		goto done;
> @@ -1999,13 +2146,13 @@ static void handle_clcc_resp(const void *buf, uint16_t len)
>  	case HAL_HANDSFREE_CALL_STATE_ALERTING:
>  		if (cmd->type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL &&
>  							number[0] != '+')
> -			hfp_gw_send_info(device.gw,
> +			hfp_gw_send_info(dev->gw,
>  					"+CLCC: %u,%u,%u,%u,%u,\"+%s\",%u",
>  					cmd->index, cmd->dir, cmd->state,
>  					cmd->mode, cmd->mpty, number,
>  					cmd->type);
>  		else
> -			hfp_gw_send_info(device.gw,
> +			hfp_gw_send_info(dev->gw,
>  					"+CLCC: %u,%u,%u,%u,%u,\"%s\",%u",
>  					cmd->index, cmd->dir, cmd->state,
>  					cmd->mode, cmd->mpty, number,
> @@ -2213,6 +2360,7 @@ static void phone_state_idle(struct hf_device *dev, int num_active,
>  static void handle_phone_state_change(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_handsfree_phone_state_change *cmd = buf;
> +	struct hf_device *dev;
>  	uint8_t status;
>  
>  	if (len != sizeof(*cmd) + cmd->number_len || (cmd->number_len != 0 &&
> @@ -2225,32 +2373,38 @@ static void handle_phone_state_change(const void *buf, uint16_t len)
>  	DBG("active=%u hold=%u state=%u", cmd->num_active, cmd->num_held,
>  								cmd->state);
>  
> +	dev = find_default_device();
> +	if (!dev) {
> +		status = HAL_STATUS_FAILED;
> +		goto failed;
> +	}
> +
>  	switch (cmd->state) {
>  	case HAL_HANDSFREE_CALL_STATE_DIALING:
> -		phone_state_dialing(&device, cmd->num_active, cmd->num_held);
> +		phone_state_dialing(dev, cmd->num_active, cmd->num_held);
>  		break;
>  	case HAL_HANDSFREE_CALL_STATE_ALERTING:
> -		phone_state_alerting(&device, cmd->num_active, cmd->num_held);
> +		phone_state_alerting(dev, cmd->num_active, cmd->num_held);
>  		break;
>  	case HAL_HANDSFREE_CALL_STATE_INCOMING:
> -		phone_state_incoming(&device, cmd->num_active, cmd->num_held,
> +		phone_state_incoming(dev, cmd->num_active, cmd->num_held,
>  						cmd->type, cmd->number,
>  						cmd->number_len);
>  		break;
>  	case HAL_HANDSFREE_CALL_STATE_IDLE:
> -		phone_state_idle(&device, cmd->num_active, cmd->num_held);
> +		phone_state_idle(dev, cmd->num_active, cmd->num_held);
>  		break;
>  	default:
>  		DBG("unhandled new state %u (current state %u)", cmd->state,
> -							device.setup_state);
> +							dev->setup_state);
>  
>  		status = HAL_STATUS_FAILED;
>  		goto failed;
>  	}
>  
> -	device.num_active = cmd->num_active;
> -	device.num_held = cmd->num_held;
> -	device.setup_state = cmd->state;
> +	dev->num_active = cmd->num_active;
> +	dev->num_held = cmd->num_held;
> +	dev->setup_state = cmd->state;
>  
>  	status = HAL_STATUS_SUCCESS;
>  
> @@ -2374,9 +2528,7 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
>  	char address[18];
>  	bdaddr_t bdaddr;
>  	GError *err = NULL;
> -
> -	if (device.sco)
> -		goto drop;
> +	struct hf_device *dev;
>  
>  	bt_io_get(chan, &err,
>  			BT_IO_OPT_DEST, address,
> @@ -2390,18 +2542,19 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
>  
>  	DBG("incoming SCO connection from %s", address);
>  
> -	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED ||
> -			bacmp(&device.bdaddr, &bdaddr)) {
> +	dev = find_device(&bdaddr);
> +	if (!dev || dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED ||
> +								dev->sco) {
>  		error("handsfree: audio connection from %s rejected", address);
>  		goto drop;
>  	}
>  
> -	if (!bt_io_accept(chan, connect_sco_cb, &device, NULL, NULL)) {
> +	if (!bt_io_accept(chan, connect_sco_cb, dev, NULL, NULL)) {
>  		error("handsfree: failed to accept audio connection");
>  		goto drop;
>  	}
>  
> -	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
> +	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
>  	return;
>  
>  drop:
> @@ -2633,21 +2786,23 @@ static void bt_sco_get_fd(const void *buf, uint16_t len)
>  	int fd;
>  	GError *err;
>  	struct sco_rsp_get_fd rsp;
> +	struct hf_device *dev;
>  
>  	DBG("");
>  
> -	if (!device.sco)
> +	dev = find_default_device();
> +	if (!dev || !dev->sco)
>  		goto failed;
>  
>  	err = NULL;
> -	if (!bt_io_get(device.sco, &err, BT_IO_OPT_MTU, &rsp.mtu,
> +	if (!bt_io_get(dev->sco, &err, BT_IO_OPT_MTU, &rsp.mtu,
>  							BT_IO_OPT_INVALID)) {
>  		error("Unable to get MTU: %s\n", err->message);
>  		g_clear_error(&err);
>  		goto failed;
>  	}
>  
> -	fd = g_io_channel_unix_get_fd(device.sco);
> +	fd = g_io_channel_unix_get_fd(dev->sco);
>  
>  	DBG("fd %d mtu %u", fd, rsp.mtu);
>  
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 13/13] android/handsfree: Make remote device non-static
  2014-10-08  7:12 ` [PATCH 13/13] android/handsfree: Make remote device non-static Szymon Janc
@ 2014-10-08  8:30   ` Andrei Emeltchenko
  0 siblings, 0 replies; 18+ messages in thread
From: Andrei Emeltchenko @ 2014-10-08  8:30 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Wed, Oct 08, 2014 at 09:12:23AM +0200, Szymon Janc wrote:
> Remote device object is now created on-demand instead of being static.
> ---
>  android/handsfree.c | 144 +++++++++++++++++++++++++++++++---------------------
>  1 file changed, 86 insertions(+), 58 deletions(-)
> 
> diff --git a/android/handsfree.c b/android/handsfree.c
> index 58eade4..2e617f6 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -37,6 +37,8 @@
>  #include "src/sdp-client.h"
>  #include "src/uuid-helper.h"
>  #include "src/shared/hfp.h"
> +#include "src/shared/queue.h"
> +#include "src/shared/util.h"
>  #include "btio/btio.h"
>  #include "hal-msg.h"
>  #include "ipc-common.h"
> @@ -155,7 +157,7 @@ static const struct hfp_codec codecs_defaults[] = {
>  	{ CODEC_ID_MSBC, false, false},
>  };
>  
> -static struct hf_device device;
> +static struct queue *devices = NULL;
>  
>  static uint32_t hfp_ag_features = 0;
>  
> @@ -172,32 +174,6 @@ static GIOChannel *hsp_server = NULL;
>  
>  static GIOChannel *sco_server = NULL;
>  
> -static struct hf_device *find_default_device(void)
> -{
> -	/* TODO should be replaced by find_device() eventually */
> -
> -	return &device;
> -}
> -
> -static struct hf_device *find_device(const bdaddr_t *bdaddr)
> -{
> -	if (bacmp(&device.bdaddr, bdaddr))
> -		return NULL;
> -
> -	return &device;
> -}
> -
> -static struct hf_device *get_device(const bdaddr_t *bdaddr)
> -{
> -	struct hf_device *dev;
> -
> -	dev = find_device(bdaddr);
> -	if (dev)
> -		return dev;
> -
> -	return &device;
> -}
> -
>  static void set_state(struct hf_device *dev, uint8_t state)
>  {
>  	struct hal_ev_handsfree_conn_state ev;
> @@ -246,28 +222,38 @@ static void init_codecs(struct hf_device *dev)
>  		dev->codecs[MSBC_OFFSET].local_supported = true;
>  }
>  
> -static void device_init(struct hf_device *dev, const bdaddr_t *bdaddr)
> +static struct hf_device *device_create(const bdaddr_t *bdaddr)
>  {
> -	bacpy(&dev->bdaddr, bdaddr);
> +	struct hf_device *dev;
>  
> +	dev = new0(struct hf_device, 1);
> +	if (!dev)
> +		return NULL;
> +
> +	bacpy(&dev->bdaddr, bdaddr);
>  	dev->setup_state = HAL_HANDSFREE_CALL_STATE_IDLE;
> +	dev->state = HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED;
> +	dev->audio_state = HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED;
>  
>  	memcpy(dev->inds, inds_defaults, sizeof(dev->inds));
>  
>  	init_codecs(dev);
>  
> -	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
> +	if (!queue_push_head(devices, dev)) {
> +		free(dev);
> +		return NULL;
> +	}
> +
> +	return dev;
>  }
>  
> -static void device_cleanup(struct hf_device *dev)
> +static void device_destroy(struct hf_device *dev)
>  {
>  	if (dev->gw) {
>  		hfp_gw_unref(dev->gw);
>  		dev->gw = NULL;
>  	}
>  
> -	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);
> -
>  	if (dev->sco_watch) {
>  		g_source_remove(dev->sco_watch);
>  		dev->sco_watch = 0;
> @@ -290,8 +276,45 @@ static void device_cleanup(struct hf_device *dev)
>  	}
>  
>  	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED);
> +	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);
> +
> +	queue_remove(devices, dev);
> +	free(dev);

So now you definitely do not need zero assignments.

> +}
> +
> +static struct hf_device *find_default_device(void)
> +{
> +	/* TODO should be replaced by find_device() eventually */
> +
> +	return queue_peek_head(devices);
> +}
>  
> -	memset(dev, 0, sizeof(*dev));
> +static bool match_by_bdaddr(const void *data, const void *match_data)
> +{
> +	const struct hf_device *dev = data;
> +	const bdaddr_t *addr = match_data;
> +
> +	return !bacmp(&dev->bdaddr, addr);
> +}
> +
> +static struct hf_device *find_device(const bdaddr_t *bdaddr)
> +{
> +	return queue_find(devices, match_by_bdaddr, bdaddr);
> +}
> +
> +static struct hf_device *get_device(const bdaddr_t *bdaddr)
> +{
> +	struct hf_device *dev;
> +
> +	dev = find_device(bdaddr);
> +	if (dev)
> +		return dev;
> +
> +	/* TODO For now allow only 1 remote device */
> +	if (!queue_isempty(devices))
> +		return NULL;
> +
> +	return device_create(bdaddr);
>  }

These get_device() functions needs to be merged with the previous patch.

Best regards 
Andrei Emeltchenko 

>  
>  static void disconnect_watch(void *user_data)
> @@ -300,7 +323,7 @@ static void disconnect_watch(void *user_data)
>  
>  	DBG("");
>  
> -	device_cleanup(dev);
> +	device_destroy(dev);
>  }
>  
>  static void at_cmd_unknown(const char *command, void *user_data)
> @@ -1421,7 +1444,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
>  
>  failed:
>  	g_io_channel_shutdown(chan, TRUE, NULL);
> -	device_cleanup(dev);
> +	device_destroy(dev);
>  }
>  
>  static void confirm_cb(GIOChannel *chan, gpointer data)
> @@ -1454,15 +1477,16 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
>  		goto drop;
>  	}
>  
> -	device_init(dev, &bdaddr);
> -
>  	if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) {
>  		error("handsfree: failed to accept connection");
> -		device_cleanup(dev);
> +		device_destroy(dev);
>  		goto drop;
>  	}
>  
>  	dev->hsp = GPOINTER_TO_INT(data);
> +
> +	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
> +
>  	return;
>  
>  drop:
> @@ -1541,7 +1565,7 @@ static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
>  	return;
>  
>  fail:
> -	device_cleanup(dev);
> +	device_destroy(dev);
>  }
>  
>  static int sdp_search_hsp(struct hf_device *dev)
> @@ -1629,7 +1653,7 @@ static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
>  	return;
>  
>  fail:
> -	device_cleanup(dev);
> +	device_destroy(dev);
>  }
>  
>  static int sdp_search_hfp(struct hf_device *dev)
> @@ -1653,13 +1677,8 @@ static void handle_connect(const void *buf, uint16_t len)
>  
>  	DBG("");
>  
> -	dev = find_default_device();
> -	if (dev) {
> -		status = HAL_STATUS_FAILED;
> -		goto failed;
> -	}
> -
>  	android2bdaddr(&cmd->bdaddr, &bdaddr);
> +
>  	dev = get_device(&bdaddr);
>  	if (!dev) {
>  		status = HAL_STATUS_FAILED;
> @@ -1674,17 +1693,17 @@ static void handle_connect(const void *buf, uint16_t len)
>  	ba2str(&bdaddr, addr);
>  	DBG("connecting to %s", addr);
>  
> -	device_init(dev, &bdaddr);
> -
>  	/* prefer HFP over HSP */
>  	ret = hfp_server ? sdp_search_hfp(dev) : sdp_search_hsp(dev);
>  	if (ret < 0) {
>  		error("handsfree: SDP search failed");
> -		device_cleanup(dev);
> +		device_destroy(dev);
>  		status = HAL_STATUS_FAILED;
>  		goto failed;
>  	}
>  
> +	set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
> +
>  	status = HAL_STATUS_SUCCESS;
>  
>  failed:
> @@ -1712,7 +1731,6 @@ static void handle_disconnect(const void *buf, uint16_t len)
>  	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
>  		status = HAL_STATUS_FAILED;
>  		goto failed;
> -
>  	}
>  
>  	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
> @@ -1721,7 +1739,7 @@ static void handle_disconnect(const void *buf, uint16_t len)
>  	}
>  
>  	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
> -		device_cleanup(dev);
> +		device_destroy(dev);
>  	} else {
>  		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
>  		hfp_gw_disconnect(dev->gw);
> @@ -2849,13 +2867,15 @@ bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
>  
>  	bacpy(&adapter_addr, addr);
>  
> -	if (!enable_hsp_ag())
> +	devices = queue_new();
> +	if (!devices)
>  		return false;
>  
> -	if (!enable_sco_server()) {
> -		cleanup_hsp_ag();
> -		return false;
> -	}
> +	if (!enable_hsp_ag())
> +		goto failed_queue;
> +
> +	if (!enable_sco_server())
> +		goto failed_hsp;
>  
>  	if (mode == HAL_MODE_HANDSFREE_HSP_ONLY)
>  		goto done;
> @@ -2868,9 +2888,14 @@ bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
>  	if (enable_hfp_ag())
>  		goto done;
>  
> -	cleanup_hsp_ag();
>  	disable_sco_server();
>  	hfp_ag_features = 0;
> +failed_hsp:
> +	cleanup_hsp_ag();
> +failed_queue:
> +	queue_destroy(devices, NULL);
> +	devices = NULL;
> +
>  	return false;
>  
>  done:
> @@ -2896,4 +2921,7 @@ void bt_handsfree_unregister(void)
>  	disable_sco_server();
>  
>  	hfp_ag_features = 0;
> +
> +	queue_destroy(devices, (queue_destroy_func_t) device_destroy);
> +	devices = NULL;
>  }
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 12/13] android/handsfree: Add helper for getting device
  2014-10-08  8:23   ` Andrei Emeltchenko
@ 2014-10-08  9:44     ` Szymon Janc
  0 siblings, 0 replies; 18+ messages in thread
From: Szymon Janc @ 2014-10-08  9:44 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth

Hi Andrei,

On Wednesday 08 of October 2014 11:23:42 Andrei Emeltchenko wrote:
> Hi Szymon,
> 
> On Wed, Oct 08, 2014 at 09:12:22AM +0200, Szymon Janc wrote:
> > For now this is just dummy to minime use of global static device.
> > ---
> >  android/handsfree.c | 321 ++++++++++++++++++++++++++++++++++++++--------------
> >  1 file changed, 238 insertions(+), 83 deletions(-)
> > 
> > diff --git a/android/handsfree.c b/android/handsfree.c
> > index 60aa504..58eade4 100644
> > --- a/android/handsfree.c
> > +++ b/android/handsfree.c
> > @@ -172,6 +172,32 @@ static GIOChannel *hsp_server = NULL;
> >  
> >  static GIOChannel *sco_server = NULL;
> >  
> > +static struct hf_device *find_default_device(void)
> > +{
> > +	/* TODO should be replaced by find_device() eventually */
> > +
> > +	return &device;
> > +}
> > +
> > +static struct hf_device *find_device(const bdaddr_t *bdaddr)
> > +{
> > +	if (bacmp(&device.bdaddr, bdaddr))
> > +		return NULL;
> > +
> > +	return &device;
> > +}
> > +
> > +static struct hf_device *get_device(const bdaddr_t *bdaddr)
> > +{
> > +	struct hf_device *dev;
> > +
> > +	dev = find_device(bdaddr);
> > +	if (dev)
> > +		return dev;
> > +
> > +	return &device;
> > +}
> 
> I think it is better to create list with one element and write code which
> might be useful later. Name find_device as cmp_device and use some list
> function.

This is done in last patch where device finally becomes non-static.
But I'll put those function in right place from beginning so that those are not
moved around in patch 13.

> 
> Best regards 
> Andrei Emeltchenko 
> 
> > +
> >  static void set_state(struct hf_device *dev, uint8_t state)
> >  {
> >  	struct hal_ev_handsfree_conn_state ev;
> > @@ -1403,6 +1429,7 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
> >  	char address[18];
> >  	bdaddr_t bdaddr;
> >  	GError *err = NULL;
> > +	struct hf_device *dev;
> >  
> >  	bt_io_get(chan, &err,
> >  			BT_IO_OPT_DEST, address,
> > @@ -1416,20 +1443,26 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
> >  
> >  	DBG("incoming connect from %s", address);
> >  
> > -	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> > +	dev = get_device(&bdaddr);
> > +	if (!dev) {
> > +		error("handsfree: Failed to get device object for %s", address);
> > +		goto drop;
> > +	}
> > +
> > +	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> >  		info("handsfree: refusing connection from %s", address);
> >  		goto drop;
> >  	}
> >  
> > -	device_init(&device, &bdaddr);
> > +	device_init(dev, &bdaddr);
> >  
> > -	if (!bt_io_accept(chan, connect_cb, &device, NULL, NULL)) {
> > +	if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) {
> >  		error("handsfree: failed to accept connection");
> > -		device_cleanup(&device);
> > +		device_cleanup(dev);
> >  		goto drop;
> >  	}
> >  
> > -	device.hsp = GPOINTER_TO_INT(data);
> > +	dev->hsp = GPOINTER_TO_INT(data);
> >  	return;
> >  
> >  drop:
> > @@ -1612,6 +1645,7 @@ static int sdp_search_hfp(struct hf_device *dev)
> >  static void handle_connect(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_connect *cmd = buf;
> > +	struct hf_device *dev;
> >  	char addr[18];
> >  	uint8_t status;
> >  	bdaddr_t bdaddr;
> > @@ -1619,23 +1653,34 @@ static void handle_connect(const void *buf, uint16_t len)
> >  
> >  	DBG("");
> >  
> > -	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> > +	dev = find_default_device();
> > +	if (dev) {
> >  		status = HAL_STATUS_FAILED;
> >  		goto failed;
> >  	}
> >  
> >  	android2bdaddr(&cmd->bdaddr, &bdaddr);
> > +	dev = get_device(&bdaddr);
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto failed;
> > +	}
> > +
> > +	if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto failed;
> > +	}
> >  
> >  	ba2str(&bdaddr, addr);
> >  	DBG("connecting to %s", addr);
> >  
> > -	device_init(&device, &bdaddr);
> > +	device_init(dev, &bdaddr);
> >  
> >  	/* prefer HFP over HSP */
> > -	ret = hfp_server ? sdp_search_hfp(&device) : sdp_search_hsp(&device);
> > +	ret = hfp_server ? sdp_search_hfp(dev) : sdp_search_hsp(dev);
> >  	if (ret < 0) {
> >  		error("handsfree: SDP search failed");
> > -		device_cleanup(&device);
> > +		device_cleanup(dev);
> >  		status = HAL_STATUS_FAILED;
> >  		goto failed;
> >  	}
> > @@ -1650,6 +1695,7 @@ failed:
> >  static void handle_disconnect(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_disconnect *cmd = buf;
> > +	struct hf_device *dev;
> >  	bdaddr_t bdaddr;
> >  	uint8_t status;
> >  
> > @@ -1657,23 +1703,28 @@ static void handle_disconnect(const void *buf, uint16_t len)
> >  
> >  	android2bdaddr(cmd->bdaddr, &bdaddr);
> >  
> > -	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED ||
> > -			bacmp(&device.bdaddr, &bdaddr)) {
> > +	dev = find_device(&bdaddr);
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto failed;
> > +	}
> > +
> > +	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
> >  		status = HAL_STATUS_FAILED;
> >  		goto failed;
> >  
> >  	}
> >  
> > -	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
> > +	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
> >  		status = HAL_STATUS_SUCCESS;
> >  		goto failed;
> >  	}
> >  
> > -	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
> > -		device_cleanup(&device);
> > +	if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
> > +		device_cleanup(dev);
> >  	} else {
> > -		set_state(&device, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
> > -		hfp_gw_disconnect(device.gw);
> > +		set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
> > +		hfp_gw_disconnect(dev->gw);
> >  	}
> >  
> >  	status = HAL_STATUS_SUCCESS;
> > @@ -1720,6 +1771,7 @@ static bool connect_audio(struct hf_device *dev)
> >  static void handle_connect_audio(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_connect_audio *cmd = buf;
> > +	struct hf_device *dev;
> >  	bdaddr_t bdaddr;
> >  	uint8_t status;
> >  
> > @@ -1727,13 +1779,18 @@ static void handle_connect_audio(const void *buf, uint16_t len)
> >  
> >  	android2bdaddr(cmd->bdaddr, &bdaddr);
> >  
> > -	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED ||
> > -			bacmp(&device.bdaddr, &bdaddr)) {
> > +	dev = find_device(&bdaddr);
> > +	if (!dev) {
> >  		status = HAL_STATUS_FAILED;
> >  		goto done;
> >  	}
> >  
> > -	status = connect_audio(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> > +	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> > +	status = connect_audio(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> >  
> >  done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > @@ -1743,6 +1800,7 @@ done:
> >  static void handle_disconnect_audio(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_disconnect_audio *cmd = buf;
> > +	struct hf_device *dev;
> >  	bdaddr_t bdaddr;
> >  	uint8_t status;
> >  
> > @@ -1750,13 +1808,18 @@ static void handle_disconnect_audio(const void *buf, uint16_t len)
> >  
> >  	android2bdaddr(cmd->bdaddr, &bdaddr);
> >  
> > -	if (device.audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED ||
> > -			bacmp(&device.bdaddr, &bdaddr)) {
> > +	dev = find_device(&bdaddr);
> > +	if (!dev) {
> >  		status = HAL_STATUS_FAILED;
> >  		goto done;
> >  	}
> >  
> > -	status = disconnect_sco(&device) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> > +	if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> > +	status = disconnect_sco(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
> >  
> >  done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > @@ -1765,34 +1828,50 @@ done:
> >  
> >  static void handle_start_vr(const void *buf, uint16_t len)
> >  {
> > +	struct hf_device *dev;
> >  	uint8_t status;
> >  
> >  	DBG("");
> >  
> > -	if (device.features & HFP_HF_FEAT_VR) {
> > -		hfp_gw_send_info(device.gw, "+BVRA: 1");
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> > +	if (dev->features & HFP_HF_FEAT_VR) {
> > +		hfp_gw_send_info(dev->gw, "+BVRA: 1");
> >  		status = HAL_STATUS_SUCCESS;
> >  	} else {
> >  		status = HAL_STATUS_FAILED;
> >  	}
> >  
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> >  					HAL_OP_HANDSFREE_START_VR, status);
> >  }
> >  
> >  static void handle_stop_vr(const void *buf, uint16_t len)
> >  {
> > +	struct hf_device *dev;
> >  	uint8_t status;
> >  
> >  	DBG("");
> >  
> > -	if (device.features & HFP_HF_FEAT_VR) {
> > -		hfp_gw_send_info(device.gw, "+BVRA: 0");
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> > +	if (dev->features & HFP_HF_FEAT_VR) {
> > +		hfp_gw_send_info(dev->gw, "+BVRA: 0");
> >  		status = HAL_STATUS_SUCCESS;
> >  	} else {
> >  		status = HAL_STATUS_FAILED;
> >  	}
> >  
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> >  				HAL_OP_HANDSFREE_STOP_VR, status);
> >  }
> > @@ -1800,20 +1879,27 @@ static void handle_stop_vr(const void *buf, uint16_t len)
> >  static void handle_volume_control(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_volume_control *cmd = buf;
> > +	struct hf_device *dev;
> >  	uint8_t status, volume;
> >  
> >  	DBG("type=%u volume=%u", cmd->type, cmd->volume);
> >  
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> >  	volume = cmd->volume > 15 ? 15 : cmd->volume;
> >  
> >  	switch (cmd->type) {
> >  	case HAL_HANDSFREE_VOLUME_TYPE_MIC:
> > -		hfp_gw_send_info(device.gw, "+VGM: %u", volume);
> > +		hfp_gw_send_info(dev->gw, "+VGM: %u", volume);
> >  
> >  		status = HAL_STATUS_SUCCESS;
> >  		break;
> >  	case HAL_HANDSFREE_VOLUME_TYPE_SPEAKER:
> > -		hfp_gw_send_info(device.gw, "+VGS: %u", volume);
> > +		hfp_gw_send_info(dev->gw, "+VGS: %u", volume);
> >  
> >  		status = HAL_STATUS_SUCCESS;
> >  		break;
> > @@ -1822,6 +1908,7 @@ static void handle_volume_control(const void *buf, uint16_t len)
> >  		break;
> >  	}
> >  
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> >  				HAL_OP_HANDSFREE_VOLUME_CONTROL, status);
> >  }
> > @@ -1848,22 +1935,34 @@ static void update_indicator(struct hf_device *dev, int ind, uint8_t val)
> >  static void handle_device_status_notif(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_device_status_notif *cmd = buf;
> > +	struct hf_device *dev;
> > +	uint8_t status;
> >  
> >  	DBG("");
> >  
> > -	update_indicator(&device, IND_SERVICE, cmd->state);
> > -	update_indicator(&device, IND_ROAM, cmd->type);
> > -	update_indicator(&device, IND_SIGNAL, cmd->signal);
> > -	update_indicator(&device, IND_BATTCHG, cmd->battery);
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> > +	update_indicator(dev, IND_SERVICE, cmd->state);
> > +	update_indicator(dev, IND_ROAM, cmd->type);
> > +	update_indicator(dev, IND_SIGNAL, cmd->signal);
> > +	update_indicator(dev, IND_BATTCHG, cmd->battery);
> >  
> > +	status = HAL_STATUS_SUCCESS;
> > +
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > -					HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF,
> > -					HAL_STATUS_SUCCESS);
> > +				HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF, status);
> >  }
> >  
> >  static void handle_cops(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_cops_response *cmd = buf;
> > +	struct hf_device *dev;
> > +	uint8_t status;
> >  
> >  	if (len != sizeof(*cmd) + cmd->len ||
> >  			(cmd->len != 0 && cmd->buf[cmd->len - 1] != '\0')) {
> > @@ -1874,13 +1973,22 @@ static void handle_cops(const void *buf, uint16_t len)
> >  
> >  	DBG("");
> >  
> > -	hfp_gw_send_info(device.gw, "+COPS: 0,0,\"%.16s\"",
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> > +	hfp_gw_send_info(dev->gw, "+COPS: 0,0,\"%.16s\"",
> >  					cmd->len ? (char *) cmd->buf : "");
> >  
> > -	hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> > +	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
> > +
> > +	status = HAL_STATUS_SUCCESS;
> >  
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > -			HAL_OP_HANDSFREE_COPS_RESPONSE, HAL_STATUS_SUCCESS);
> > +				HAL_OP_HANDSFREE_COPS_RESPONSE, status);
> >  }
> >  
> >  static unsigned int get_callsetup(uint8_t state)
> > @@ -1900,38 +2008,51 @@ static unsigned int get_callsetup(uint8_t state)
> >  static void handle_cind(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_cind_response *cmd = buf;
> > +	struct hf_device *dev;
> > +	uint8_t status;
> >  
> >  	DBG("");
> >  
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> >  	/* HAL doesn't provide indicators values so need to convert here */
> > -	device.inds[IND_SERVICE].val = cmd->svc;
> > -	device.inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held);
> > -	device.inds[IND_CALLSETUP].val = get_callsetup(cmd->state);
> > -	device.inds[IND_CALLHELD].val = cmd->num_held ?
> > +	dev->inds[IND_SERVICE].val = cmd->svc;
> > +	dev->inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held);
> > +	dev->inds[IND_CALLSETUP].val = get_callsetup(cmd->state);
> > +	dev->inds[IND_CALLHELD].val = cmd->num_held ?
> >  						(cmd->num_active ? 1 : 2) : 0;
> > -	device.inds[IND_SIGNAL].val = cmd->signal;
> > -	device.inds[IND_ROAM].val = cmd->roam;
> > -	device.inds[IND_BATTCHG].val = cmd->batt_chg;
> > +	dev->inds[IND_SIGNAL].val = cmd->signal;
> > +	dev->inds[IND_ROAM].val = cmd->roam;
> > +	dev->inds[IND_BATTCHG].val = cmd->batt_chg;
> >  
> >  	/* Order must match indicators_defaults table */
> > -	hfp_gw_send_info(device.gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
> > -						device.inds[IND_SERVICE].val,
> > -						device.inds[IND_CALL].val,
> > -						device.inds[IND_CALLSETUP].val,
> > -						device.inds[IND_CALLHELD].val,
> > -						device.inds[IND_SIGNAL].val,
> > -						device.inds[IND_ROAM].val,
> > -						device.inds[IND_BATTCHG].val);
> > +	hfp_gw_send_info(dev->gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
> > +						dev->inds[IND_SERVICE].val,
> > +						dev->inds[IND_CALL].val,
> > +						dev->inds[IND_CALLSETUP].val,
> > +						dev->inds[IND_CALLHELD].val,
> > +						dev->inds[IND_SIGNAL].val,
> > +						dev->inds[IND_ROAM].val,
> > +						dev->inds[IND_BATTCHG].val);
> >  
> > -	hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> > +	hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
> >  
> > +	status = HAL_STATUS_SUCCESS;
> > +
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > -			HAL_OP_HANDSFREE_CIND_RESPONSE, HAL_STATUS_SUCCESS);
> > +				HAL_OP_HANDSFREE_CIND_RESPONSE, status);
> >  }
> >  
> >  static void handle_formatted_at_resp(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_formatted_at_response *cmd = buf;
> > +	struct hf_device *dev;
> > +	uint8_t status;
> >  
> >  	DBG("");
> >  
> > @@ -1942,33 +2063,53 @@ static void handle_formatted_at_resp(const void *buf, uint16_t len)
> >  		return;
> >  	}
> >  
> > -	hfp_gw_send_info(device.gw, "%s", cmd->len ? (char *) cmd->buf : "");
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> >  
> > +	hfp_gw_send_info(dev->gw, "%s", cmd->len ? (char *) cmd->buf : "");
> > +
> > +	status = HAL_STATUS_SUCCESS;
> > +
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > -					HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE,
> > -					HAL_STATUS_SUCCESS);
> > +			HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE, status);
> >  }
> >  
> >  static void handle_at_resp(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_at_response *cmd = buf;
> > +	struct hf_device *dev;
> > +	uint8_t status;
> >  
> >  	DBG("");
> >  
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> >  	if (cmd->response == HAL_HANDSFREE_AT_RESPONSE_OK)
> > -		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> > -	else if (device.cmee_enabled)
> > -		hfp_gw_send_error(device.gw, cmd->error);
> > +		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
> > +	else if (dev->cmee_enabled)
> > +		hfp_gw_send_error(dev->gw, cmd->error);
> >  	else
> > -		hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
> > +		hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR);
> > +
> > +	status = HAL_STATUS_SUCCESS;
> >  
> > +done:
> >  	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
> > -			HAL_OP_HANDSFREE_AT_RESPONSE, HAL_STATUS_SUCCESS);
> > +					HAL_OP_HANDSFREE_AT_RESPONSE, status);
> >  }
> >  
> >  static void handle_clcc_resp(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_clcc_response *cmd = buf;
> > +	struct hf_device *dev;
> >  	uint8_t status;
> >  	char *number;
> >  
> > @@ -1981,8 +2122,14 @@ static void handle_clcc_resp(const void *buf, uint16_t len)
> >  
> >  	DBG("");
> >  
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto done;
> > +	}
> > +
> >  	if (!cmd->index) {
> > -		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
> > +		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
> >  
> >  		status = HAL_STATUS_SUCCESS;
> >  		goto done;
> > @@ -1999,13 +2146,13 @@ static void handle_clcc_resp(const void *buf, uint16_t len)
> >  	case HAL_HANDSFREE_CALL_STATE_ALERTING:
> >  		if (cmd->type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL &&
> >  							number[0] != '+')
> > -			hfp_gw_send_info(device.gw,
> > +			hfp_gw_send_info(dev->gw,
> >  					"+CLCC: %u,%u,%u,%u,%u,\"+%s\",%u",
> >  					cmd->index, cmd->dir, cmd->state,
> >  					cmd->mode, cmd->mpty, number,
> >  					cmd->type);
> >  		else
> > -			hfp_gw_send_info(device.gw,
> > +			hfp_gw_send_info(dev->gw,
> >  					"+CLCC: %u,%u,%u,%u,%u,\"%s\",%u",
> >  					cmd->index, cmd->dir, cmd->state,
> >  					cmd->mode, cmd->mpty, number,
> > @@ -2213,6 +2360,7 @@ static void phone_state_idle(struct hf_device *dev, int num_active,
> >  static void handle_phone_state_change(const void *buf, uint16_t len)
> >  {
> >  	const struct hal_cmd_handsfree_phone_state_change *cmd = buf;
> > +	struct hf_device *dev;
> >  	uint8_t status;
> >  
> >  	if (len != sizeof(*cmd) + cmd->number_len || (cmd->number_len != 0 &&
> > @@ -2225,32 +2373,38 @@ static void handle_phone_state_change(const void *buf, uint16_t len)
> >  	DBG("active=%u hold=%u state=%u", cmd->num_active, cmd->num_held,
> >  								cmd->state);
> >  
> > +	dev = find_default_device();
> > +	if (!dev) {
> > +		status = HAL_STATUS_FAILED;
> > +		goto failed;
> > +	}
> > +
> >  	switch (cmd->state) {
> >  	case HAL_HANDSFREE_CALL_STATE_DIALING:
> > -		phone_state_dialing(&device, cmd->num_active, cmd->num_held);
> > +		phone_state_dialing(dev, cmd->num_active, cmd->num_held);
> >  		break;
> >  	case HAL_HANDSFREE_CALL_STATE_ALERTING:
> > -		phone_state_alerting(&device, cmd->num_active, cmd->num_held);
> > +		phone_state_alerting(dev, cmd->num_active, cmd->num_held);
> >  		break;
> >  	case HAL_HANDSFREE_CALL_STATE_INCOMING:
> > -		phone_state_incoming(&device, cmd->num_active, cmd->num_held,
> > +		phone_state_incoming(dev, cmd->num_active, cmd->num_held,
> >  						cmd->type, cmd->number,
> >  						cmd->number_len);
> >  		break;
> >  	case HAL_HANDSFREE_CALL_STATE_IDLE:
> > -		phone_state_idle(&device, cmd->num_active, cmd->num_held);
> > +		phone_state_idle(dev, cmd->num_active, cmd->num_held);
> >  		break;
> >  	default:
> >  		DBG("unhandled new state %u (current state %u)", cmd->state,
> > -							device.setup_state);
> > +							dev->setup_state);
> >  
> >  		status = HAL_STATUS_FAILED;
> >  		goto failed;
> >  	}
> >  
> > -	device.num_active = cmd->num_active;
> > -	device.num_held = cmd->num_held;
> > -	device.setup_state = cmd->state;
> > +	dev->num_active = cmd->num_active;
> > +	dev->num_held = cmd->num_held;
> > +	dev->setup_state = cmd->state;
> >  
> >  	status = HAL_STATUS_SUCCESS;
> >  
> > @@ -2374,9 +2528,7 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
> >  	char address[18];
> >  	bdaddr_t bdaddr;
> >  	GError *err = NULL;
> > -
> > -	if (device.sco)
> > -		goto drop;
> > +	struct hf_device *dev;
> >  
> >  	bt_io_get(chan, &err,
> >  			BT_IO_OPT_DEST, address,
> > @@ -2390,18 +2542,19 @@ static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
> >  
> >  	DBG("incoming SCO connection from %s", address);
> >  
> > -	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED ||
> > -			bacmp(&device.bdaddr, &bdaddr)) {
> > +	dev = find_device(&bdaddr);
> > +	if (!dev || dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED ||
> > +								dev->sco) {
> >  		error("handsfree: audio connection from %s rejected", address);
> >  		goto drop;
> >  	}
> >  
> > -	if (!bt_io_accept(chan, connect_sco_cb, &device, NULL, NULL)) {
> > +	if (!bt_io_accept(chan, connect_sco_cb, dev, NULL, NULL)) {
> >  		error("handsfree: failed to accept audio connection");
> >  		goto drop;
> >  	}
> >  
> > -	set_audio_state(&device, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
> > +	set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING);
> >  	return;
> >  
> >  drop:
> > @@ -2633,21 +2786,23 @@ static void bt_sco_get_fd(const void *buf, uint16_t len)
> >  	int fd;
> >  	GError *err;
> >  	struct sco_rsp_get_fd rsp;
> > +	struct hf_device *dev;
> >  
> >  	DBG("");
> >  
> > -	if (!device.sco)
> > +	dev = find_default_device();
> > +	if (!dev || !dev->sco)
> >  		goto failed;
> >  
> >  	err = NULL;
> > -	if (!bt_io_get(device.sco, &err, BT_IO_OPT_MTU, &rsp.mtu,
> > +	if (!bt_io_get(dev->sco, &err, BT_IO_OPT_MTU, &rsp.mtu,
> >  							BT_IO_OPT_INVALID)) {
> >  		error("Unable to get MTU: %s\n", err->message);
> >  		g_clear_error(&err);
> >  		goto failed;
> >  	}
> >  
> > -	fd = g_io_channel_unix_get_fd(device.sco);
> > +	fd = g_io_channel_unix_get_fd(dev->sco);
> >  
> >  	DBG("fd %d mtu %u", fd, rsp.mtu);
> >  
> 

-- 
Best regards, 
Szymon Janc

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2014-10-08  9:44 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-08  7:12 [PATCH 01/13] android/handsfree: Define proper type for device structure Szymon Janc
2014-10-08  7:12 ` [PATCH 02/13] android/handsfree: Make init, cleanup and state functions static less Szymon Janc
2014-10-08  7:12 ` [PATCH 03/13] android/handsfree: Pass device as user data to AT handlers Szymon Janc
2014-10-08  7:12 ` [PATCH 04/13] android/handsfree: Pass device to connection handling functions Szymon Janc
2014-10-08  7:12 ` [PATCH 05/13] android/handsfree: Pass device pointer when registering AT commands Szymon Janc
2014-10-08  7:12 ` [PATCH 06/13] android/handsfree: Pass device pointer to codec handling functions Szymon Janc
2014-10-08  7:12 ` [PATCH 07/13] android/handsfree: Pass device to SCO " Szymon Janc
2014-10-08  7:12 ` [PATCH 08/13] android/handsfree: Move clip into device structure Szymon Janc
2014-10-08  8:06   ` Andrei Emeltchenko
2014-10-08  7:12 ` [PATCH 09/13] android/handsfree: Pass device to SCO handling functions Szymon Janc
2014-10-08  8:10   ` Andrei Emeltchenko
2014-10-08  7:12 ` [PATCH 10/13] android/handsfree: Pass device object to disconnect watch Szymon Janc
2014-10-08  7:12 ` [PATCH 11/13] android/handsfree: Pass device to phone state and indicators functions Szymon Janc
2014-10-08  7:12 ` [PATCH 12/13] android/handsfree: Add helper for getting device Szymon Janc
2014-10-08  8:23   ` Andrei Emeltchenko
2014-10-08  9:44     ` Szymon Janc
2014-10-08  7:12 ` [PATCH 13/13] android/handsfree: Make remote device non-static Szymon Janc
2014-10-08  8:30   ` Andrei Emeltchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.