Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 0/8] Initial AT handling for handsfree
@ 2014-03-04 15:32 Szymon Janc
  2014-03-04 15:32 ` [PATCH 1/8] android/handsfree: Add support for AT+BRSF command Szymon Janc
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Hi,

This adds initial minimal set of AT commands to establish SLC connection.

Szymon Janc (8):
  android/handsfree: Add support for AT+BRSF command
  android/handsfree: Add support for AT+CIND command
  android/handsfree: Add support for AT+CMER command
  android/handsfree: Distinguish between HSP and HFP connection
  shared/hfp: Add function to check if reach end of command
  shared/hfp: Add hfp_gw_result_get_number_default function
  android/handsfree: Add support for AT+BIA command
  android/handsfree: Make connection state constants name shorter

 android/hal-msg.h   |  10 +-
 android/handsfree.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/shared/hfp.c    |  20 ++++
 src/shared/hfp.h    |   4 +
 4 files changed, 282 insertions(+), 18 deletions(-)

-- 
1.8.3.2


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

* [PATCH 1/8] android/handsfree: Add support for AT+BRSF command
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-04 15:32 ` [PATCH 2/8] android/handsfree: Add support for AT+CIND command Szymon Janc
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/android/handsfree.c b/android/handsfree.c
index 4f69e68..ce690d7 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -54,6 +54,7 @@
 static struct {
 	bdaddr_t bdaddr;
 	uint8_t state;
+	uint32_t features;
 	struct hfp_gw *gw;
 } device;
 
@@ -119,6 +120,31 @@ static void disconnect_watch(void *user_data)
 	device_cleanup();
 }
 
+static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+							void *user_data)
+{
+	unsigned int feat;
+
+	switch (type) {
+	case HFP_GW_CMD_TYPE_SET:
+		if (!hfp_gw_result_get_number(result, &feat))
+			break;
+
+		/* TODO verify features */
+		device.features = feat;
+
+		hfp_gw_send_info(device.gw, "+BRSF=%u", HFP_AG_FEATURES);
+		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+		return;
+	case HFP_GW_CMD_TYPE_READ:
+	case HFP_GW_CMD_TYPE_TEST:
+	case HFP_GW_CMD_TYPE_COMMAND:
+		break;
+	}
+
+	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+}
+
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	DBG("");
@@ -138,6 +164,8 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	hfp_gw_set_command_handler(device.gw, at_command_handler, NULL, NULL);
 	hfp_gw_set_disconnect_handler(device.gw, disconnect_watch, NULL, NULL);
 
+
+	hfp_gw_register(device.gw, at_cmd_brsf, "+BRSF", NULL, NULL);
 	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
 
 	return;
-- 
1.8.3.2


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

* [PATCH 2/8] android/handsfree: Add support for AT+CIND command
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
  2014-03-04 15:32 ` [PATCH 1/8] android/handsfree: Add support for AT+BRSF command Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-04 15:32 ` [PATCH 3/8] android/handsfree: Add support for AT+CMER command Szymon Janc
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index ce690d7..4db0560 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -51,6 +51,21 @@
 
 #define HFP_AG_FEATURES 0
 
+static const struct {
+	const char *name;
+	int min;
+	int max;
+	bool always_active;
+} indicators[] = {
+		{ "service",   0, 1, false },
+		{ "call",      0, 1, true },
+		{ "callsetup", 0, 3, true },
+		{ "callheld",  0, 2, true },
+		{ "signal",    0, 5, false },
+		{ "roam",      0, 1, false },
+		{ "battchg",   0, 5, false },
+};
+
 static struct {
 	bdaddr_t bdaddr;
 	uint8_t state;
@@ -120,6 +135,56 @@ static void disconnect_watch(void *user_data)
 	device_cleanup();
 }
 
