All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] shared\hfp: Add support for HFP-HF
@ 2014-11-03  9:35 Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 01/10] shared/hfp: Rename hfp_gw_result to hfp_context Lukasz Rymanowski
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

This set is continuation of adding support for HFP-HF.
Most of the patches is refactor of handling hfp result.
No it is commong hfp_context which can be parsed by GW and HF
with API funtions hfp_context_*

There is also CME ERROR handling added and couple of unit test.

v2
* rebase
* Handled Marcin comment.
* Added two more patches for skipping field in hfp_context 

Lukasz Rymanowski (10):
  shared/hfp: Rename hfp_gw_result to hfp_context
  shared/hfp: Rename hfp_hf_result to common hfp_context
  shared/hfp: Rename functions operating on context
  shared/hfp: Add handling +CME ERROR to parser
  shared/hfp: Minor fix in container close function
  shared/hfp: Add hfp_context_get_range function
  unit/hfp: Add unit tests for parsing hfp_context
  unit/hfp: Add test for +CME ERROR: response
  shared/hfp: Add function to skip field in hfp_context
  unit/test-hfp: Test for skip hfp_context field

 android/handsfree.c | 184 ++++++++++++++++++++--------------------
 src/shared/hfp.c    | 237 +++++++++++++++++++++++++++++++++-------------------
 src/shared/hfp.h    |  35 ++++----
 unit/test-hfp.c     | 136 +++++++++++++++++++++++++++---
 4 files changed, 389 insertions(+), 203 deletions(-)

-- 
1.8.4


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

* [PATCH v2 01/10] shared/hfp: Rename hfp_gw_result to hfp_context
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 02/10] shared/hfp: Rename hfp_hf_result to common hfp_context Lukasz Rymanowski
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

hfp_context seems to be better name for data we get in the result of HFP
GW. Especially that we want to use same for HFP HF response data.
---
 android/handsfree.c | 149 ++++++++++++++++++++++++++--------------------------
 src/shared/hfp.c    | 129 +++++++++++++++++++++++----------------------
 src/shared/hfp.h    |  21 ++++----
 unit/test-hfp.c     |  10 ++--
 4 files changed, 156 insertions(+), 153 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index aaf4f7a..a0bd9dd 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -342,8 +342,8 @@ static void at_cmd_unknown(const char *command, void *user_data)
 			HAL_EV_HANDSFREE_UNKNOWN_AT, sizeof(*ev) + ev->len, ev);
 }
 
