Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF
@ 2014-11-19  9:43 Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 01/15] android/handsfree-client: Fix index type in call action command Lukasz Rymanowski
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

In this set all mising signaling part is implemented.
Tested on UPF 49 as well.

SCO part will come in next set.

v2:
* Addressed Szymon comments
* Added patch fixing index type in IPC call action command (01/15)

Lukasz Rymanowski (15):
  android/handsfree-client: Fix index type in call action command
  android/handsfree-client: Add handle start/stop vr
  android/handsfree-client: Add volume control handling
  android/handsfree-client: Add handling dial command
  android/handsfree-client: Add call action implementation
  android/handsfree-client: Implement query current calls
  android/handsfree-client: Add handling +CLCC
  android/handsfree-client: Add support for +CIEV events
  android/handsfree-client: Send indicators val we got during SLC setup
  android/handsfree-client: Add support to get operator name
  android/handsfree-client: Send to AG that we do support long name
  android/handsfree-client: Retrieve subscriber number information
  android/handsfree-client: Implement send DTMF codes
  android/handsfree-client: Implement handling AT+BINP and +BINP
  android/handsfree-client: Implement codec negotiations

 android/hal-msg.h          |   2 +-
 android/handsfree-client.c | 833 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 802 insertions(+), 33 deletions(-)

-- 
1.8.4


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

* [PATCH v2 01/15] android/handsfree-client: Fix index type in call action command
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 02/15] android/handsfree-client: Add handle start/stop vr Lukasz Rymanowski
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

According to BT HAL API index should be int.
---
 android/hal-msg.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index c86b0a6..c2c659c 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -1089,7 +1089,7 @@ struct hal_cmd_hf_client_dial_memory {
 #define HAL_OP_HF_CLIENT_CALL_ACTION		0x0a
 struct hal_cmd_hf_client_call_action {
 	uint8_t action;
-	uint8_t index;
+	int32_t index;
 } __attribute__((packed));
 
 #define HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS	0x0b
-- 
1.8.4


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

* [PATCH v2 02/15] android/handsfree-client: Add handle start/stop vr
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 01/15] android/handsfree-client: Fix index type in call action command Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 03/15] android/handsfree-client: Add volume control handling Lukasz Rymanowski
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

This patch implements start/stop voice recogniction command handling.
It also introduce find_default_device which returns connected device.

Note that for now we support only one device as this is HAL limitation
---
 android/handsfree-client.c | 106 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 102 insertions(+), 4 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index c576ae8..8b016c6 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -135,6 +135,11 @@ static uint32_t hfp_hf_record_id = 0;
 static struct queue *devices = NULL;
 static GIOChannel *hfp_hf_server = NULL;
 
+static struct device *find_default_device(void)
+{
+	return queue_peek_head(devices);
+}
+
 static bool match_by_bdaddr(const void *data, const void *user_data)
 {
 	const bdaddr_t *addr1 = data;
@@ -293,18 +298,95 @@ static void handle_disconnect_audio(const void *buf, uint16_t len)
 					HAL_STATUS_UNSUPPORTED);
 }
 
+static void cmd_complete_cb(enum hfp_result result, enum hfp_error cme_err,
+							void *user_data)
+{
+	struct hal_ev_hf_client_command_complete ev;
+
+	DBG("");
+
+	memset(&ev, 0, sizeof(ev));
+
+	switch (result) {
+	case HFP_RESULT_OK:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_OK;
+		break;
+	case HFP_RESULT_NO_CARRIER:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_NO_CARRIER;
+		break;
+	case HFP_RESULT_ERROR:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR;
+		break;
+	case HFP_RESULT_BUSY:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_BUSY;
+		break;
+	case HFP_RESULT_NO_ANSWER:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_NO_ANSWER;
+		break;
+	case HFP_RESULT_DELAYED:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_DELAYED;
+		break;
+	case HFP_RESULT_BLACKLISTED:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_BACKLISTED;
+		break;
+	case HFP_RESULT_CME_ERROR:
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_CME;
+		ev.cme = cme_err;
+		break;
+	default:
+		error("hf-client: Unknown error code %d", result);
+		ev.type = HAL_HF_CLIENT_CMD_COMP_ERR;
+		break;
+	}
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+			HAL_EV_CLIENT_COMMAND_COMPLETE, sizeof(ev), &ev);
+}
+
 static void handle_start_vr(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct device *dev;
+	uint8_t status;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BVRA=1"))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-			HAL_OP_HF_CLIENT_START_VR, HAL_STATUS_UNSUPPORTED);
+			HAL_OP_HF_CLIENT_START_VR, status);
 }
 
 static void handle_stop_vr(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct device *dev;
+	uint8_t status;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BVRA=0"))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-			HAL_OP_HF_CLIENT_STOP_VR, HAL_STATUS_UNSUPPORTED);
+			HAL_OP_HF_CLIENT_STOP_VR, status);
 }
 
 static void handle_volume_control(const void *buf, uint16_t len)
@@ -447,6 +529,20 @@ static void get_local_codecs_string(struct device *dev, char *buf,
 	}
 }
 