+static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+							void *user_data)
+{
+	char *buf, *ptr;
+	int len;
+	unsigned int i;
+
+	switch (type) {
+	case HFP_GW_CMD_TYPE_TEST:
+
+		len = strlen("+CIND:") + 1;
+
+		for (i = 0; i < G_N_ELEMENTS(indicators); i++) {
+			len += strlen("(\"\",(X,X)),");
+			len += strlen(indicators[i].name);
+		}
+
+		buf = g_malloc(len);
+
+		ptr = buf + sprintf(buf, "+CIND:");
+
+		for (i = 0; i < G_N_ELEMENTS(indicators); i++) {
+			ptr += sprintf(ptr, "(\"%s\",(%d%c%d)),",
+					indicators[i].name,
+					indicators[i].min,
+					indicators[i].max == 1 ? ',' : '-',
+					indicators[i].max);
+		}
+
+		ptr--;
+		*ptr = '\0';
+
+		hfp_gw_send_info(device.gw, "%s", buf);
+		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+
+		g_free(buf);
+
+		return;
+	case HFP_GW_CMD_TYPE_READ:
+		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
+						HAL_EV_HANDSFREE_CIND, 0, NULL);
+		return;
+	case HFP_GW_CMD_TYPE_SET:
+	case HFP_GW_CMD_TYPE_COMMAND:
+		break;
+	}
+
+	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+}
+
 static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 							void *user_data)
 {
@@ -166,6 +231,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 
 	hfp_gw_register(device.gw, at_cmd_brsf, "+BRSF", NULL, NULL);
+	hfp_gw_register(device.gw, at_cmd_cind, "+CIND", NULL, NULL);
 	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
 
 	return;
@@ -512,12 +578,41 @@ static void handle_cops(const void *buf, uint16_t len)
 			HAL_OP_HANDSFREE_COPS_RESPONSE, HAL_STATUS_FAILED);
 }
 
+static unsigned int get_callsetup(uint8_t state)
+{
+	switch (state) {
+	case HAL_HANDSFREE_CALL_STATE_INCOMING:
+		return 1;
+	case HAL_HANDSFREE_CALL_STATE_DIALING:
+		return 2;
+	case HAL_HANDSFREE_CALL_STATE_ALERTING:
+		return 3;
+	default:
+		return 0;
+	}
+}
+
 static void handle_cind(const void *buf, uint16_t len)
 {
+	const struct hal_cmd_handsfree_cind_response *cmd = buf;
+
 	DBG("");
 
+	/* HAL doesn't provide CIND values directly so need to convert here */
+
+	hfp_gw_send_info(device.gw, "+CIND: %u,%u,%u,%u,%u,%u,%u",
+				cmd->svc,
+				!!(cmd->num_active + cmd->num_held),
+				get_callsetup(cmd->state),
+				cmd->num_held ? (cmd->num_active ? 1 : 2) : 0,
+				cmd->signal,
+				cmd->roam,
+				cmd->batt_chg);
+
+	hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
-			HAL_OP_HANDSFREE_CIND_RESPONSE, HAL_STATUS_FAILED);
+			HAL_OP_HANDSFREE_CIND_RESPONSE, HAL_STATUS_SUCCESS);
 }
 
 static void handle_formatted_at_resp(const void *buf, uint16_t len)
-- 
1.8.3.2


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

