[PATCH 3/3] Add list_calls and send_dtmf support for HFP voicecall driver

Zhenhua Zhang zhenhua.zhang at intel.com
Fri Nov 6 23:26:43 PST 2009


send_dtmf doesn't allow double quotes in AT commands.
---
 drivers/hfpmodem/voicecall.c |  109
+++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/drivers/hfpmodem/voicecall.c b/drivers/hfpmodem/voicecall.c
index fabcd6d..24841da 100644
--- a/drivers/hfpmodem/voicecall.c
+++ b/drivers/hfpmodem/voicecall.c
@@ -454,6 +454,76 @@ static gboolean poll_clcc(gpointer user_data)
 	return FALSE;
 }
 
+static void list_calls_cb(gboolean ok, GAtResult *result, gpointer
user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_call_list_cb_t cb = cbd->cb;
+	struct ofono_error error;
+	GSList *calls = NULL;
+	GSList *l;
+	struct ofono_call *list;
+	int num = 0;
+
+	dump_response("list_calls_cb", ok, result);
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok) {
+		cb(&error, 0, NULL, cbd->data);
+		goto out;
+	}
+
+	calls = parse_clcc(result);
+
+	if (calls == NULL) {
+		CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data);
+		goto out;
+	}
+
+	list = g_try_new0(struct ofono_call, g_slist_length(calls));
+
+	if (!list) {
+		CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data);
+		goto out;
+	}
+
+	for (num = 0, l = calls; l; l = l->next, num++)
+		memcpy(&list[num], l->data, sizeof(struct ofono_call));
+
+	cb(&error, num, list, cbd->data);
+
+	g_free(list);
+
+out:
+	g_slist_foreach(calls, (GFunc) g_free, NULL);
+	g_slist_free(calls);
+}
+
+static void hfp_list_calls(struct ofono_voicecall *vc,
ofono_call_list_cb_t cb,
+				void *data)
+{
+	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+	struct cb_data *cbd = cb_data_new(cb, data);
+
+	if (!cbd)
+		goto error;
+
+	if (!(vd->ag_features & AG_FEATURE_ENHANCED_CALL_STATUS)) {
+		ofono_error("The phone doesn't support enhanced "
+				"call status control to get list of calls");
+		goto error;
+	}
+
+	if (g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
+				list_calls_cb, cbd, g_free) > 0)
+		return;
+
+error:
+	if (cbd)
+		g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, 0, NULL, data);
+}
+
 static gboolean check_mpty_feature(struct ofono_voicecall *vc,
 				unsigned int feature,
 				ofono_voicecall_cb_t cb, void *data)
@@ -644,6 +714,41 @@ static void hfp_transfer(struct ofono_voicecall
*vc,
 		hfp_template("AT+CHLD=4", vc, generic_cb, transfer, cb, data);
 }
 
+static void hfp_send_dtmf(struct ofono_voicecall *vc, const char *dtmf,
+			ofono_voicecall_cb_t cb, void *data)
+{
+	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+	struct change_state_req *req = g_try_new0(struct change_state_req, 1);
+	char *buf;
+
+	if (!req)
+		goto error;
+
+	req->vc = vc;
+	req->cb = cb;
+	req->data = data;
+	req->affected_types = 0;
+
+	/* strlen("AT+VTS=") = 7 */
+	buf = g_try_new(char, strlen(dtmf) + 7);
+
+	if (!buf)
+		goto error;
+
+	sprintf(buf, "AT+VTS=%s", dtmf);
+
+	g_at_chat_send(vd->chat, buf, none_prefix,
+				generic_cb, req, g_free);
+
+	g_free(buf);
+
+	return;
+
+error:
+	CALLBACK_WITH_FAILURE(cb, data);
+	return;
+}
+
 static void ring_notify(GAtResult *result, gpointer user_data)
 {
 	struct ofono_voicecall *vc = user_data;
@@ -1039,7 +1144,7 @@ static struct ofono_voicecall_driver driver = {
 	.dial			= hfp_dial,
 	.answer			= hfp_answer,
 	.hangup			= hfp_hangup,
-	.list_calls		= NULL,
+	.list_calls		= hfp_list_calls,
 	.hold_all_active	= hfp_hold_all_active,
 	.release_all_held	= hfp_release_all_held,
 	.set_udub		= hfp_set_udub,
@@ -1050,7 +1155,7 @@ static struct ofono_voicecall_driver driver = {
 	.transfer		= hfp_transfer,
 	.deflect		= NULL,
 	.swap_without_accept	= NULL,
-	.send_tones		= NULL
+	.send_tones		= hfp_send_dtmf
 };
 
 void hfp_voicecall_init()
-- 
1.6.2.5





More information about the ofono mailing list