+static void bvra_cb(struct hfp_context *context, void *user_data)
+{
+	struct hal_ev_hf_client_vr_state ev;
+	unsigned int val;
+
+	if (!hfp_context_get_number(context, &val) || val > 1)
+		return;
+
+	ev.state = val ? HAL_HF_CLIENT_VR_STARTED : HAL_HF_CLIENT_VR_STOPPED;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+				HAL_EV_HF_CLIENT_VR_STATE, sizeof(ev), &ev);
+}
+
 static void slc_completed(struct device *dev)
 {
 	DBG("");
@@ -457,6 +553,8 @@ static void slc_completed(struct device *dev)
 	 * TODO: Notify Android with indicators, register unsolicited result
 	 * handlers
 	 */
+
+	hfp_hf_register(dev->hf, bvra_cb, "+BRVA", dev, NULL);
 }
 
 static void slc_chld_cb(struct hfp_context *context, void *user_data)
-- 
1.8.4


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

* [PATCH v2 03/15] android/handsfree-client: Add volume control handling
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 01/15] android/handsfree-client: Fix index type in call action command Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 02/15] android/handsfree-client: Add handle start/stop vr Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 04/15] android/handsfree-client: Add handling dial command Lukasz Rymanowski
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 71 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 69 insertions(+), 2 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 8b016c6..9e856e3 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -391,10 +391,45 @@ done:
 
 static void handle_volume_control(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct hal_cmd_hf_client_volume_control *cmd = buf;
+	struct device *dev;
+	uint8_t status;
+	uint8_t vol;
+	bool ret;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	/* Volume is in the range 0-15. Make sure we send correct value
+	 * to remote device
+	 */
+	vol = cmd->volume > 15 ? 15 : cmd->volume;
+
+	switch (cmd->type) {
+	case HF_CLIENT_VOLUME_TYPE_SPEAKER:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+							"AT+VGS=%u", vol);
+		break;
+	case HF_CLIENT_VOLUME_TYPE_MIC:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+							"AT+VGM=%u", vol);
+		break;
+	default:
+		ret = false;
+		break;
+	}
+
+	status = ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
 					HAL_OP_HF_CLIENT_VOLUME_CONTROL,
-					HAL_STATUS_UNSUPPORTED);
+					status);
 }
 
 static void handle_dial(const void *buf, uint16_t len)
@@ -543,6 +578,36 @@ static void bvra_cb(struct hfp_context *context, void *user_data)
 				HAL_EV_HF_CLIENT_VR_STATE, sizeof(ev), &ev);
 }
 
+static void vgm_cb(struct hfp_context *context, void *user_data)
+{
+	struct hal_ev_hf_client_volume_changed ev;
+	unsigned int val;
+
+	if (!hfp_context_get_number(context, &val) || val > 15)
+		return;
+
+	ev.type = HF_CLIENT_VOLUME_TYPE_MIC;
+	ev.volume = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+				HAL_EV_HF_CLIENT_VR_STATE, sizeof(ev), &ev);
+}
+
+static void vgs_cb(struct hfp_context *context, void *user_data)
+{
+	struct hal_ev_hf_client_volume_changed ev;
+	unsigned int val;
+
+	if (!hfp_context_get_number(context, &val) || val > 15)
+		return;
+
+	ev.type = HF_CLIENT_VOLUME_TYPE_SPEAKER;
+	ev.volume = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+			HAL_EV_CLIENT_VOLUME_CHANGED, sizeof(ev), &ev);
+}
+
 static void slc_completed(struct device *dev)
 {
 	DBG("");
@@ -555,6 +620,8 @@ static void slc_completed(struct device *dev)
 	 */
 
 	hfp_hf_register(dev->hf, bvra_cb, "+BRVA", dev, NULL);
+	hfp_hf_register(dev->hf, vgm_cb, "+VGM", dev, NULL);
+	hfp_hf_register(dev->hf, vgs_cb, "+VGS", dev, NULL);
 }
 
 static void slc_chld_cb(struct hfp_context *context, void *user_data)
-- 
1.8.4


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

* [PATCH v2 04/15] android/handsfree-client: Add handling dial command
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (2 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 03/15] android/handsfree-client: Add volume control handling Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 05/15] android/handsfree-client: Add call action implementation Lukasz Rymanowski
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 72 ++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 63 insertions(+), 9 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 9e856e3..2b9a3ac 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -435,24 +435,78 @@ done:
 static void handle_dial(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_hf_client_dial *cmd = buf;
+	struct device *dev;
+	uint8_t status;
+	bool ret;
 
-	if (len != sizeof(*cmd) + cmd->number_len) {
-		error("Malformed number data, size (%u bytes), terminating",
-									len);
-		raise(SIGTERM);
-		return;
+	DBG("");
+
+	if (len != sizeof(*cmd) + cmd->number_len)
+		goto failed;
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
 	}
 
-	DBG("Not Implemented");
+	if (cmd->number_len > 0) {
+		if (cmd->number[cmd->number_len - 1] != '\0')
+			goto failed;
+
+		DBG("Dialing %s", cmd->number);
+
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+							"ATD%s;", cmd->number);
+	} else {
+		DBG("Redialing");
+
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+BLDN");
+	}
+
+	status =  ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-				HAL_OP_HF_CLIENT_DIAL, HAL_STATUS_UNSUPPORTED);
+						HAL_OP_HF_CLIENT_DIAL, status);
+
+	return;
+
+failed:
+	error("Malformed number data, size (%u bytes), terminating", len);
+	raise(SIGTERM);
 }
 
 static void handle_dial_memory(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct hal_cmd_hf_client_dial_memory *cmd = buf;
+	struct device *dev;
+	uint8_t status;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	/* For some reason location in BT HAL is int. Therefore that check */
+	if (cmd->location < 0) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL , "ATD>%d;",
+								cmd->location))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-			HAL_OP_HF_CLIENT_DIAL_MEMORY, HAL_STATUS_UNSUPPORTED);
+					HAL_OP_HF_CLIENT_DIAL_MEMORY, status);
 }
 
 static void handle_call_action(const void *buf, uint16_t len)