* [PATCH 3/8] android/handsfree: Add support for AT+CMER command
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
  2014-03-04 15:32 ` [PATCH 1/8] android/handsfree: Add support for AT+BRSF command Szymon Janc
  2014-03-04 15:32 ` [PATCH 2/8] android/handsfree: Add support for AT+CIND command Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-04 15:32 ` [PATCH 4/8] android/handsfree: Distinguish between HSP and HFP connection Szymon Janc
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

When this command is received SLC is connected.
---
 android/handsfree.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 4db0560..a437fba 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -70,6 +70,7 @@ static struct {
 	bdaddr_t bdaddr;
 	uint8_t state;
 	uint32_t features;
+	bool indicators_enabled;
 	struct hfp_gw *gw;
 } device;
 
@@ -125,7 +126,8 @@ static void at_command_handler(const char *command, void *user_data)
 {
 	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
 
-	hfp_gw_disconnect(device.gw);
+	if (device.state != HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED)
+		hfp_gw_disconnect(device.gw);
 }
 
 static void disconnect_watch(void *user_data)
@@ -135,6 +137,46 @@ static void disconnect_watch(void *user_data)
 	device_cleanup();
 }
 
+static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+							void *user_data)
+{
+	unsigned int val;
+
+	switch (type) {
+	case HFP_GW_CMD_TYPE_SET:
+		/* mode must be =3 */
+		if (!hfp_gw_result_get_number(result, &val) || val != 3)
+			break;
+
+		/* keyp is don't care */
+		if (!hfp_gw_result_get_number(result, &val))
+			break;
+
+		/* disp is don't care */
+		if (!hfp_gw_result_get_number(result, &val))
+			break;
+
+		/* ind must be 0 or 1 */
+		if (!hfp_gw_result_get_number(result, &val) || val > 1)
+			break;
+
+		device.indicators_enabled = val;
+
+		/* TODO Check for 3-way calling support */
+		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED);
+
+		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+
+		return;
+	case HFP_GW_CMD_TYPE_TEST:
+	case HFP_GW_CMD_TYPE_READ:
+	case HFP_GW_CMD_TYPE_COMMAND:
+		break;
+	}
+
+	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+}
+
 static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 							void *user_data)
 {
@@ -232,6 +274,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 	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);
 	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
 
 	return;
-- 
1.8.3.2


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

* [PATCH 4/8] android/handsfree: Distinguish between HSP and HFP connection
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
                   ` (2 preceding siblings ...)
  2014-03-04 15:32 ` [PATCH 3/8] android/handsfree: Add support for AT+CMER command Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-04 15:32 ` [PATCH 5/8] shared/hfp: Add function to check if reach end of command Szymon Janc
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

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

diff --git a/android/handsfree.c b/android/handsfree.c
index a437fba..50b32da 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -71,6 +71,7 @@ static struct {
 	uint8_t state;
 	uint32_t features;
 	bool indicators_enabled;
+	bool hsp;
 	struct hfp_gw *gw;
 } device;
 
@@ -272,10 +273,16 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	hfp_gw_set_disconnect_handler(device.gw, disconnect_watch, NULL, NULL);
 
 
-	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);
-	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
+	if (device.hsp) {
+		/* TODO CKPD, VGS, VGM */
+		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
+		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED);
+	} else {
+		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);
+		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
+	}
 
 	return;
 
@@ -315,6 +322,8 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
 		goto drop;
 	}
 
+	device.hsp = GPOINTER_TO_INT(data);
+
 	return;
 
 drop:
@@ -386,6 +395,8 @@ static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
 		goto fail;
 	}
 
+	device.hsp = true;
+
 	g_io_channel_unref(io);
 	return;
 
@@ -804,7 +815,8 @@ static bool enable_hsp_ag(void)
 
 	DBG("");
 