-static void at_cmd_vgm(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
-								void *user_data)
+static void at_cmd_vgm(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_volume ev;
@@ -353,10 +353,10 @@ static void at_cmd_vgm(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val > 15)
+		if (!hfp_gw_result_get_number(context, &val) || val > 15)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ev.type = HAL_HANDSFREE_VOLUME_TYPE_MIC;
@@ -377,8 +377,8 @@ static void at_cmd_vgm(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_vgs(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_volume ev;
@@ -388,10 +388,10 @@ static void at_cmd_vgs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val > 15)
+		if (!hfp_gw_result_get_number(context, &val) || val > 15)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ev.type = HAL_HANDSFREE_VOLUME_TYPE_SPEAKER;
@@ -412,21 +412,21 @@ static void at_cmd_vgs(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_cops(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	unsigned int val;
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val != 3)
+		if (!hfp_gw_result_get_number(context, &val) || val != 3)
 			break;
 
-		if (!hfp_gw_result_get_number(result, &val) || val != 0)
+		if (!hfp_gw_result_get_number(context, &val) || val != 0)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
@@ -443,8 +443,8 @@ static void at_cmd_cops(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_bia(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	unsigned int val, i, def;
@@ -462,7 +462,8 @@ static void at_cmd_bia(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		do {
 			def = (i < IND_COUNT) ? dev->inds[i].active : 0;
 
-			if (!hfp_gw_result_get_number_default(result, &val, def))
+			if (!hfp_gw_result_get_number_default(context, &val,
+									def))
 				goto failed;
 
 			if (val > 1)
@@ -472,7 +473,7 @@ static void at_cmd_bia(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 				tmp[i] = val || dev->inds[i].always_active;
 				i++;
 			}
-		} while (hfp_gw_result_has_next(result));
+		} while (hfp_gw_result_has_next(context));
 
 		for (i = 0; i < IND_COUNT; i++)
 			dev->inds[i].active = tmp[i];
@@ -489,8 +490,8 @@ failed:
 	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)
+static void at_cmd_a(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 
@@ -498,7 +499,7 @@ static void at_cmd_a(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -516,8 +517,8 @@ static void at_cmd_a(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_d(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	char buf[IPC_MTU];
@@ -528,7 +529,7 @@ static void at_cmd_d(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_unquoted_string(result,
+		if (!hfp_gw_result_get_unquoted_string(context,
 						(char *) ev->number, 255))
 			break;
 
@@ -560,8 +561,8 @@ static void at_cmd_d(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_ccwa(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	unsigned int val;
@@ -570,10 +571,10 @@ static void at_cmd_ccwa(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val > 1)
+		if (!hfp_gw_result_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		dev->ccwa_enabled = val;
@@ -589,8 +590,8 @@ static void at_cmd_ccwa(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_chup(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 
@@ -598,7 +599,7 @@ static void at_cmd_chup(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -616,8 +617,8 @@ static void at_cmd_chup(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_clcc(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 
@@ -625,7 +626,7 @@ static void at_cmd_clcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -640,8 +641,8 @@ static void at_cmd_clcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_cmee(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	unsigned int val;
@@ -650,10 +651,10 @@ static void at_cmd_cmee(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val > 1)
+		if (!hfp_gw_result_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		dev->cmee_enabled = val;
@@ -669,8 +670,8 @@ static void at_cmd_cmee(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_clip(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	unsigned int val;
@@ -679,10 +680,10 @@ static void at_cmd_clip(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val > 1)
+		if (!hfp_gw_result_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		dev->clip_enabled = val;
@@ -698,8 +699,8 @@ static void at_cmd_clip(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_vts(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_dtmf ev;
@@ -709,7 +710,7 @@ static void at_cmd_vts(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_unquoted_string(result, str, 2))
+		if (!hfp_gw_result_get_unquoted_string(context, str, 2))
 			break;
 
 		if (!((str[0] >= '0' && str[0] <= '9') ||
@@ -717,7 +718,7 @@ static void at_cmd_vts(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 				str[0] == '*' || str[0] == '#'))
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ev.tone = str[0];
@@ -737,8 +738,8 @@ static void at_cmd_vts(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_cnum(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 
@@ -746,7 +747,7 @@ static void at_cmd_cnum(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -761,8 +762,8 @@ static void at_cmd_cnum(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_binp(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 
@@ -773,8 +774,8 @@ static void at_cmd_binp(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_bldn(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_dial ev;
@@ -783,7 +784,7 @@ static void at_cmd_bldn(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ev.number_len = 0;
@@ -800,8 +801,8 @@ static void at_cmd_bldn(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_bvra(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_vr_state ev;
@@ -811,10 +812,10 @@ static void at_cmd_bvra(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val > 1)
+		if (!hfp_gw_result_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		if (val)
@@ -834,8 +835,8 @@ static void at_cmd_bvra(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_nrec(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 	struct hal_ev_handsfree_nrec ev;
@@ -850,10 +851,10 @@ static void at_cmd_nrec(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		 * callback, but spec allows HF to only disable AG's NREC
 		 * feature for SLC duration. Follow spec here.
 		 */
-		if (!hfp_gw_result_get_number(result, &val) || val != 0)
+		if (!hfp_gw_result_get_number(context, &val) || val != 0)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_gw_result_has_next(context))
 			break;
 
 		ev.nrec = HAL_HANDSFREE_NREC_STOP;
@@ -861,7 +862,7 @@ static void at_cmd_nrec(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
 					HAL_EV_HANDSFREE_NREC, sizeof(ev), &ev);
 
-		/* Framework is not replying with result for AT+NREC */
+		/* Framework is not replying with context for AT+NREC */
 		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
 		return;
 	case HFP_GW_CMD_TYPE_READ:
@@ -873,8 +874,8 @@ static void at_cmd_nrec(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_bsir(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 
@@ -885,8 +886,8 @@ static void at_cmd_bsir(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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)
+static void at_cmd_btrh(struct hfp_context *context,
+				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct hf_device *dev = user_data;
 
@@ -1034,7 +1035,7 @@ static gboolean connect_sco_delayed(void *data)
 	return FALSE;
 }
 
-static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+static void at_cmd_bcc(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
@@ -1070,7 +1071,7 @@ static void at_cmd_bcc(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 	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,
+static void at_cmd_bcs(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
@@ -1113,7 +1114,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_ERROR);
 }
 
-static void at_cmd_ckpd(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+static void at_cmd_ckpd(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
@@ -1175,7 +1176,7 @@ static void register_post_slc_at(struct hf_device *dev)
 	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,
+static void at_cmd_cmer(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
@@ -1224,7 +1225,7 @@ static void at_cmd_cmer(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		hfp_gw_disconnect(dev->gw);
 }
 
-static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+static void at_cmd_cind(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
@@ -1285,7 +1286,7 @@ static void at_cmd_cind(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		hfp_gw_disconnect(dev->gw);
 }
 
-static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+static void at_cmd_brsf(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
@@ -1317,7 +1318,7 @@ static void at_cmd_brsf(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
 		hfp_gw_disconnect(dev->gw);
 }
 
-static void at_cmd_chld(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+static void at_cmd_chld(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
@@ -1370,7 +1371,7 @@ static struct hfp_codec *find_codec_by_type(struct hf_device *dev, uint8_t type)
 	return NULL;
 }
 
-static void at_cmd_bac(struct hfp_gw_result *result, enum hfp_gw_cmd_type type,
+static void at_cmd_bac(struct hfp_context *result, enum hfp_gw_cmd_type type,
 								void *user_data)
 {
 	struct hf_device *dev = user_data;
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 8f23ba2..565ddd3 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -94,7 +94,7 @@ struct cmd_handler {
 	hfp_result_func_t callback;
 };
 
-struct hfp_gw_result {
+struct hfp_context {
 	const char *data;
 	unsigned int offset;
 };
@@ -178,37 +178,37 @@ static void wakeup_writer(struct hfp_gw *hfp)
 	hfp->writer_active = true;
 }
 
-static void skip_whitespace(struct hfp_gw_result *result)
+static void skip_whitespace(struct hfp_context *context)
 {
-	while (result->data[result->offset] == ' ')
-		result->offset++;
+	while (context->data[context->offset] == ' ')
+		context->offset++;
 }
 
 static bool call_prefix_handler(struct hfp_gw *hfp, const char *data)
 {
 	struct cmd_handler *handler;
 	const char *separators = ";?=\0";
-	struct hfp_gw_result result;
+	struct hfp_context context;
 	enum hfp_gw_cmd_type type;
 	char lookup_prefix[18];
 	uint8_t pref_len = 0;
 	const char *prefix;
 	int i;
 
-	result.offset = 0;
-	result.data = data;
+	context.offset = 0;
+	context.data = data;
 
-	skip_whitespace(&result);
+	skip_whitespace(&context);
 
-	if (strlen(data + result.offset) < 3)
+	if (strlen(data + context.offset) < 3)
 		return false;
 
-	if (strncmp(data + result.offset, "AT", 2))
-		if (strncmp(data + result.offset, "at", 2))
+	if (strncmp(data + context.offset, "AT", 2))
+		if (strncmp(data + context.offset, "at", 2))
 			return false;
 
-	result.offset += 2;
-	prefix = data + result.offset;
+	context.offset += 2;
+	prefix = data + context.offset;
 
 	if (isalpha(prefix[0])) {
 		lookup_prefix[pref_len++] = toupper(prefix[0]);
@@ -222,17 +222,17 @@ static bool call_prefix_handler(struct hfp_gw *hfp, const char *data)
 	}
 
 	lookup_prefix[pref_len] = '\0';
-	result.offset += pref_len;
+	context.offset += pref_len;
 
 	if (lookup_prefix[0] == 'D') {
 		type = HFP_GW_CMD_TYPE_SET;
 		goto done;
 	}
 
-	if (data[result.offset] == '=') {
-		result.offset++;
-		if (data[result.offset] == '?') {
-			result.offset++;
+	if (data[context.offset] == '=') {
+		context.offset++;
+		if (data[context.offset] == '?') {
+			context.offset++;
 			type = HFP_GW_CMD_TYPE_TEST;
 		} else {
 			type = HFP_GW_CMD_TYPE_SET;
@@ -240,8 +240,8 @@ static bool call_prefix_handler(struct hfp_gw *hfp, const char *data)
 		goto done;
 	}
 
-	if (data[result.offset] == '?') {
-		result.offset++;
+	if (data[context.offset] == '?') {
+		context.offset++;
 		type = HFP_GW_CMD_TYPE_READ;
 		goto done;
 	}
@@ -255,98 +255,99 @@ done:
 	if (!handler)
 		return false;
 
-	handler->callback(&result, type, handler->user_data);
+	handler->callback(&context, type, handler->user_data);
 
 	return true;
 }
 
-static void next_field(struct hfp_gw_result *result)
+static void next_field(struct hfp_context *context)
 {
-	if (result->data[result->offset] == ',')
-		result->offset++;
+	if (context->data[context->offset] == ',')
+		context->offset++;
 }
 
-bool hfp_gw_result_get_number_default(struct hfp_gw_result *result,
+bool hfp_gw_result_get_number_default(struct hfp_context *context,
 						unsigned int *val,
 						unsigned int default_val)
 {
-	skip_whitespace(result);
+	skip_whitespace(context);
 
-	if (result->data[result->offset] == ',') {
+	if (context->data[context->offset] == ',') {
 		if (val)
 			*val = default_val;
 
-		result->offset++;
+		context->offset++;
 		return true;
 	}
 
-	return hfp_gw_result_get_number(result, val);
+	return hfp_gw_result_get_number(context, val);
 }
 
-bool hfp_gw_result_get_number(struct hfp_gw_result *result, unsigned int *val)
+bool hfp_gw_result_get_number(struct hfp_context *context,
+							unsigned int *val)
 {
 	unsigned int i;
 	int tmp = 0;
 
-	skip_whitespace(result);
+	skip_whitespace(context);
 
-	i = result->offset;
+	i = context->offset;
 
-	while (result->data[i] >= '0' && result->data[i] <= '9')
-		tmp = tmp * 10 + result->data[i++] - '0';
+	while (context->data[i] >= '0' && context->data[i] <= '9')
+		tmp = tmp * 10 + context->data[i++] - '0';
 
-	if (i == result->offset)
+	if (i == context->offset)
 		return false;
 
 	if (val)
 		*val = tmp;
-	result->offset = i;
+	context->offset = i;
 
-	skip_whitespace(result);
-	next_field(result);
+	skip_whitespace(context);
+	next_field(context);
 
 	return true;
 }
 
-bool hfp_gw_result_open_container(struct hfp_gw_result *result)
+bool hfp_gw_result_open_container(struct hfp_context *context)
 {
-	skip_whitespace(result);
+	skip_whitespace(context);
 
 	/* The list shall be preceded by a left parenthesis "(") */
-	if (result->data[result->offset] != '(')
+	if (context->data[context->offset] != '(')
 		return false;
 
-	result->offset++;
+	context->offset++;
 
 	return true;
 }
 
-bool hfp_gw_result_close_container(struct hfp_gw_result *result)
+bool hfp_gw_result_close_container(struct hfp_context *context)
 {
-	skip_whitespace(result);
+	skip_whitespace(context);
 
 	/* The list shall be followed by a right parenthesis (")" V250 5.7.3.1*/
-	if (result->data[result->offset] != ')')
+	if (context->data[context->offset] != ')')
 		return false;
 
-	result->offset++;
+	context->offset++;
 
 	return true;
 }
 
-bool hfp_gw_result_get_string(struct hfp_gw_result *result, char *buf,
+bool hfp_gw_result_get_string(struct hfp_context *context, char *buf,
 								uint8_t len)
 {
 	int i = 0;
-	const char *data = result->data;
+	const char *data = context->data;
 	unsigned int offset;
 
-	skip_whitespace(result);
+	skip_whitespace(context);
 
-	if (data[result->offset] != '"')
+	if (data[context->offset] != '"')
 		return false;
 
-	offset = result->offset;
+	offset = context->offset;
 	offset++;
 
 	while (data[offset] != '\0' && data[offset] != '"') {
@@ -367,29 +368,29 @@ bool hfp_gw_result_get_string(struct hfp_gw_result *result, char *buf,
 	else
 		return false;
 
-	result->offset = offset;
+	context->offset = offset;
 
-	skip_whitespace(result);
-	next_field(result);
+	skip_whitespace(context);
+	next_field(context);
 
 	return true;
 }
 
-bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
-								uint8_t len)
+bool hfp_gw_result_get_unquoted_string(struct hfp_context *context,
+							char *buf, uint8_t len)
 {
-	const char *data = result->data;
+	const char *data = context->data;
 	unsigned int offset;
 	int i = 0;
 	char c;
 
-	skip_whitespace(result);
+	skip_whitespace(context);
 
-	c = data[result->offset];
+	c = data[context->offset];
 	if (c == '"' || c == ')' || c == '(')
 		return false;
 
-	offset = result->offset;
+	offset = context->offset;
 
 	while (data[offset] != '\0' && data[offset] != ',' &&
 							data[offset] != ')') {
@@ -405,16 +406,16 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
 
 	buf[i] = '\0';
 
-	result->offset = offset;
+	context->offset = offset;
 
-	next_field(result);
+	next_field(context);
 
 	return true;
 }
 
-bool hfp_gw_result_has_next(struct hfp_gw_result *result)
+bool hfp_gw_result_has_next(struct hfp_context *context)
 {
-	return result->data[result->offset] != '\0';
+	return context->data[context->offset] != '\0';
 }
 
 static void process_input(struct hfp_gw *hfp)
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 1467c62..998525c 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -69,9 +69,9 @@ enum hfp_gw_cmd_type {
 	HFP_GW_CMD_TYPE_COMMAND
 };
 
-struct hfp_gw_result;
+struct hfp_context;
 
-typedef void (*hfp_result_func_t)(struct hfp_gw_result *result,
+typedef void (*hfp_result_func_t)(struct hfp_context *context,
 				enum hfp_gw_cmd_type type, void *user_data);
 
 typedef void (*hfp_destroy_func_t)(void *user_data);
@@ -115,17 +115,18 @@ bool hfp_gw_register(struct hfp_gw *hfp, hfp_result_func_t callback,
 						hfp_destroy_func_t destroy);
 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,
+bool hfp_gw_result_get_number(struct hfp_context *context,
+							unsigned int *val);
+bool hfp_gw_result_get_number_default(struct hfp_context *context,
 						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,
+bool hfp_gw_result_open_container(struct hfp_context *context);
+bool hfp_gw_result_close_container(struct hfp_context *context);
+bool hfp_gw_result_get_string(struct hfp_context *context, 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);
+bool hfp_gw_result_get_unquoted_string(struct hfp_context *context,
+						char *buf, uint8_t len);
+bool hfp_gw_result_has_next(struct hfp_context *context);
 
 struct hfp_hf_result;
 
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index c11a424..6e58204 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -206,7 +206,7 @@ static void cmd_handler(const char *command, void *user_data)
 	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
 }
 
-static void prefix_handler(struct hfp_gw_result *result,
+static void prefix_handler(struct hfp_context *result,
 				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct context *context = user_data;
@@ -358,7 +358,7 @@ static void test_fragmented(gconstpointer data)
 	execute_context(context);
 }
 
-static void check_ustring_1(struct hfp_gw_result *result,
+static void check_ustring_1(struct hfp_context *result,
 				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct context *context = user_data;
@@ -385,7 +385,7 @@ static void check_ustring_1(struct hfp_gw_result *result,
 	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
 }
 
-static void check_ustring_2(struct hfp_gw_result *result,
+static void check_ustring_2(struct hfp_context *result,
 				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct context *context = user_data;
@@ -405,7 +405,7 @@ static void check_ustring_2(struct hfp_gw_result *result,
 	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
 }
 
-static void check_string_1(struct hfp_gw_result *result,
+static void check_string_1(struct hfp_context *result,
 				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct context *context = user_data;
@@ -433,7 +433,7 @@ static void check_string_1(struct hfp_gw_result *result,
 	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
 }
 
-static void check_string_2(struct hfp_gw_result *result,
+static void check_string_2(struct hfp_context *result,
 				enum hfp_gw_cmd_type type, void *user_data)
 {
 	struct context *context = user_data;
-- 
1.8.4


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

* [PATCH v2 02/10] shared/hfp: Rename hfp_hf_result to common hfp_context
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 01/10] shared/hfp: Rename hfp_gw_result to hfp_context Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 03/10] shared/hfp: Rename functions operating on context Lukasz Rymanowski
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 src/shared/hfp.c | 29 ++++++++++++-----------------
 src/shared/hfp.h |  4 +---
 unit/test-hfp.c  |  4 ++--
 3 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 565ddd3..f3f75ab 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -99,14 +99,9 @@ struct hfp_context {
 	unsigned int offset;
 };
 
-struct hfp_hf_result {
-	const char *data;
-	unsigned int offset;
-};
-
 struct cmd_response {
 	hfp_response_func_t resp_cb;
-	struct hfp_hf_result *response;
+	struct hfp_context *response;
 	char *resp_data;
 	void *user_data;
 };
@@ -903,10 +898,10 @@ static void hf_write_watch_destroy(void *user_data)
 	hfp->writer_active = false;
 }
 
-static void hf_skip_whitespace(struct hfp_hf_result *result)
+static void hf_skip_whitespace(struct hfp_context *context)
 {
-	while (result->data[result->offset] == ' ')
-		result->offset++;
+	while (context->data[context->offset] == ' ')
+		context->offset++;
 }
 
 static bool is_response(const char *prefix, enum hfp_result *result)
@@ -968,22 +963,22 @@ static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
 {
 	struct event_handler *handler;
 	const char *separators = ";:\0";
-	struct hfp_hf_result result_data;
+	struct hfp_context context;
 	enum hfp_result result;
 	char lookup_prefix[18];
 	uint8_t pref_len = 0;
 	const char *prefix;
 	int i;
 
-	result_data.offset = 0;
-	result_data.data = data;
+	context.offset = 0;
+	context.data = data;
 
-	hf_skip_whitespace(&result_data);
+	hf_skip_whitespace(&context);
 
-	if (strlen(data + result_data.offset) < 2)
+	if (strlen(data + context.offset) < 2)
 		return;
 
-	prefix = data + result_data.offset;
+	prefix = data + context.offset;
 
 	pref_len = strcspn(prefix, separators);
 	if (pref_len > 17 || pref_len < 2)
@@ -993,7 +988,7 @@ static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
 		lookup_prefix[i] = toupper(prefix[i]);
 
 	lookup_prefix[pref_len] = '\0';
-	result_data.offset += pref_len + 1;
+	context.offset += pref_len + 1;
 
 	if (is_response(lookup_prefix, &result)) {
 		struct cmd_response *cmd;
@@ -1016,7 +1011,7 @@ static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
 	if (!handler)
 		return;
 
-	handler->callback(&result_data, handler->user_data);
+	handler->callback(&context, handler->user_data);
 }
 
 static char *find_cr_lf(char *str, size_t len)
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 998525c..6bb6d35 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -128,9 +128,7 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_context *context,
 						char *buf, uint8_t len);
 bool hfp_gw_result_has_next(struct hfp_context *context);
 
-struct hfp_hf_result;
-
-typedef void (*hfp_hf_result_func_t)(struct hfp_hf_result *result,
+typedef void (*hfp_hf_result_func_t)(struct hfp_context *context,
 							void *user_data);
 
 typedef void (*hfp_response_func_t)(enum hfp_result result, void *user_data);
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 6e58204..f6bbe2b 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -469,7 +469,7 @@ static void test_hf_init(gconstpointer data)
 
 static bool unsolicited_resp = false;
 
-static void hf_unsolicited_resp_cb(struct hfp_hf_result *result,
+static void hf_unsolicited_resp_cb(struct hfp_context *context,
 							void *user_data) {
 	unsolicited_resp = true;
 }
@@ -526,7 +526,7 @@ static void test_hf_send_command(gconstpointer data)
 	execute_context(context);
 }
 
-static void hf_result_handler(struct hfp_hf_result *result,
+static void hf_result_handler(struct hfp_context *result,
 							void *user_data)
 {
 	struct context *context = user_data;
-- 
1.8.4


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

* [PATCH v2 03/10] shared/hfp: Rename functions operating on context
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 01/10] shared/hfp: Rename hfp_gw_result to hfp_context Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 02/10] shared/hfp: Rename hfp_hf_result to common hfp_context Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 04/10] shared/hfp: Add handling +CME ERROR to parser Lukasz Rymanowski
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree.c | 91 ++++++++++++++++++++++++++---------------------------
 src/shared/hfp.c    | 16 +++++-----
 src/shared/hfp.h    | 14 ++++-----
 unit/test-hfp.c     |  8 ++---
 4 files changed, 64 insertions(+), 65 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index a0bd9dd..3aa4522 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -353,10 +353,10 @@ static void at_cmd_vgm(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(context, &val) || val > 15)
+		if (!hfp_context_get_number(context, &val) || val > 15)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ev.type = HAL_HANDSFREE_VOLUME_TYPE_MIC;
@@ -388,10 +388,10 @@ static void at_cmd_vgs(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(context, &val) || val > 15)
+		if (!hfp_context_get_number(context, &val) || val > 15)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ev.type = HAL_HANDSFREE_VOLUME_TYPE_SPEAKER;
@@ -420,13 +420,13 @@ static void at_cmd_cops(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(context, &val) || val != 3)
+		if (!hfp_context_get_number(context, &val) || val != 3)
 			break;
 
-		if (!hfp_gw_result_get_number(context, &val) || val != 0)
+		if (!hfp_context_get_number(context, &val) || val != 0)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
@@ -462,8 +462,7 @@ static void at_cmd_bia(struct hfp_context *context,
 		do {
 			def = (i < IND_COUNT) ? dev->inds[i].active : 0;
 
-			if (!hfp_gw_result_get_number_default(context, &val,
-									def))
+			if (!hfp_context_get_number_default(context, &val, def))
 				goto failed;
 
 			if (val > 1)
@@ -473,7 +472,7 @@ static void at_cmd_bia(struct hfp_context *context,
 				tmp[i] = val || dev->inds[i].always_active;
 				i++;
 			}
-		} while (hfp_gw_result_has_next(context));
+		} while (hfp_context_has_next(context));
 
 		for (i = 0; i < IND_COUNT; i++)
 			dev->inds[i].active = tmp[i];
@@ -499,7 +498,7 @@ static void at_cmd_a(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -529,7 +528,7 @@ static void at_cmd_d(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_unquoted_string(context,
+		if (!hfp_context_get_unquoted_string(context,
 						(char *) ev->number, 255))
 			break;
 
@@ -571,10 +570,10 @@ static void at_cmd_ccwa(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(context, &val) || val > 1)
+		if (!hfp_context_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		dev->ccwa_enabled = val;
@@ -599,7 +598,7 @@ static void at_cmd_chup(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -626,7 +625,7 @@ static void at_cmd_clcc(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -651,10 +650,10 @@ static void at_cmd_cmee(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(context, &val) || val > 1)
+		if (!hfp_context_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		dev->cmee_enabled = val;
@@ -680,10 +679,10 @@ static void at_cmd_clip(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(context, &val) || val > 1)
+		if (!hfp_context_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		dev->clip_enabled = val;
@@ -710,7 +709,7 @@ static void at_cmd_vts(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_unquoted_string(context, str, 2))
+		if (!hfp_context_get_unquoted_string(context, str, 2))
 			break;
 
 		if (!((str[0] >= '0' && str[0] <= '9') ||
@@ -718,7 +717,7 @@ static void at_cmd_vts(struct hfp_context *context,
 				str[0] == '*' || str[0] == '#'))
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ev.tone = str[0];
@@ -747,7 +746,7 @@ static void at_cmd_cnum(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -784,7 +783,7 @@ static void at_cmd_bldn(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_COMMAND:
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ev.number_len = 0;
@@ -812,10 +811,10 @@ static void at_cmd_bvra(struct hfp_context *context,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(context, &val) || val > 1)
+		if (!hfp_context_get_number(context, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		if (val)
@@ -851,10 +850,10 @@ static void at_cmd_nrec(struct hfp_context *context,
 		 * callback, but spec allows HF to only disable AG's NREC
 		 * feature for SLC duration. Follow spec here.
 		 */
-		if (!hfp_gw_result_get_number(context, &val) || val != 0)
+		if (!hfp_context_get_number(context, &val) || val != 0)
 			break;
 
-		if (hfp_gw_result_has_next(context))
+		if (hfp_context_has_next(context))
 			break;
 
 		ev.nrec = HAL_HANDSFREE_NREC_STOP;
@@ -1047,7 +1046,7 @@ static void at_cmd_bcc(struct hfp_context *result, enum hfp_gw_cmd_type type,
 		if (!codec_negotiation_supported(dev))
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_context_has_next(result))
 			break;
 
 		hfp_gw_send_result(dev->gw, HFP_RESULT_OK);
@@ -1081,10 +1080,10 @@ static void at_cmd_bcs(struct hfp_context *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val))
+		if (!hfp_context_get_number(result, &val))
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_context_has_next(result))
 			break;
 
 		/* Remote replied with other codec. Reply with error */
@@ -1124,10 +1123,10 @@ static void at_cmd_ckpd(struct hfp_context *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val != 200)
+		if (!hfp_context_get_number(result, &val) || val != 200)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_context_has_next(result))
 			break;
 
 		ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE,
@@ -1185,22 +1184,22 @@ static void at_cmd_cmer(struct hfp_context *result, enum hfp_gw_cmd_type type,
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
 		/* mode must be =3 */
-		if (!hfp_gw_result_get_number(result, &val) || val != 3)
+		if (!hfp_context_get_number(result, &val) || val != 3)
 			break;
 
 		/* keyp is don't care */
-		if (!hfp_gw_result_get_number(result, &val))
+		if (!hfp_context_get_number(result, &val))
 			break;
 
 		/* disp is don't care */
-		if (!hfp_gw_result_get_number(result, &val))
+		if (!hfp_context_get_number(result, &val))
 			break;
 
 		/* ind must be 0 or 1 */
-		if (!hfp_gw_result_get_number(result, &val) || val > 1)
+		if (!hfp_context_get_number(result, &val) || val > 1)
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_context_has_next(result))
 			break;
 
 		dev->indicators_enabled = val;
@@ -1294,10 +1293,10 @@ static void at_cmd_brsf(struct hfp_context *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &feat))
+		if (!hfp_context_get_number(result, &feat))
 			break;
 
-		if (hfp_gw_result_has_next(result))
+		if (hfp_context_has_next(result))
 			break;
 
 		/* TODO verify features */
@@ -1329,11 +1328,11 @@ static void at_cmd_chld(struct hfp_context *result, enum hfp_gw_cmd_type type,
 
 	switch (type) {
 	case HFP_GW_CMD_TYPE_SET:
-		if (!hfp_gw_result_get_number(result, &val) || val > 3)
+		if (!hfp_context_get_number(result, &val) || val > 3)
 			break;
 
 		/* No ECC support */
-		if (hfp_gw_result_has_next(result))
+		if (hfp_context_has_next(result))
 			break;
 
 		/* value match HAL type */
@@ -1392,23 +1391,23 @@ static void at_cmd_bac(struct hfp_context *result, enum hfp_gw_cmd_type type,
 		 * At least CVSD mandatory codec must exist
 		 * HFP V1.6 4.34.1
 		 */
-		if (!hfp_gw_result_get_number(result, &val) ||
+		if (!hfp_context_get_number(result, &val) ||
 							val != CODEC_ID_CVSD)
 			goto failed;
 
 		dev->codecs[CVSD_OFFSET].remote_supported = true;
 
-		if (hfp_gw_result_get_number(result, &val)) {
+		if (hfp_context_get_number(result, &val)) {
 			if (val != CODEC_ID_MSBC)
 				goto failed;
 
 			dev->codecs[MSBC_OFFSET].remote_supported = true;
 		}
 
-		while (hfp_gw_result_has_next(result)) {
+		while (hfp_context_has_next(result)) {
 			struct hfp_codec *codec;
 
-			if (!hfp_gw_result_get_number(result, &val))
+			if (!hfp_context_get_number(result, &val))
 				goto failed;
 
 			codec = find_codec_by_type(dev, val);
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index f3f75ab..037f63d 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -261,7 +261,7 @@ static void next_field(struct hfp_context *context)
 		context->offset++;
 }
 
-bool hfp_gw_result_get_number_default(struct hfp_context *context,
+bool hfp_context_get_number_default(struct hfp_context *context,
 						unsigned int *val,
 						unsigned int default_val)
 {
@@ -275,10 +275,10 @@ bool hfp_gw_result_get_number_default(struct hfp_context *context,
 		return true;
 	}
 
-	return hfp_gw_result_get_number(context, val);
+	return hfp_context_get_number(context, val);
 }
 
-bool hfp_gw_result_get_number(struct hfp_context *context,
+bool hfp_context_get_number(struct hfp_context *context,
 							unsigned int *val)
 {
 	unsigned int i;
@@ -304,7 +304,7 @@ bool hfp_gw_result_get_number(struct hfp_context *context,
 	return true;
 }
 
-bool hfp_gw_result_open_container(struct hfp_context *context)
+bool hfp_context_open_container(struct hfp_context *context)
 {
 	skip_whitespace(context);
 
@@ -317,7 +317,7 @@ bool hfp_gw_result_open_container(struct hfp_context *context)
 	return true;
 }
 
-bool hfp_gw_result_close_container(struct hfp_context *context)
+bool hfp_context_close_container(struct hfp_context *context)
 {
 	skip_whitespace(context);
 
@@ -330,7 +330,7 @@ bool hfp_gw_result_close_container(struct hfp_context *context)
 	return true;
 }
 
-bool hfp_gw_result_get_string(struct hfp_context *context, char *buf,
+bool hfp_context_get_string(struct hfp_context *context, char *buf,
 								uint8_t len)
 {
 	int i = 0;
@@ -371,7 +371,7 @@ bool hfp_gw_result_get_string(struct hfp_context *context, char *buf,
 	return true;
 }
 
-bool hfp_gw_result_get_unquoted_string(struct hfp_context *context,
+bool hfp_context_get_unquoted_string(struct hfp_context *context,
 							char *buf, uint8_t len)
 {
 	const char *data = context->data;
@@ -408,7 +408,7 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_context *context,
 	return true;
 }
 
-bool hfp_gw_result_has_next(struct hfp_context *context)
+bool hfp_context_has_next(struct hfp_context *context)
 {
 	return context->data[context->offset] != '\0';
 }
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 6bb6d35..4ab7150 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -115,18 +115,18 @@ bool hfp_gw_register(struct hfp_gw *hfp, hfp_result_func_t callback,
 						hfp_destroy_func_t destroy);
 bool hfp_gw_unregister(struct hfp_gw *hfp, const char *prefix);
 
-bool hfp_gw_result_get_number(struct hfp_context *context,
+bool hfp_context_get_number(struct hfp_context *context,
 							unsigned int *val);
-bool hfp_gw_result_get_number_default(struct hfp_context *context,
+bool hfp_context_get_number_default(struct hfp_context *context,
 						unsigned int *val,
 						unsigned int default_val);
-bool hfp_gw_result_open_container(struct hfp_context *context);
-bool hfp_gw_result_close_container(struct hfp_context *context);
-bool hfp_gw_result_get_string(struct hfp_context *context, char *buf,
+bool hfp_context_open_container(struct hfp_context *context);
+bool hfp_context_close_container(struct hfp_context *context);
+bool hfp_context_get_string(struct hfp_context *context, char *buf,
 								uint8_t len);
-bool hfp_gw_result_get_unquoted_string(struct hfp_context *context,
+bool hfp_context_get_unquoted_string(struct hfp_context *context,
 						char *buf, uint8_t len);
-bool hfp_gw_result_has_next(struct hfp_context *context);
+bool hfp_context_has_next(struct hfp_context *context);
 
 typedef void (*hfp_hf_result_func_t)(struct hfp_context *context,
 							void *user_data);
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index f6bbe2b..e992cf7 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -370,7 +370,7 @@ static void check_ustring_1(struct hfp_context *result,
 
 	g_assert(type == pdu->type);
 
-	g_assert(hfp_gw_result_get_unquoted_string(result, str, sizeof(str)));
+	g_assert(hfp_context_get_unquoted_string(result, str, sizeof(str)));
 
 	while (context->data->pdu_list[1].data[i] != '\r') {
 		g_assert(j < sizeof(str));
@@ -398,7 +398,7 @@ static void check_ustring_2(struct hfp_context *result,
 
 	g_assert(type == pdu->type);
 
-	g_assert(!hfp_gw_result_get_unquoted_string(result, str, 3));
+	g_assert(!hfp_context_get_unquoted_string(result, str, 3));
 
 	g_assert(str[3] == 'X');
 
@@ -417,7 +417,7 @@ static void check_string_1(struct hfp_context *result,
 
 	g_assert(type == pdu->type);
 
-	g_assert(hfp_gw_result_get_string(result, str, sizeof(str)));
+	g_assert(hfp_context_get_string(result, str, sizeof(str)));
 
 	while (context->data->pdu_list[1].data[i] != '\"') {
 		g_assert(j < sizeof(str));
@@ -446,7 +446,7 @@ static void check_string_2(struct hfp_context *result,
 
 	g_assert(type == pdu->type);
 
-	g_assert(!hfp_gw_result_get_string(result, str, 3));
+	g_assert(!hfp_context_get_string(result, str, 3));
 
 	g_assert(str[3] == 'X');
 
-- 
1.8.4


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

* [PATCH v2 04/10] shared/hfp: Add handling +CME ERROR to parser
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (2 preceding siblings ...)
  2014-11-03  9:35 ` [PATCH v2 03/10] shared/hfp: Rename functions operating on context Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 05/10] shared/hfp: Minor fix in container close function Lukasz Rymanowski
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 src/shared/hfp.c | 34 +++++++++++++++++++++++++++++++---
 src/shared/hfp.h |  5 ++++-
 unit/test-hfp.c  |  4 +++-
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 037f63d..e047574 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -904,40 +904,67 @@ static void hf_skip_whitespace(struct hfp_context *context)
 		context->offset++;
 }
 
-static bool is_response(const char *prefix, enum hfp_result *result)
+static bool is_response(const char *prefix, enum hfp_result *result,
+						enum hfp_error *cme_err,
+						struct hfp_context *context)
 {
 	if (strcmp(prefix, "OK") == 0) {
 		*result = HFP_RESULT_OK;
+		/*
+		 * Set cme_err to 0 as this is not valid when result is not
+		 * CME ERROR
+		 */
+		*cme_err = 0;
 		return true;
 	}
 
 	if (strcmp(prefix, "ERROR") == 0) {
 		*result = HFP_RESULT_ERROR;
+		*cme_err = 0;
 		return true;
 	}
 
 	if (strcmp(prefix, "NO CARRIER") == 0) {
 		*result = HFP_RESULT_NO_CARRIER;
+		*cme_err = 0;
 		return true;
 	}
 
 	if (strcmp(prefix, "NO ANSWER") == 0) {
 		*result = HFP_RESULT_NO_ANSWER;
+		*cme_err = 0;
 		return true;
 	}
 
 	if (strcmp(prefix, "BUSY") == 0) {
 		*result = HFP_RESULT_BUSY;
+		*cme_err = 0;
 		return true;
 	}
 
 	if (strcmp(prefix, "DELAYED") == 0) {
 		*result = HFP_RESULT_DELAYED;
+		*cme_err = 0;
 		return true;
 	}
 
 	if (strcmp(prefix, "BLACKLISTED") == 0) {
 		*result = HFP_RESULT_BLACKLISTED;
+		*cme_err = 0;
+		return true;
+	}
+
+	if (strcmp(prefix, "+CME ERROR") == 0) {
+		uint32_t val;
+
+		*result = HFP_RESULT_CME_ERROR;
+
+		if (hfp_context_get_number(context, &val) &&
+					val <= HFP_ERROR_NETWORK_NOT_ALLOWED)
+			*cme_err = val;
+		else
+			*cme_err = HFP_ERROR_AG_FAILURE;
+
 		return true;
 	}
 
@@ -965,6 +992,7 @@ static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
 	const char *separators = ";:\0";
 	struct hfp_context context;
 	enum hfp_result result;
+	enum hfp_error cme_err;
 	char lookup_prefix[18];
 	uint8_t pref_len = 0;
 	const char *prefix;
@@ -990,14 +1018,14 @@ static void hf_call_prefix_handler(struct hfp_hf *hfp, const char *data)
 	lookup_prefix[pref_len] = '\0';
 	context.offset += pref_len + 1;
 
-	if (is_response(lookup_prefix, &result)) {
+	if (is_response(lookup_prefix, &result, &cme_err, &context)) {
 		struct cmd_response *cmd;
 
 		cmd = queue_peek_head(hfp->cmd_queue);
 		if (!cmd)
 			return;
 
-		cmd->resp_cb(result, cmd->user_data);
+		cmd->resp_cb(result, cme_err, cmd->user_data);
 
 		queue_remove(hfp->cmd_queue, cmd);
 		free(cmd);
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 4ab7150..be7cbb8 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -34,6 +34,7 @@ enum hfp_result {
 	HFP_RESULT_NO_ANSWER	= 8,
 	HFP_RESULT_DELAYED	= 9,
 	HFP_RESULT_BLACKLISTED	= 10,
+	HFP_RESULT_CME_ERROR	= 11,
 };
 
 enum hfp_error {
@@ -131,7 +132,9 @@ bool hfp_context_has_next(struct hfp_context *context);
 typedef void (*hfp_hf_result_func_t)(struct hfp_context *context,
 							void *user_data);
 
-typedef void (*hfp_response_func_t)(enum hfp_result result, void *user_data);
+typedef void (*hfp_response_func_t)(enum hfp_result result,
+							enum hfp_error cme_err,
+							void *user_data);
 
 struct hfp_hf;
 
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index e992cf7..19250f6 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -475,6 +475,7 @@ static void hf_unsolicited_resp_cb(struct hfp_context *context,
 }
 
 static void hf_response_with_data(enum hfp_result res,
+							enum hfp_error cme_err,
 							void *user_data)
 {
 	struct context *context = user_data;
@@ -485,7 +486,8 @@ static void hf_response_with_data(enum hfp_result res,
 	hfp_hf_disconnect(context->hfp_hf);
 }
 
-static void hf_response_cb(enum hfp_result res, void *user_data)
+static void hf_response_cb(enum hfp_result res, enum hfp_error cme_err,
+							void *user_data)
 {
 	struct context *context = user_data;
 
-- 
1.8.4


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

* [PATCH v2 05/10] shared/hfp: Minor fix in container close function
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (3 preceding siblings ...)
  2014-11-03  9:35 ` [PATCH v2 04/10] shared/hfp: Add handling +CME ERROR to parser Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 06/10] shared/hfp: Add hfp_context_get_range function Lukasz Rymanowski
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

When closing container of hfp_context, we should try to move to next
field so offset is set correctly to next data.

Needed in case of parsing for example:
.+CIND: ("call",(0,1)),("callsetup",(0-3))")
---
 src/shared/hfp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index e047574..e375d27 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -327,6 +327,8 @@ bool hfp_context_close_container(struct hfp_context *context)
 
 	context->offset++;
 
+	next_field(context);
+
 	return true;
 }
 
-- 
1.8.4


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

* [PATCH v2 06/10] shared/hfp: Add hfp_context_get_range function
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (4 preceding siblings ...)
  2014-11-03  9:35 ` [PATCH v2 05/10] shared/hfp: Minor fix in container close function Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 07/10] unit/hfp: Add unit tests for parsing hfp_context Lukasz Rymanowski
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

This patch adds hfp_contex_get_range function which is useful in parsing
response like this : +CIND: ("battchr",(1-5))
---
 src/shared/hfp.c | 31 +++++++++++++++++++++++++++++++
 src/shared/hfp.h |  2 ++
 2 files changed, 33 insertions(+)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index e375d27..6c804f5 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -415,6 +415,37 @@ bool hfp_context_has_next(struct hfp_context *context)
 	return context->data[context->offset] != '\0';
 }
 
+bool hfp_context_get_range(struct hfp_context *context, uint32_t *min,
+								uint32_t *max)
+{
+	uint32_t l, h;
+	uint32_t start;
+
+	start = context->offset;
+
+	if (!hfp_context_get_number(context, &l))
+		goto failed;
+
+	if (context->data[context->offset] != '-')
+		goto failed;
+
+	context->offset++;
+
+	if (!hfp_context_get_number(context, &h))
+		goto failed;
+
+	*min = l;
+	*max = h;
+
+	next_field(context);
+
+	return true;
+
+failed:
+	context->offset = start;
+	return false;
+}
+
 static void process_input(struct hfp_gw *hfp)
 {
 	char *str, *ptr;
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index be7cbb8..5ba020d 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -127,6 +127,8 @@ bool hfp_context_get_string(struct hfp_context *context, char *buf,
 								uint8_t len);
 bool hfp_context_get_unquoted_string(struct hfp_context *context,
 						char *buf, uint8_t len);
+bool hfp_context_get_range(struct hfp_context *context, unsigned int *min,
+							unsigned int *max);
 bool hfp_context_has_next(struct hfp_context *context);
 
 typedef void (*hfp_hf_result_func_t)(struct hfp_context *context,
-- 
1.8.4


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

* [PATCH v2 07/10] unit/hfp: Add unit tests for parsing hfp_context
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (5 preceding siblings ...)
  2014-11-03  9:35 ` [PATCH v2 06/10] shared/hfp: Add hfp_context_get_range function Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:35 ` [PATCH v2 08/10] unit/hfp: Add test for +CME ERROR: response Lukasz Rymanowski
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

This patch adds:
/hfp/test_hf_context_parser_1
/hfp/test_hf_context_parser_2
---
 unit/test-hfp.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 19250f6..dd5dbcf 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -527,6 +527,54 @@ static void test_hf_send_command(gconstpointer data)
 
 	execute_context(context);
 }
+static void hf_chld_result_handler(struct hfp_context *hf_context,
+							void *user_data)
+{
+	struct context *context = user_data;
+	char str[3];
+
+	g_assert(hf_context);
+	g_assert(hfp_context_get_unquoted_string(hf_context, str,
+							sizeof(str)));
+	g_assert_cmpstr(str, ==, "1");
+	g_assert(hfp_context_get_unquoted_string(hf_context, str,
+							sizeof(str)));
+	g_assert_cmpstr(str, ==, "2x");
+
+	hfp_hf_disconnect(context->hfp_hf);
+}
+
+static void hf_clcc_result_handler(struct hfp_context *hf_context,
+							void *user_data)
+{
+	struct context *context = user_data;
+	char name[10];
+	uint32_t val1, val2;
+
+	g_assert(hf_context);
+	g_assert(hfp_context_open_container(hf_context));
+	g_assert(hfp_context_get_string(hf_context, name, sizeof(name)));
+	g_assert_cmpstr(name, ==, "call");
+	g_assert(hfp_context_open_container(hf_context));
+	g_assert(hfp_context_get_number(hf_context, &val1));
+	g_assert_cmpint(val1, ==, 0);
+	g_assert(hfp_context_get_number(hf_context, &val1));
+	g_assert_cmpint(val1, ==, 1);
+	g_assert(hfp_context_close_container(hf_context));
+	g_assert(hfp_context_close_container(hf_context));
+
+	g_assert(hfp_context_open_container(hf_context));
+	g_assert(hfp_context_get_string(hf_context, name, sizeof(name)));
+	g_assert_cmpstr(name, ==, "callsetup");
+	g_assert(hfp_context_open_container(hf_context));
+	g_assert(hfp_context_get_range(hf_context, &val1, &val2));
+	g_assert_cmpint(val1, ==, 0);
+	g_assert_cmpint(val2, ==, 3);
+	g_assert(hfp_context_close_container(hf_context));
+	g_assert(hfp_context_close_container(hf_context));
+
+	hfp_hf_disconnect(context->hfp_hf);
+}
 
 static void hf_result_handler(struct hfp_context *result,
 							void *user_data)
@@ -715,5 +763,23 @@ int main(int argc, char *argv[])
 			raw_pdu('\r', '\n', 'B', 'R', '\r', '\n'),
 			data_end());
 
+	define_hf_test("/hfp_hf/test_context_parser_1", test_hf_unsolicited,
+			hf_clcc_result_handler, NULL,
+			raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
+			frg_pdu('+', 'C', 'L', 'C', 'C', ':'),
+			frg_pdu('(', '\"', 'c', 'a', 'l', 'l', '\"'),
+			frg_pdu('(', '0', ',', '1', ')', ')', ','),
+			frg_pdu('(', '\"', 'c', 'a', 'l', 'l', 's', 'e', 't'),
+			frg_pdu('u', 'p', '\"', ',', '(', '0', '-', '3', ')'),
+			frg_pdu(')', '\r', '\n'),
+			data_end());
+
+	define_hf_test("/hfp_hf/test_context_parser_2", test_hf_unsolicited,
+			hf_chld_result_handler, NULL,
+			raw_pdu('+', 'C', 'H', 'L', 'D', '\0'),
+			frg_pdu('+', 'C', 'H', 'L', 'D', ':'),
+			frg_pdu('1', ',', '2', 'x', '\r', '\n'),
+			data_end());
+
 	return g_test_run();
 }
-- 
1.8.4


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

* [PATCH v2 08/10] unit/hfp: Add test for +CME ERROR: response
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (6 preceding siblings ...)
  2014-11-03  9:35 ` [PATCH v2 07/10] unit/hfp: Add unit tests for parsing hfp_context Lukasz Rymanowski
@ 2014-11-03  9:35 ` Lukasz Rymanowski
  2014-11-03  9:36 ` [PATCH v2 09/10] shared/hfp: Add function to skip field in hfp_context Lukasz Rymanowski
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 unit/test-hfp.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index dd5dbcf..617b336 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -486,6 +486,18 @@ static void hf_response_with_data(enum hfp_result res,
 	hfp_hf_disconnect(context->hfp_hf);
 }
 
+static void hf_cme_error_response_cb(enum hfp_result res,
+							enum hfp_error cme_err,
+							void *user_data)
+{
+	struct context *context = user_data;
+
+	g_assert_cmpint(res, ==, HFP_RESULT_CME_ERROR);
+	g_assert_cmpint(cme_err, ==, 30);
+
+	hfp_hf_disconnect(context->hfp_hf);
+}
+
 static void hf_response_cb(enum hfp_result res, enum hfp_error cme_err,
 							void *user_data)
 {
@@ -718,6 +730,14 @@ int main(int argc, char *argv[])
 			frg_pdu('\r', '\n', 'O', 'k', '\r', '\n'),
 			data_end());
 
+	define_hf_test("/hfp_hf/test_send_command_3", test_hf_send_command,
+			NULL, hf_cme_error_response_cb,
+			raw_pdu('A', 'T', '+', 'C', 'H', 'L', 'D', '=',
+								'1', '\0'),
+			frg_pdu('\r', '\n', '+', 'C', 'M', 'E', ' ', 'E'),
+			frg_pdu('R', 'R', 'O', 'R', ':', '3', '0', '\r', '\n'),
+			data_end());
+
 	define_hf_test("/hfp_hf/test_unsolicited_1", test_hf_unsolicited,
 			hf_result_handler, NULL,
 			raw_pdu('+', 'C', 'L', 'C', 'C', '\0'),
-- 
1.8.4


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

* [PATCH v2 09/10] shared/hfp: Add function to skip field in hfp_context
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (7 preceding siblings ...)
  2014-11-03  9:35 ` [PATCH v2 08/10] unit/hfp: Add test for +CME ERROR: response Lukasz Rymanowski
@ 2014-11-03  9:36 ` Lukasz Rymanowski
  2014-11-03  9:36 ` [PATCH v2 10/10] unit/test-hfp: Test for skip hfp_context field Lukasz Rymanowski
  2014-11-05  7:54 ` [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Szymon Janc
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

Some fields in AT commands are not used by HFP spec. When parsing such
commands it is convinient to just skip it without looking what is inside
there
---
 src/shared/hfp.c | 12 ++++++++++++
 src/shared/hfp.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 6c804f5..a35cb7b 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -415,6 +415,18 @@ bool hfp_context_has_next(struct hfp_context *context)
 	return context->data[context->offset] != '\0';
 }
 
+void hfp_context_skip_field(struct hfp_context *context)
+{
+	const char *data = context->data;
+	unsigned int offset = context->offset;
+
+	while (data[offset] != '\0' && data[offset] != ',')
+		offset++;
+
+	context->offset = offset;
+	next_field(context);
+}
+
 bool hfp_context_get_range(struct hfp_context *context, uint32_t *min,
 								uint32_t *max)
 {
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 5ba020d..2eb7838 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -130,6 +130,7 @@ bool hfp_context_get_unquoted_string(struct hfp_context *context,
 bool hfp_context_get_range(struct hfp_context *context, unsigned int *min,
 							unsigned int *max);
 bool hfp_context_has_next(struct hfp_context *context);
+void hfp_context_skip_field(struct hfp_context *context);
 
 typedef void (*hfp_hf_result_func_t)(struct hfp_context *context,
 							void *user_data);
-- 
1.8.4


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

* [PATCH v2 10/10] unit/test-hfp: Test for skip hfp_context field
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (8 preceding siblings ...)
  2014-11-03  9:36 ` [PATCH v2 09/10] shared/hfp: Add function to skip field in hfp_context Lukasz Rymanowski
@ 2014-11-03  9:36 ` Lukasz Rymanowski
  2014-11-05  7:54 ` [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Szymon Janc
  10 siblings, 0 replies; 12+ messages in thread
From: Lukasz Rymanowski @ 2014-11-03  9:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

This patch adds test:
/hfp_hf/test_context_skip_field
---
 unit/test-hfp.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 617b336..ef8a100 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -556,6 +556,23 @@ static void hf_chld_result_handler(struct hfp_context *hf_context,
 	hfp_hf_disconnect(context->hfp_hf);
 }
 
+static void hf_chld_skip_field(struct hfp_context *hf_context,
+							void *user_data)
+{
+	struct context *context = user_data;
+	char str[3];
+
+	g_assert(hf_context);
+
+	hfp_context_skip_field(hf_context);
+
+	g_assert(hfp_context_get_unquoted_string(hf_context, str,
+								sizeof(str)));
+	g_assert_cmpstr(str, ==, "2x");
+
+	hfp_hf_disconnect(context->hfp_hf);
+}
+
 static void hf_clcc_result_handler(struct hfp_context *hf_context,
 							void *user_data)
 {
@@ -801,5 +818,12 @@ int main(int argc, char *argv[])
 			frg_pdu('1', ',', '2', 'x', '\r', '\n'),
 			data_end());
 
+	define_hf_test("/hfp_hf/test_context_skip_field", test_hf_unsolicited,
+			hf_chld_skip_field, NULL,
+			raw_pdu('+', 'C', 'H', 'L', 'D', '\0'),
+			frg_pdu('+', 'C', 'H', 'L', 'D', ':'),
+			frg_pdu('1', ',', '2', 'x', '\r', '\n'),
+			data_end());
+
 	return g_test_run();
 }
-- 
1.8.4


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

* Re: [PATCH v2 00/10] shared\hfp: Add support for HFP-HF
  2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
                   ` (9 preceding siblings ...)
  2014-11-03  9:36 ` [PATCH v2 10/10] unit/test-hfp: Test for skip hfp_context field Lukasz Rymanowski
@ 2014-11-05  7:54 ` Szymon Janc
  10 siblings, 0 replies; 12+ messages in thread
From: Szymon Janc @ 2014-11-05  7:54 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth

Hi Łukasz,

On Monday 03 of November 2014 10:35:51 Lukasz Rymanowski wrote:
> This set is continuation of adding support for HFP-HF.
> Most of the patches is refactor of handling hfp result.
> No it is commong hfp_context which can be parsed by GW and HF
> with API funtions hfp_context_*
> 
> There is also CME ERROR handling added and couple of unit test.
> 
> v2
> * rebase
> * Handled Marcin comment.
> * Added two more patches for skipping field in hfp_context 
> 
> Lukasz Rymanowski (10):
>   shared/hfp: Rename hfp_gw_result to hfp_context
>   shared/hfp: Rename hfp_hf_result to common hfp_context
>   shared/hfp: Rename functions operating on context
>   shared/hfp: Add handling +CME ERROR to parser
>   shared/hfp: Minor fix in container close function
>   shared/hfp: Add hfp_context_get_range function
>   unit/hfp: Add unit tests for parsing hfp_context
>   unit/hfp: Add test for +CME ERROR: response
>   shared/hfp: Add function to skip field in hfp_context
>   unit/test-hfp: Test for skip hfp_context field
> 
>  android/handsfree.c | 184 ++++++++++++++++++++--------------------
>  src/shared/hfp.c    | 237 +++++++++++++++++++++++++++++++++-------------------
>  src/shared/hfp.h    |  35 ++++----
>  unit/test-hfp.c     | 136 +++++++++++++++++++++++++++---
>  4 files changed, 389 insertions(+), 203 deletions(-)
> 

All patches applied, thanks. 

-- 
Best regards, 
Szymon Janc

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

end of thread, other threads:[~2014-11-05  7:54 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-03  9:35 [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 01/10] shared/hfp: Rename hfp_gw_result to hfp_context Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 02/10] shared/hfp: Rename hfp_hf_result to common hfp_context Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 03/10] shared/hfp: Rename functions operating on context Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 04/10] shared/hfp: Add handling +CME ERROR to parser Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 05/10] shared/hfp: Minor fix in container close function Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 06/10] shared/hfp: Add hfp_context_get_range function Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 07/10] unit/hfp: Add unit tests for parsing hfp_context Lukasz Rymanowski
2014-11-03  9:35 ` [PATCH v2 08/10] unit/hfp: Add test for +CME ERROR: response Lukasz Rymanowski
2014-11-03  9:36 ` [PATCH v2 09/10] shared/hfp: Add function to skip field in hfp_context Lukasz Rymanowski
2014-11-03  9:36 ` [PATCH v2 10/10] unit/test-hfp: Test for skip hfp_context field Lukasz Rymanowski
2014-11-05  7:54 ` [PATCH v2 00/10] shared\hfp: Add support for HFP-HF Szymon Janc

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.