-- 
1.8.4


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

* [PATCH v2 05/15] android/handsfree-client: Add call action implementation
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (3 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 04/15] android/handsfree-client: Add handling dial command Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 06/15] android/handsfree-client: Implement query current calls Lukasz Rymanowski
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 103 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 101 insertions(+), 2 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 2b9a3ac..c6812ec 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -511,9 +511,87 @@ done:
 
 static void handle_call_action(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct hal_cmd_hf_client_call_action *cmd = buf;
+	struct device *dev;
+	uint8_t status;
+	bool ret;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	switch (cmd->action) {
+	case HAL_HF_CLIENT_ACTION_CHLD_0:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+CHLD=0");
+		break;
+	case HAL_HF_CLIENT_ACTION_CHLD_1:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+CHLD=1");
+		break;
+	case HAL_HF_CLIENT_ACTION_CHLD_2:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb,
+							NULL, "AT+CHLD=2");
+		break;
+	case HAL_HF_CLIENT_ACTION_CHLD_3:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+CHLD=3");
+		break;
+	case HAL_HF_CLIENT_ACTION_CHLD_4:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+CHLD=4");
+		break;
+	case HAL_HF_CLIENT_ACTION_CHLD_1x:
+		/* Index is int in BT HAL. Let's be paranoid here */
+		if (cmd->index < 0)
+			ret = false;
+		else
+			ret = hfp_hf_send_command(dev->hf, cmd_complete_cb,
+					NULL, "AT+CHLD=1%d", cmd->index);
+		break;
+	case HAL_HF_CLIENT_ACTION_CHLD_2x:
+		/* Index is int in BT HAL. Let's be paranoid here */
+		if (cmd->index < 0)
+			ret = false;
+		else
+			ret = hfp_hf_send_command(dev->hf, cmd_complete_cb,
+					NULL, "AT+CHLD=2%d", cmd->index);
+		break;
+	case HAL_HF_CLIENT_ACTION_ATA:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+									"ATA");
+		break;
+	case HAL_HF_CLIENT_ACTION_CHUP:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+CHUP");
+		break;
+	case HAL_HF_CLIENT_ACTION_BRTH_0:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+BTRH=0");
+		break;
+	case HAL_HF_CLIENT_ACTION_BRTH_1:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+BTRH=1");
+		break;
+	case HAL_HF_CLIENT_ACTION_BRTH_2:
+		ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL,
+								"AT+BTRH=2");
+		break;
+	default:
+		error("hf-client: Unknown action %d", cmd->action);
+		ret = false;
+		break;
+	}
+
+	status = ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-			HAL_OP_HF_CLIENT_CALL_ACTION, HAL_STATUS_UNSUPPORTED);
+					HAL_OP_HF_CLIENT_CALL_ACTION, status);
 }
 
 static void handle_query_current_calls(const void *buf, uint16_t len)
@@ -662,6 +740,26 @@ static void vgs_cb(struct hfp_context *context, void *user_data)
 			HAL_EV_CLIENT_VOLUME_CHANGED, sizeof(ev), &ev);
 }
 
+static void brth_cb(struct hfp_context *context, void *user_data)
+{
+	struct hal_ev_hf_client_response_and_hold_status ev;
+	unsigned int val;
+
+	DBG("");
+
+	if (!hfp_context_get_number(context, &val) ||
+			val > HAL_HF_CLIENT_RESP_AND_HOLD_STATUS_REJECT) {
+		error("hf-client: incorrect BTRH response ");
+		return;
+	}
+
+	ev.status = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+				HAL_EV_HF_CLIENT_RESPONSE_AND_HOLD_STATUS,
+				sizeof(ev), &ev);
+}
+
 static void slc_completed(struct device *dev)
 {
 	DBG("");
@@ -676,6 +774,7 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, bvra_cb, "+BRVA", dev, NULL);
 	hfp_hf_register(dev->hf, vgm_cb, "+VGM", dev, NULL);
 	hfp_hf_register(dev->hf, vgs_cb, "+VGS", dev, NULL);
+	hfp_hf_register(dev->hf, brth_cb, "+BTRH", dev, NULL);
 }
 
 static void slc_chld_cb(struct hfp_context *context, void *user_data)
-- 
1.8.4


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

* [PATCH v2 06/15] android/handsfree-client: Implement query current calls
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (4 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 05/15] android/handsfree-client: Add call action implementation Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 07/15] android/handsfree-client: Add handling +CLCC Lukasz Rymanowski
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index c6812ec..6860bed 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -596,10 +596,26 @@ done:
 
 static void handle_query_current_calls(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct device *dev;
+	uint8_t status;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+CLCC"))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
 					HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS,
-					HAL_STATUS_UNSUPPORTED);
+					status);
 }
 
 static void handle_query_operator_name(const void *buf, uint16_t len)
-- 
1.8.4


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

* [PATCH v2 07/15] android/handsfree-client: Add handling +CLCC
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (5 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 06/15] android/handsfree-client: Implement query current calls Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 08/15] android/handsfree-client: Add support for +CIEV events Lukasz Rymanowski
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

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

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 6860bed..79779c2 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -776,6 +776,63 @@ static void brth_cb(struct hfp_context *context, void *user_data)
 				sizeof(ev), &ev);
 }
 