-	hsp_server =  bt_io_listen(NULL, confirm_cb, NULL, NULL, &err,
+	hsp_server =  bt_io_listen(NULL, confirm_cb, GINT_TO_POINTER(true), NULL,
+					&err,
 					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
 					BT_IO_OPT_CHANNEL, HSP_AG_CHANNEL,
 					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
@@ -935,7 +947,8 @@ static bool enable_hfp_ag(void)
 	if (hfp_server)
 		return false;
 
-	hfp_server =  bt_io_listen(NULL, confirm_cb, NULL, NULL, &err,
+	hfp_server =  bt_io_listen(NULL, confirm_cb, GINT_TO_POINTER(false),
+					NULL, &err,
 					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
 					BT_IO_OPT_CHANNEL, HFP_AG_CHANNEL,
 					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-- 
1.8.3.2


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

* [PATCH 5/8] shared/hfp: Add function to check if reach end of command
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
                   ` (3 preceding siblings ...)
  2014-03-04 15:32 ` [PATCH 4/8] android/handsfree: Distinguish between HSP and HFP connection Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-04 15:32 ` [PATCH 6/8] shared/hfp: Add hfp_gw_result_get_number_default function Szymon Janc
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 src/shared/hfp.c | 5 +++++
 src/shared/hfp.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index b10316e..44b5b55 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -336,6 +336,11 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
 	return true;
 }
 
+bool hfp_gw_result_has_next(struct hfp_gw_result *result)
+{
+	return result->data[result->offset] != '\0';
+}
+
 static void process_input(struct hfp_gw *hfp)
 {
 	char *str, *ptr;
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 649b77e..4da5c97 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -120,3 +120,4 @@ bool hfp_gw_result_get_string(struct hfp_gw_result *result, char *buf,
 								uint8_t len);
 bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
 								uint8_t len);
+bool hfp_gw_result_has_next(struct hfp_gw_result *result);
-- 
1.8.3.2


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

* [PATCH 6/8] shared/hfp: Add hfp_gw_result_get_number_default function
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
                   ` (4 preceding siblings ...)
  2014-03-04 15:32 ` [PATCH 5/8] shared/hfp: Add function to check if reach end of command Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-04 15:32 ` [PATCH 7/8] android/handsfree: Add support for AT+BIA command Szymon Janc
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 src/shared/hfp.c | 15 +++++++++++++++
 src/shared/hfp.h |  3 +++
 2 files changed, 18 insertions(+)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 44b5b55..e548672 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -224,6 +224,21 @@ static void next_field(struct hfp_gw_result *result)
 		result->offset++;
 }
 
+bool hfp_gw_result_get_number_default(struct hfp_gw_result *result,
+						unsigned int *val,
+						unsigned int default_val)
+{
+	skip_whitespace(result);
+
+	if (result->data[result->offset] == ',') {
+		if (val)
+			*val = default_val;
+		return true;
+	}
+
+	return hfp_gw_result_get_number(result, val);
+}
+
 bool hfp_gw_result_get_number(struct hfp_gw_result *result, unsigned int *val)
 {
 	int tmp = 0;
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 4da5c97..743db65 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -114,6 +114,9 @@ bool hfp_gw_register(struct hfp_gw *hfp, hfp_result_func_t callback,
 bool hfp_gw_unregister(struct hfp_gw *hfp, const char *prefix);
 
 bool hfp_gw_result_get_number(struct hfp_gw_result *result, unsigned int *val);
+bool hfp_gw_result_get_number_default(struct hfp_gw_result *result,
+						unsigned int *val,
+						unsigned int default_val);
 bool hfp_gw_result_open_container(struct hfp_gw_result *result);
 bool hfp_gw_result_close_container(struct hfp_gw_result *result);
 bool hfp_gw_result_get_string(struct hfp_gw_result *result, char *buf,
-- 
1.8.3.2


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

* [PATCH 7/8] android/handsfree: Add support for AT+BIA command
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
                   ` (5 preceding siblings ...)
  2014-03-04 15:32 ` [PATCH 6/8] shared/hfp: Add hfp_gw_result_get_number_default function Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-04 15:32 ` [PATCH 8/8] android/handsfree: Make connection state constants name shorter Szymon Janc
  2014-03-05 16:14 ` [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

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

diff --git a/android/handsfree.c b/android/handsfree.c
index 50b32da..99e786f 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -71,6 +71,7 @@ static struct {
 	uint8_t state;
 	uint32_t features;
 	bool indicators_enabled;
+	bool active_ind[G_N_ELEMENTS(indicators)];
 	bool hsp;
 	struct hfp_gw *gw;
 } device;
@@ -106,8 +107,13 @@ static void device_set_state(uint8_t state)
 
 static void device_init(const bdaddr_t *bdaddr)
 {
+	unsigned int i;
+
 	bacpy(&device.bdaddr, bdaddr);
 
+	for (i = 0; i < G_N_ELEMENTS(device.active_ind); i++)
+		device.active_ind[i] = indicators[i].always_active;
+
 	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTING);
 }
 
@@ -138,6 +144,54 @@ static void disconnect_watch(void *user_data)
 	device_cleanup();
 }
 
+static void at_cmd_bia(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+							void *user_data)
+{
+	unsigned int val, i = 0;
+
+	switch (type) {
+	case HFP_GW_CMD_TYPE_SET:
+		do {
+			if (!hfp_gw_result_get_number_default(result, &val, 0))
+				goto failed;
+
+			if (val > 1)
+				goto failed;
+		} while(hfp_gw_result_has_next(result));
+
+
+		do {
+			if (!hfp_gw_result_get_number(result, &val))
+				device.active_ind[i] = val ||
+						indicators[i].always_active;
+
+			if (++i == G_N_ELEMENTS(indicators))
+				break;
+		} while (hfp_gw_result_has_next(result));
+
+		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
+
+		return;
+	case HFP_GW_CMD_TYPE_TEST:
+	case HFP_GW_CMD_TYPE_READ:
+	case HFP_GW_CMD_TYPE_COMMAND:
+		break;
+	}
+
+failed:
+	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+}
+
+static void register_post_slc_at(void)
+{
+	if (device.hsp) {
+		/* TODO CKPD, VGS, VGM */
+		return;
+	}
+
+	hfp_gw_register(device.gw, at_cmd_bia, "+BIA", NULL, NULL);
+}
+
 static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 							void *user_data)
 {
@@ -164,6 +218,7 @@ static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		device.indicators_enabled = val;
 
 		/* TODO Check for 3-way calling support */
+		register_post_slc_at();
 		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED);
 
 		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
@@ -253,6 +308,13 @@ static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	hfp_gw_send_result(device.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);
+}
+
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	DBG("");
@@ -274,16 +336,15 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 
 	if (device.hsp) {
-		/* TODO CKPD, VGS, VGM */
+		register_post_slc_at();
 		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
 		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED);
-	} else {
-		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);
-		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
+		return;
 	}
 
+	register_slc_at();
+	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
+
 	return;
 
 failed:
-- 
1.8.3.2


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

* [PATCH 8/8] android/handsfree: Make connection state constants name shorter
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
                   ` (6 preceding siblings ...)
  2014-03-04 15:32 ` [PATCH 7/8] android/handsfree: Add support for AT+BIA command Szymon Janc
@ 2014-03-04 15:32 ` Szymon Janc
  2014-03-05 16:14 ` [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-04 15:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/hal-msg.h   | 10 +++++-----
 android/handsfree.c | 26 +++++++++++++-------------
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index dd25f6e..886b5d3 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -979,11 +979,11 @@ struct hal_ev_a2dp_audio_state {
 	uint8_t bdaddr[6];
 } __attribute__((packed));
 
-#define HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTED	0x00
-#define HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTING	0x01
-#define HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED	0x02
-#define HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED	0x03
-#define HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTING	0x04
+#define HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED	0x00
+#define HAL_EV_HANDSFREE_CONN_STATE_CONNECTING		0x01
+#define HAL_EV_HANDSFREE_CONN_STATE_CONNECTED		0x02
+#define HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED	0x03
+#define HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING	0x04
 
 #define HAL_EV_HANDSFREE_CONN_STATE		0x81
 struct hal_ev_handsfree_conn_state {
diff --git a/android/handsfree.c b/android/handsfree.c
index 99e786f..6f91e74 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -114,7 +114,7 @@ static void device_init(const bdaddr_t *bdaddr)
 	for (i = 0; i < G_N_ELEMENTS(device.active_ind); i++)
 		device.active_ind[i] = indicators[i].always_active;
 
-	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTING);
+	device_set_state(HAL_EV_HANDSFREE_CONN_STATE_CONNECTING);
 }
 
 static void device_cleanup(void)
@@ -124,7 +124,7 @@ static void device_cleanup(void)
 		device.gw = NULL;
 	}
 