+static void clcc_cb(struct hfp_context *context, void *user_data)
+{
+	uint8_t buf[IPC_MTU];
+	struct hal_ev_hf_client_current_call *ev = (void *) buf;
+	unsigned int val;
+	char number[33];
+
+	DBG("");
+
+	memset(buf, 0, sizeof(buf));
+
+	if (!hfp_context_get_number(context, &val)) {
+		error("hf-client: Could not get index");
+		return;
+	}
+
+	ev->index = val;
+
+	if (!hfp_context_get_number(context, &val) ||
+				val > HAL_HF_CLIENT_DIRECTION_INCOMIGN) {
+		error("hf-client: Could not get direction");
+		return;
+	}
+
+	ev->direction = val;
+
+	if (!hfp_context_get_number(context, &val) ||
+			val > HAL_HF_CLIENT_CALL_STATE_HELD_BY_RESP_AND_HOLD) {
+		error("hf-client: Could not get callstate");
+		return;
+	}
+
+	ev->call_state = val;
+
+	/* Next field is MODE but Android is not interested in this. Skip it */
+	if (!hfp_context_get_number(context, &val)) {
+		error("hf-client: Could not get mode");
+		return;
+	}
+
+	if (!hfp_context_get_number(context, &val) || val > 1) {
+		error("hf-client: Could not get multiparty");
+		return;
+	}
+
+	ev->multiparty = val;
+
+	if (hfp_context_get_string(context, number, sizeof(number))) {
+		ev->number_len = strlen(number) + 1;
+		memcpy(ev->number, number, ev->number_len);
+	}
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_HF_CLIENT_CURRENT_CALL,
+					sizeof(*ev) + ev->number_len, ev);
+}
+
 static void slc_completed(struct device *dev)
 {
 	DBG("");
@@ -791,6 +848,7 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, vgm_cb, "+VGM", dev, NULL);
 	hfp_hf_register(dev->hf, vgs_cb, "+VGS", dev, NULL);
 	hfp_hf_register(dev->hf, brth_cb, "+BTRH", dev, NULL);
+	hfp_hf_register(dev->hf, clcc_cb, "+CLCC", dev, NULL);
 }
 
 static void slc_chld_cb(struct hfp_context *context, void *user_data)
-- 
1.8.4


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

* [PATCH v2 08/15] android/handsfree-client: Add support for +CIEV events
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (6 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 07/15] android/handsfree-client: Add handling +CLCC Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 09/15] android/handsfree-client: Send indicators val we got during SLC setup Lukasz Rymanowski
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

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

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 79779c2..50c5821 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -95,11 +95,14 @@ enum hfp_indicator {
 	HFP_INDICATOR_LAST
 };
 
+typedef void (*ciev_func_t)(uint8_t val);
+
 struct indicator {
 	uint8_t index;
 	uint32_t min;
 	uint32_t max;
 	uint32_t val;
+	ciev_func_t cb;
 };
 
 struct hfp_codec {
@@ -833,6 +836,32 @@ static void clcc_cb(struct hfp_context *context, void *user_data)
 					sizeof(*ev) + ev->number_len, ev);
 }
 
+static void ciev_cb(struct hfp_context *context, void *user_data)
+{
+	struct device *dev = user_data;
+	unsigned int index, val;
+	int i;
+
+	DBG("");
+
+	if (!hfp_context_get_number(context, &index))
+		return;
+
+	if (!hfp_context_get_number(context, &val))
+		return;
+
+	for (i = 0; i < HFP_INDICATOR_LAST; i++) {
+		if (dev->ag_ind[i].index != index)
+			continue;
+
+		if (dev->ag_ind[i].cb) {
+			dev->ag_ind[i].val = val;
+			dev->ag_ind[i].cb(val);
+			return;
+		}
+	}
+}
+
 static void slc_completed(struct device *dev)
 {
 	DBG("");
@@ -849,6 +878,7 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, vgs_cb, "+VGS", dev, NULL);
 	hfp_hf_register(dev->hf, brth_cb, "+BTRH", dev, NULL);
 	hfp_hf_register(dev->hf, clcc_cb, "+CLCC", dev, NULL);
+	hfp_hf_register(dev->hf, ciev_cb, "+CIEV", dev, NULL);
 }
 
 static void slc_chld_cb(struct hfp_context *context, void *user_data)
@@ -1019,6 +1049,119 @@ failed:
 	slc_error(dev);
 }
 
+static void ciev_service_cb(uint8_t val)
+{
+	struct hal_ev_hf_client_net_state ev;
+
+	DBG("");
+
+	if (val > HAL_HF_CLIENT_NET_ROAMING_TYPE_ROAMING) {
+		error("hf-client: Incorrect state %u:", val);
+		return;
+	}
+
+	ev.state = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+				HAL_EV_HF_CLIENT_NET_STATE, sizeof(ev), &ev);
+}
+
+static void ciev_call_cb(uint8_t val)
+{
+	struct hal_ev_hf_client_call_indicator ev;
+
+	DBG("");
+
+	if (val > HAL_HF_CLIENT_CALL_IND_CALL_IN_PROGERSS) {
+		error("hf-client: Incorrect call state %u:", val);
+		return;
+	}
+
+	ev.call = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+			HAL_EV_HF_CLIENT_CALL_INDICATOR, sizeof(ev), &ev);
+}
+
+static void ciev_callsetup_cb(uint8_t val)
+{
+	struct hal_ev_hf_client_call_setup_indicator ev;
+
+	DBG("");
+
+	if (val > HAL_HF_CLIENT_CALL_SETUP_ALERTING) {
+		error("hf-client: Incorrect call setup state  %u:", val);
+		return;
+	}
+
+	ev.call_setup = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_HF_CLIENT_CALL_SETUP_INDICATOR,
+					sizeof(ev), &ev);
+}
+
+static void ciev_callheld_cb(uint8_t val)
+{
+	struct hal_ev_hf_client_call_held_indicator ev;
+
+	DBG("");
+
+	if (val > HAL_HF_CLIENT_CALL_SETUP_IND_HOLD) {
+		error("hf-client: Incorrect call held state  %u:", val);
+		return;
+	}
+
+	ev.call_held = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_HF_CLIENT_CALL_HELD_INDICATOR,
+					sizeof(ev), &ev);
+}
+
+static void ciev_signal_cb(uint8_t val)
+{
+	struct hal_ev_hf_client_net_signal_strength ev;
+
+	DBG("");
+
+	ev.signal_strength = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_HF_CLIENT_NET_SIGNAL_STRENGTH,
+					sizeof(ev), &ev);
+}
+
+static void ciev_roam_cb(uint8_t val)
+{
+	struct hal_ev_hf_client_net_roaming_type ev;
+
+	DBG("");
+
+	if (val > HAL_HF_CLIENT_NET_ROAMING_TYPE_ROAMING) {
+		error("hf-client: Incorrect roaming state  %u:", val);
+		return;
+	}
+
+	ev.state = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_HF_CLIENT_NET_ROAMING_TYPE,
+					sizeof(ev), &ev);
+}
+
+static void ciev_battchg_cb(uint8_t val)
+{
+	struct hal_ev_hf_client_battery_level ev;
+
+	DBG("");
+
+	ev.battery_level = val;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+			HAL_EV_HF_CLIENT_BATTERY_LEVEL, sizeof(ev), &ev);
+}
+
 static void set_indicator_parameters(uint8_t index, const char *indicator,
 						unsigned int min,
 						unsigned int max,
@@ -1032,6 +1175,7 @@ static void set_indicator_parameters(uint8_t index, const char *indicator,
 		ag_ind[HFP_INDICATOR_SERVICE].index = index;
 		ag_ind[HFP_INDICATOR_SERVICE].min = min;
 		ag_ind[HFP_INDICATOR_SERVICE].max = max;
+		ag_ind[HFP_INDICATOR_SERVICE].cb = ciev_service_cb;
 		return;
 	}
 
@@ -1039,6 +1183,7 @@ static void set_indicator_parameters(uint8_t index, const char *indicator,
 		ag_ind[HFP_INDICATOR_CALL].index = index;
 		ag_ind[HFP_INDICATOR_CALL].min = min;
 		ag_ind[HFP_INDICATOR_CALL].max = max;
+		ag_ind[HFP_INDICATOR_CALL].cb = ciev_call_cb;
 		return;
 	}
 
@@ -1046,6 +1191,7 @@ static void set_indicator_parameters(uint8_t index, const char *indicator,
 		ag_ind[HFP_INDICATOR_CALLSETUP].index = index;
 		ag_ind[HFP_INDICATOR_CALLSETUP].min = min;
 		ag_ind[HFP_INDICATOR_CALLSETUP].max = max;
+		ag_ind[HFP_INDICATOR_CALLSETUP].cb = ciev_callsetup_cb;
 		return;
 	}
 
@@ -1053,6 +1199,7 @@ static void set_indicator_parameters(uint8_t index, const char *indicator,
 		ag_ind[HFP_INDICATOR_CALLHELD].index = index;
 		ag_ind[HFP_INDICATOR_CALLHELD].min = min;
 		ag_ind[HFP_INDICATOR_CALLHELD].max = max;
+		ag_ind[HFP_INDICATOR_CALLHELD].cb = ciev_callheld_cb;
 		return;
 	}
 
@@ -1060,6 +1207,7 @@ static void set_indicator_parameters(uint8_t index, const char *indicator,
 		ag_ind[HFP_INDICATOR_SIGNAL].index = index;
 		ag_ind[HFP_INDICATOR_SIGNAL].min = min;
 		ag_ind[HFP_INDICATOR_SIGNAL].max = max;
+		ag_ind[HFP_INDICATOR_SIGNAL].cb = ciev_signal_cb;
 		return;
 	}
 
@@ -1067,6 +1215,7 @@ static void set_indicator_parameters(uint8_t index, const char *indicator,
 		ag_ind[HFP_INDICATOR_ROAM].index = index;
 		ag_ind[HFP_INDICATOR_ROAM].min = min;
 		ag_ind[HFP_INDICATOR_ROAM].max = max;
+		ag_ind[HFP_INDICATOR_ROAM].cb = ciev_roam_cb;
 		return;
 	}
 
@@ -1074,6 +1223,7 @@ static void set_indicator_parameters(uint8_t index, const char *indicator,
 		ag_ind[HFP_INDICATOR_BATTCHG].index = index;
 		ag_ind[HFP_INDICATOR_BATTCHG].min = min;
 		ag_ind[HFP_INDICATOR_BATTCHG].max = max;
+		ag_ind[HFP_INDICATOR_BATTCHG].cb = ciev_battchg_cb;
 		return;
 	}
 
-- 
1.8.4


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

* [PATCH v2 09/15] android/handsfree-client: Send indicators val we got during SLC setup
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (7 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 08/15] android/handsfree-client: Add support for +CIEV events Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 10/15] android/handsfree-client: Add support to get operator name Lukasz Rymanowski
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

Once SLC is done, Android is ready to get indicators values.
---
 android/handsfree-client.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 50c5821..d3a3bd1 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -864,14 +864,24 @@ static void ciev_cb(struct hfp_context *context, void *user_data)
 
 static void slc_completed(struct device *dev)
 {
+	int i;
+	struct indicator *ag_ind;
+
 	DBG("");
 
+	ag_ind = dev->ag_ind;
+
 	device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED);
 
-	/*
-	 * TODO: Notify Android with indicators, register unsolicited result
-	 * handlers
-	 */
+	/* Notify Android with indicators */
+	for (i = 0; i < HFP_INDICATOR_LAST; i++) {
+		if (!ag_ind[i].cb)
+			continue;
+
+		ag_ind[i].cb(ag_ind[i].val);
+	}
+
+	/* TODO: register unsolicited results handlers */
 
 	hfp_hf_register(dev->hf, bvra_cb, "+BRVA", dev, NULL);
 	hfp_hf_register(dev->hf, vgm_cb, "+VGM", dev, NULL);
@@ -964,6 +974,7 @@ static void set_indicator_value(uint8_t index, unsigned int val,
 			continue;
 
 		ag_ind[i].val = val;
+		ag_ind[i].cb(val);
 		return;
 	}
 }
-- 
1.8.4


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

* [PATCH v2 10/15] android/handsfree-client: Add support to get operator name
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (8 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 09/15] android/handsfree-client: Send indicators val we got during SLC setup Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 11/15] android/handsfree-client: Send to AG that we do support long name Lukasz Rymanowski
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 52 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index d3a3bd1..6c318fc 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -623,10 +623,26 @@ done:
 
 static void handle_query_operator_name(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct device *dev;
+	uint8_t status;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS?"))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
 					HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME,
-					HAL_STATUS_UNSUPPORTED);
+					status);
 }
 
 static void handle_retrieve_subscr_info(const void *buf, uint16_t len)
@@ -862,6 +878,37 @@ static void ciev_cb(struct hfp_context *context, void *user_data)
 	}
 }
 
+static void cops_cb(struct hfp_context *context, void *user_data)
+{
+	uint8_t buf[IPC_MTU];
+	struct hal_ev_hf_client_operator_name *ev = (void *) buf;
+	char name[17];
+	unsigned int format;
+
+	DBG("");
+
+	/* Not interested in mode */
+	hfp_context_skip_field(context);
+
+	if (!hfp_context_get_number(context, &format))
+		return;
+
+	if (format != 0)
+		info("hf-client: Not correct string format in +COSP");
+
+	if (!hfp_context_get_string(context, name, sizeof(name))) {
+		error("hf-client: incorrect COPS response");
+		return;
+	}
+
+	ev->name_len = strlen(name) + 1;
+	memcpy(ev->name, name, ev->name_len);
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_HF_CLIENT_OPERATOR_NAME,
+					sizeof(*ev) + ev->name_len, ev);
+}
+
 static void slc_completed(struct device *dev)
 {
 	int i;
@@ -889,6 +936,7 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, brth_cb, "+BTRH", dev, NULL);
 	hfp_hf_register(dev->hf, clcc_cb, "+CLCC", dev, NULL);
 	hfp_hf_register(dev->hf, ciev_cb, "+CIEV", dev, NULL);
+	hfp_hf_register(dev->hf, cops_cb, "+COPS", dev, NULL);
 }
 
 static void slc_chld_cb(struct hfp_context *context, void *user_data)
-- 
1.8.4


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

* [PATCH v2 11/15] android/handsfree-client: Send to AG that we do support long name
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (9 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 10/15] android/handsfree-client: Add support to get operator name Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 12/15] android/handsfree-client: Retrieve subscriber number information Lukasz Rymanowski
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

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

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 6c318fc..b78294a 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -937,6 +937,9 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, clcc_cb, "+CLCC", dev, NULL);
 	hfp_hf_register(dev->hf, ciev_cb, "+CIEV", dev, NULL);
 	hfp_hf_register(dev->hf, cops_cb, "+COPS", dev, NULL);
+
+	if (!hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS=3,0"))
+		info("hf-client: Could not send AT+COPS=3,0");
 }
 
 static void slc_chld_cb(struct hfp_context *context, void *user_data)
-- 
1.8.4


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

* [PATCH v2 12/15] android/handsfree-client: Retrieve subscriber number information
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (10 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 11/15] android/handsfree-client: Send to AG that we do support long name Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 13/15] android/handsfree-client: Implement send DTMF codes Lukasz Rymanowski
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index b78294a..eb3e7c3 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -647,10 +647,26 @@ done:
 
 static void handle_retrieve_subscr_info(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct device *dev;
+	uint8_t status;
+
+	DBG("");
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+CNUM"))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
 					HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO,
-					HAL_STATUS_UNSUPPORTED);
+					status);
 }
 
 static void handle_send_dtmf(const void *buf, uint16_t len)
@@ -878,6 +894,52 @@ static void ciev_cb(struct hfp_context *context, void *user_data)
 	}
 }
 