-	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTED);
+	device_set_state(HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED);
 
 	memset(&device, 0, sizeof(device));
 }
@@ -133,7 +133,7 @@ static void at_command_handler(const char *command, void *user_data)
 {
 	hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
 
-	if (device.state != HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED)
+	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED)
 		hfp_gw_disconnect(device.gw);
 }
 
@@ -219,7 +219,7 @@ static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 		/* TODO Check for 3-way calling support */
 		register_post_slc_at();
-		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED);
+		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 
 		hfp_gw_send_result(device.gw, HFP_RESULT_OK);
 
@@ -337,13 +337,13 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 	if (device.hsp) {
 		register_post_slc_at();
-		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
-		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_SLC_CONNECTED);
+		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
+		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED);
 		return;
 	}
 
 	register_slc_at();
-	device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
+	device_set_state(HAL_EV_HANDSFREE_CONN_STATE_CONNECTED);
 
 	return;
 
@@ -370,7 +370,7 @@ static void confirm_cb(GIOChannel *chan, gpointer data)
 
 	DBG("incoming connect from %s", address);
 
-	if (device.state != HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTED) {
+	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
 		info("handsfree: refusing connection from %s", address);
 		goto drop;
 	}
@@ -572,7 +572,7 @@ static void handle_connect(const void *buf, uint16_t len)
 
 	DBG("");
 