+static void cnum_cb(struct hfp_context *context, void *user_data)
+{
+	uint8_t buf[IPC_MTU];
+	struct hal_ev_hf_client_subscriber_service_info *ev = (void *) buf;
+	char number[33];
+	unsigned int service;
+
+	DBG("");
+
+	/* Alpha field is empty string, just skip it */
+	hfp_context_skip_field(context);
+
+	if (!hfp_context_get_string(context, number, sizeof(number))) {
+		error("hf-client: Could not get number");
+		return;
+	}
+
+	/* Type is not used in Android */
+	hfp_context_skip_field(context);
+
+	/* Speed field is empty string, just skip it*/
+	hfp_context_skip_field(context);
+
+	if (!hfp_context_get_number(context, &service))
+		return;
+
+	ev->name_len = strlen(number) + 1;
+	memcpy(ev->name, number, ev->name_len);
+
+	switch (service) {
+	case 4:
+		ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_VOICE;
+		break;
+	case 5:
+		ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_FAX;
+		break;
+	default:
+		ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_UNKNOWN;
+		break;
+	}
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_CLIENT_SUBSCRIBER_SERVICE_INFO,
+					sizeof(*ev) + ev->name_len, ev);
+}
+
 static void cops_cb(struct hfp_context *context, void *user_data)
 {
 	uint8_t buf[IPC_MTU];
@@ -937,6 +999,7 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, clcc_cb, "+CLCC", dev, NULL);
 	hfp_hf_register(dev->hf, ciev_cb, "+CIEV", dev, NULL);
 	hfp_hf_register(dev->hf, cops_cb, "+COPS", dev, NULL);
+	hfp_hf_register(dev->hf, cnum_cb, "+CNUM", dev, NULL);
 
 	if (!hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS=3,0"))
 		info("hf-client: Could not send AT+COPS=3,0");
-- 
1.8.4


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

* [PATCH v2 13/15] android/handsfree-client: Implement send DTMF codes
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (11 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 12/15] android/handsfree-client: Retrieve subscriber number information Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 14/15] android/handsfree-client: Implement handling AT+BINP and +BINP Lukasz Rymanowski
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index eb3e7c3..79e96a1 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -671,9 +671,25 @@ done:
 
 static void handle_send_dtmf(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct hal_cmd_hf_client_send_dtmf *cmd = buf;
+	struct device *dev;
+	uint8_t status;
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+VTS=%c",
+							(char) cmd->tone))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-			HAL_OP_HF_CLIENT_SEND_DTMF, HAL_STATUS_UNSUPPORTED);
+					HAL_OP_HF_CLIENT_SEND_DTMF, status);
 }
 
 static void handle_get_last_vc_tag_num(const void *buf, uint16_t len)
-- 
1.8.4


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

* [PATCH v2 14/15] android/handsfree-client: Implement handling AT+BINP and +BINP
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (12 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 13/15] android/handsfree-client: Implement send DTMF codes Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19  9:43 ` [PATCH v2 15/15] android/handsfree-client: Implement codec negotiations Lukasz Rymanowski
  2014-11-19 14:09 ` [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Szymon Janc
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 79e96a1..fbee44e 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -694,10 +694,23 @@ done:
 
 static void handle_get_last_vc_tag_num(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct device *dev;
+	uint8_t status;
+
+	dev = find_default_device();
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BINP=1"))
+		status = HAL_STATUS_SUCCESS;
+	else
+		status = HAL_STATUS_FAILED;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-					HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM,
-					HAL_STATUS_UNSUPPORTED);
+			HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM, status);
 }
 
 static void disconnect_watch(void *user_data)
@@ -987,6 +1000,27 @@ static void cops_cb(struct hfp_context *context, void *user_data)
 					sizeof(*ev) + ev->name_len, ev);
 }
 
+static void binp_cb(struct hfp_context *context, void *user_data)
+{
+	uint8_t buf[IPC_MTU];
+	struct hal_ev_hf_client_last_void_call_tag_num *ev = (void *) buf;
+	char number[33];
+
+	DBG("");
+
+	if (!hfp_context_get_string(context, number, sizeof(number))) {
+		error("hf-client: incorrect COPS response");
+		return;
+	}
+
+	ev->number_len = strlen(number) + 1;
+	memcpy(ev->number, number, ev->number_len);
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+					HAL_EV_CLIENT_LAST_VOICE_CALL_TAG_NUM,
+					sizeof(*ev) + ev->number_len, ev);
+}
+
 static void slc_completed(struct device *dev)
 {
 	int i;
@@ -1016,6 +1050,7 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, ciev_cb, "+CIEV", dev, NULL);
 	hfp_hf_register(dev->hf, cops_cb, "+COPS", dev, NULL);
 	hfp_hf_register(dev->hf, cnum_cb, "+CNUM", dev, NULL);
+	hfp_hf_register(dev->hf, binp_cb, "+BINP", dev, NULL);
 
 	if (!hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS=3,0"))
 		info("hf-client: Could not send AT+COPS=3,0");
-- 
1.8.4


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

* [PATCH v2 15/15] android/handsfree-client: Implement codec negotiations
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (13 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 14/15] android/handsfree-client: Implement handling AT+BINP and +BINP Lukasz Rymanowski
@ 2014-11-19  9:43 ` Lukasz Rymanowski
  2014-11-19 14:09 ` [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Szymon Janc
  15 siblings, 0 replies; 17+ messages in thread
From: Lukasz Rymanowski @ 2014-11-19  9:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

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

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index fbee44e..c3d955e 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -116,6 +116,7 @@ struct device {
 	struct hfp_hf *hf;
 	uint8_t state;
 
+	uint8_t negotiated_codec;
 	uint32_t features;
 	struct hfp_codec codecs[2];
 
@@ -1021,6 +1022,55 @@ static void binp_cb(struct hfp_context *context, void *user_data)
 					sizeof(*ev) + ev->number_len, ev);
 }
 
+static bool is_codec_supported_localy(struct device *dev, uint8_t codec)
+{
+	int i;
+
+	for (i = 0; i < CODECS_COUNT; i++) {
+		if (dev->codecs[i].type != codec)
+			continue;
+
+		return dev->codecs[i].local_supported;
+	}
+
+	return false;
+}
+
+static void bcs_resp(enum hfp_result result, enum hfp_error cme_err,
+							void *user_data)
+{
+	if (result != HFP_RESULT_OK)
+		error("hf-client: Error on AT+BCS (err=%u)", result);
+}
+
+static void bcs_cb(struct hfp_context *context, void *user_data)
+{
+	struct device *dev = user_data;
+	unsigned int codec;
+	char codecs_string[8];
+
+	DBG("");
+
+	if (!hfp_context_get_number(context, &codec))
+		goto failed;
+
+	if (!is_codec_supported_localy(dev, codec))
+		goto failed;
+
+	dev->negotiated_codec = codec;
+
+	hfp_hf_send_command(dev->hf, bcs_resp, dev, "AT+BCS=%d", codec);
+
+	return;
+
+failed:
+	error("hf-client: Could not get codec");
+
+	get_local_codecs_string(dev, codecs_string, sizeof(codecs_string));
+
+	hfp_hf_send_command(dev->hf, bcs_resp, dev, "AT+BCS=%s", codecs_string);
+}
+
 static void slc_completed(struct device *dev)
 {
 	int i;
@@ -1051,6 +1101,7 @@ static void slc_completed(struct device *dev)
 	hfp_hf_register(dev->hf, cops_cb, "+COPS", dev, NULL);
 	hfp_hf_register(dev->hf, cnum_cb, "+CNUM", dev, NULL);
 	hfp_hf_register(dev->hf, binp_cb, "+BINP", dev, NULL);
+	hfp_hf_register(dev->hf, bcs_cb, "+BCS", dev, NULL);
 
 	if (!hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS=3,0"))
 		info("hf-client: Could not send AT+COPS=3,0");
-- 
1.8.4


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

* Re: [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF
  2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
                   ` (14 preceding siblings ...)
  2014-11-19  9:43 ` [PATCH v2 15/15] android/handsfree-client: Implement codec negotiations Lukasz Rymanowski
@ 2014-11-19 14:09 ` Szymon Janc
  15 siblings, 0 replies; 17+ messages in thread
From: Szymon Janc @ 2014-11-19 14:09 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth

Hi Łukasz,

On Wednesday 19 of November 2014 10:43:33 Lukasz Rymanowski wrote:
> In this set all mising signaling part is implemented.
> Tested on UPF 49 as well.
> 
> SCO part will come in next set.
> 
> v2:
> * Addressed Szymon comments
> * Added patch fixing index type in IPC call action command (01/15)
> 
> Lukasz Rymanowski (15):
>   android/handsfree-client: Fix index type in call action command
>   android/handsfree-client: Add handle start/stop vr
>   android/handsfree-client: Add volume control handling
>   android/handsfree-client: Add handling dial command
>   android/handsfree-client: Add call action implementation
>   android/handsfree-client: Implement query current calls
>   android/handsfree-client: Add handling +CLCC
>   android/handsfree-client: Add support for +CIEV events
>   android/handsfree-client: Send indicators val we got during SLC setup
>   android/handsfree-client: Add support to get operator name
>   android/handsfree-client: Send to AG that we do support long name
>   android/handsfree-client: Retrieve subscriber number information
>   android/handsfree-client: Implement send DTMF codes
>   android/handsfree-client: Implement handling AT+BINP and +BINP
>   android/handsfree-client: Implement codec negotiations
> 
>  android/hal-msg.h          |   2 +-
>  android/handsfree-client.c | 833 +++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 802 insertions(+), 33 deletions(-)
> 

Patch-set applied (with some small fixes), thanks.

-- 
Best regards, 
Szymon Janc

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

end of thread, other threads:[~2014-11-19 14:09 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-19  9:43 [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 01/15] android/handsfree-client: Fix index type in call action command Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 02/15] android/handsfree-client: Add handle start/stop vr Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 03/15] android/handsfree-client: Add volume control handling Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 04/15] android/handsfree-client: Add handling dial command Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 05/15] android/handsfree-client: Add call action implementation Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 06/15] android/handsfree-client: Implement query current calls Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 07/15] android/handsfree-client: Add handling +CLCC Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 08/15] android/handsfree-client: Add support for +CIEV events Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 09/15] android/handsfree-client: Send indicators val we got during SLC setup Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 10/15] android/handsfree-client: Add support to get operator name Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 11/15] android/handsfree-client: Send to AG that we do support long name Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 12/15] android/handsfree-client: Retrieve subscriber number information Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 13/15] android/handsfree-client: Implement send DTMF codes Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 14/15] android/handsfree-client: Implement handling AT+BINP and +BINP Lukasz Rymanowski
2014-11-19  9:43 ` [PATCH v2 15/15] android/handsfree-client: Implement codec negotiations Lukasz Rymanowski
2014-11-19 14:09 ` [PATCH v2 00/15] android/handsfree-clien: Second set of HFP HF Szymon Janc

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