-	if (device.state != HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTED) {
+	if (device.state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) {
 		status = HAL_STATUS_FAILED;
 		goto failed;
 	}
@@ -610,22 +610,22 @@ static void handle_disconnect(const void *buf, uint16_t len)
 
 	android2bdaddr(cmd->bdaddr, &bdaddr);
 
-	if (device.state == HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTED ||
+	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED ||
 			bacmp(&device.bdaddr, &bdaddr)) {
 		status = HAL_STATUS_FAILED;
 		goto failed;
 
 	}
 
-	if (device.state == HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTING) {
+	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) {
 		status = HAL_STATUS_SUCCESS;
 		goto failed;
 	}
 
-	if (device.state == HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTING) {
+	if (device.state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) {
 		device_cleanup();
 	} else {
-		device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTING);
+		device_set_state(HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING);
 		hfp_gw_disconnect(device.gw);
 	}
 
-- 
1.8.3.2


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

* Re: [PATCH 0/8] Initial AT handling for handsfree
  2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
                   ` (7 preceding siblings ...)
  2014-03-04 15:32 ` [PATCH 8/8] android/handsfree: Make connection state constants name shorter Szymon Janc
@ 2014-03-05 16:14 ` Szymon Janc
  8 siblings, 0 replies; 10+ messages in thread
From: Szymon Janc @ 2014-03-05 16:14 UTC (permalink / raw)
  To: linux-bluetooth

On Tuesday 04 of March 2014 16:32:02 Szymon Janc wrote:
> Hi,
> 
> This adds initial minimal set of AT commands to establish SLC connection.
> 
> Szymon Janc (8):
>   android/handsfree: Add support for AT+BRSF command
>   android/handsfree: Add support for AT+CIND command
>   android/handsfree: Add support for AT+CMER command
>   android/handsfree: Distinguish between HSP and HFP connection
>   shared/hfp: Add function to check if reach end of command
>   shared/hfp: Add hfp_gw_result_get_number_default function
>   android/handsfree: Add support for AT+BIA command
>   android/handsfree: Make connection state constants name shorter
> 
>  android/hal-msg.h   |  10 +-
>  android/handsfree.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++---
>  src/shared/hfp.c    |  20 ++++
>  src/shared/hfp.h    |   4 +
>  4 files changed, 282 insertions(+), 18 deletions(-)

Updated version of those patches is now pushed upstream.

-- 
Best regards, 
Szymon Janc

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

end of thread, other threads:[~2014-03-05 16:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-04 15:32 [PATCH 0/8] Initial AT handling for handsfree Szymon Janc
2014-03-04 15:32 ` [PATCH 1/8] android/handsfree: Add support for AT+BRSF command Szymon Janc
2014-03-04 15:32 ` [PATCH 2/8] android/handsfree: Add support for AT+CIND command Szymon Janc
2014-03-04 15:32 ` [PATCH 3/8] android/handsfree: Add support for AT+CMER command Szymon Janc
2014-03-04 15:32 ` [PATCH 4/8] android/handsfree: Distinguish between HSP and HFP connection Szymon Janc
2014-03-04 15:32 ` [PATCH 5/8] shared/hfp: Add function to check if reach end of command Szymon Janc
2014-03-04 15:32 ` [PATCH 6/8] shared/hfp: Add hfp_gw_result_get_number_default function Szymon Janc
2014-03-04 15:32 ` [PATCH 7/8] android/handsfree: Add support for AT+BIA command Szymon Janc
2014-03-04 15:32 ` [PATCH 8/8] android/handsfree: Make connection state constants name shorter Szymon Janc
2014-03-05 16:14 ` [PATCH 0/8] Initial AT handling for handsfree Szymon Janc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox