All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] doc: Play Tone command proposed d-bus API.
@ 2010-09-08 17:59 Andrzej Zaborowski
  2010-09-09 16:23 ` Marcel Holtmann
  0 siblings, 1 reply; 8+ messages in thread
From: Andrzej Zaborowski @ 2010-09-08 17:59 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1551 bytes --]

This is a version with the tone identified by a string based on irc
discussion, I leave the decision to you about which version to use.
---
 doc/stk-api.txt |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/doc/stk-api.txt b/doc/stk-api.txt
index d0dd740..14819a7 100644
--- a/doc/stk-api.txt
+++ b/doc/stk-api.txt
@@ -200,6 +200,38 @@ Methods		byte RequestSelection(string title, byte icon_id,
 
 			Possible Errors: [service].Error.SimToolkit.EndSession
 
+		void PlayTone(string tone, boolean loop,
+				string text, byte icon_id)
+
+			Tells the agent to play an audio tone.  A repeatable
+			tone is played for the duration of the method call
+			(until it is cancelled), otherwise it is played once
+			and the method should return.  The text parameter
+			contains an optional text to be displayed to the
+			user.  The following tones are defined:
+				"dial tone"
+				"busy"
+				"congestion"
+				"radio path acknowledge"
+				"radio path not available"
+				"error"
+				"call waiting"
+				"ringing tone"
+				"general beep"
+				"positive acknowledgement"
+				"negative acknowledgement"
+				"user ringing tone"
+				"user sms alert"
+				"critical" (high priority)
+				"vibrate"
+				"happy"
+				"sad"
+				"urgent action"
+				"question"
+				"message received"
+
+			Possible Errors: [service].Error.SimToolkit.EndSession
+
 		void Cancel()
 
 			Asks the agent to cancel any ongoing operation in
-- 
1.7.1.86.g0e460.dirty


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

* Re: [PATCH] doc: Play Tone command proposed d-bus API.
  2010-09-08 17:59 Andrzej Zaborowski
@ 2010-09-09 16:23 ` Marcel Holtmann
  2010-09-10  1:12   ` andrzej zaborowski
  0 siblings, 1 reply; 8+ messages in thread
From: Marcel Holtmann @ 2010-09-09 16:23 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2316 bytes --]

Hi Andrew,

> This is a version with the tone identified by a string based on irc
> discussion, I leave the decision to you about which version to use.
> ---
>  doc/stk-api.txt |   32 ++++++++++++++++++++++++++++++++
>  1 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/doc/stk-api.txt b/doc/stk-api.txt
> index d0dd740..14819a7 100644
> --- a/doc/stk-api.txt
> +++ b/doc/stk-api.txt
> @@ -200,6 +200,38 @@ Methods		byte RequestSelection(string title, byte icon_id,
>  
>  			Possible Errors: [service].Error.SimToolkit.EndSession
>  
> +		void PlayTone(string tone, boolean loop,
> +				string text, byte icon_id)
> +
> +			Tells the agent to play an audio tone.  A repeatable
> +			tone is played for the duration of the method call
> +			(until it is cancelled), otherwise it is played once
> +			and the method should return.  The text parameter
> +			contains an optional text to be displayed to the
> +			user.  The following tones are defined:

string sounds here more than reasonable. For the looping part we have to
clarify when to return from this method. For non repeating tones it is
pretty clear. It should return when playing the tone finished. For the
repeating one we can return right away, or after the first iteration has
played. That needs to be properly described in what to expect from the
agent.

Also has PlayTone and PlayLoop method calls considered to have a clearer
semantic separation?

> +				"dial tone"
> +				"busy"
> +				"congestion"
> +				"radio path acknowledge"
> +				"radio path not available"
> +				"error"
> +				"call waiting"
> +				"ringing tone"
> +				"general beep"
> +				"positive acknowledgement"
> +				"negative acknowledgement"
> +				"user ringing tone"
> +				"user sms alert"
> +				"critical" (high priority)
> +				"vibrate"
> +				"happy"
> +				"sad"
> +				"urgent action"
> +				"question"
> +				"message received"

I prefer to have them as "call-waiting" with a - in between. Space are
sort of a bad idea for constant type strings. And we do similar things
for "cs-preferred" etc. But essentially I agree that strings are way
better.

Can we also fix the typo in acknowledgment ;)

The alternate text string comes from the SIM Toolkit, right?

Regards

Marcel



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

* Re: [PATCH] doc: Play Tone command proposed d-bus API.
  2010-09-09 16:23 ` Marcel Holtmann
@ 2010-09-10  1:12   ` andrzej zaborowski
  0 siblings, 0 replies; 8+ messages in thread
From: andrzej zaborowski @ 2010-09-10  1:12 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3112 bytes --]

Hi,

On 9 September 2010 18:23, Marcel Holtmann <marcel@holtmann.org> wrote:
>> +                     Tells the agent to play an audio tone.  A repeatable
>> +                     tone is played for the duration of the method call
>> +                     (until it is cancelled), otherwise it is played once
>> +                     and the method should return.  The text parameter
>> +                     contains an optional text to be displayed to the
>> +                     user.  The following tones are defined:
>
> string sounds here more than reasonable. For the looping part we have to
> clarify when to return from this method. For non repeating tones it is
> pretty clear. It should return when playing the tone finished. For the
> repeating one we can return right away, or after the first iteration has
> played. That needs to be properly described in what to expect from the
> agent.

My idea is for it to wait until the call is cancelled, and not return.
 Otherwise we'll have to send the duration in a 0.1s units.

>
> Also has PlayTone and PlayLoop method calls considered to have a clearer
> semantic separation?

That's a good idea, I'll change it to use the separate methods unless
someone objects.

>
>> +                             "dial tone"
>> +                             "busy"
>> +                             "congestion"
>> +                             "radio path acknowledge"
>> +                             "radio path not available"
>> +                             "error"
>> +                             "call waiting"
>> +                             "ringing tone"
>> +                             "general beep"
>> +                             "positive acknowledgement"
>> +                             "negative acknowledgement"
>> +                             "user ringing tone"
>> +                             "user sms alert"
>> +                             "critical" (high priority)
>> +                             "vibrate"
>> +                             "happy"
>> +                             "sad"
>> +                             "urgent action"
>> +                             "question"
>> +                             "message received"
>
> I prefer to have them as "call-waiting" with a - in between. Space are
> sort of a bad idea for constant type strings. And we do similar things
> for "cs-preferred" etc.

Ok.

> Can we also fix the typo in acknowledgment ;)

I think I copied it from the spec (I'll check), the interwebs claims
both forms are correct :)

> The alternate text string comes from the SIM Toolkit, right?

Yes, it's actually the AlphaId / Icon to be displayed *while* playing,
not instead.

Regards,
Andrew

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

* [PATCH] doc: Play Tone command proposed d-bus API.
@ 2010-10-06 10:35 Andrzej Zaborowski
  2010-10-06 10:35 ` [PATCH 1/3] voicecall: __ofono_voicecall_send_tone internal api Andrzej Zaborowski
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Andrzej Zaborowski @ 2010-10-06 10:35 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1688 bytes --]

---
 doc/stk-api.txt |   40 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/doc/stk-api.txt b/doc/stk-api.txt
index 3b47819..f5b9ebc 100644
--- a/doc/stk-api.txt
+++ b/doc/stk-api.txt
@@ -203,6 +203,46 @@ Methods		byte RequestSelection(string title, byte icon_id,
 
 			Possible Errors: [service].Error.SimToolkit.EndSession
 
+		void PlayTone(string tone, string text, byte icon_id)
+
+			Tells the agent to play an audio tone once.  The
+			method should return once the tone is finished
+			playing.  The text parameter contains an optional
+			text to be displayed to the user.  The following
+			tones are defined:
+				"dial-tone"
+				"busy"
+				"congestion"
+				"radio-path-acknowledge"
+				"radio-path-not-available"
+				"error"
+				"call-waiting"
+				"ringing-tone"
+				"general-beep"
+				"positive-acknowledgement"
+				"negative-acknowledgement"
+				"user-ringing-tone"
+				"user-sms-alert"
+				"critical" (high priority)
+				"vibrate"
+				"happy"
+				"sad"
+				"urgent-action"
+				"question"
+				"message-received"
+
+			Possible Errors: [service].Error.SimToolkit.EndSession
+
+		void LoopTone(string tone, string text, byte icon_id)
+
+			Tells the agent to reproduce an audio tone in a
+			loop until the method call is cancelled.  See
+			PlayTone() above for the list of possible tone names.
+			The text parameter contains an optional text to
+			be displayed to the user.
+
+			Possible Errors: [service].Error.SimToolkit.EndSession
+
 		void Cancel()
 
 			Asks the agent to cancel any ongoing operation in
-- 
1.7.1.86.g0e460.dirty


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

* [PATCH 1/3] voicecall: __ofono_voicecall_send_tone internal api.
  2010-10-06 10:35 [PATCH] doc: Play Tone command proposed d-bus API Andrzej Zaborowski
@ 2010-10-06 10:35 ` Andrzej Zaborowski
  2010-10-06 10:35 ` [PATCH 2/3] stk: Handle the Send DTMF proactive command Andrzej Zaborowski
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Andrzej Zaborowski @ 2010-10-06 10:35 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1368 bytes --]

This provides a way for other atoms to send DTMF tones during a call.
---
 src/ofono.h     |    4 ++++
 src/voicecall.c |   16 ++++++++++++++++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/src/ofono.h b/src/ofono.h
index 6c7f649..6efd9ac 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -218,6 +218,10 @@ int __ofono_voicecall_dial(struct ofono_voicecall *vc,
 				ofono_voicecall_dial_cb_t cb, void *user_data);
 void __ofono_voicecall_dial_cancel(struct ofono_voicecall *vc);
 
+int __ofono_voicecall_send_tone(struct ofono_voicecall *vc,
+				const char *tone_str,
+				ofono_voicecall_cb_t cb, void *user_data);
+
 #include <ofono/sms.h>
 
 struct sms;
diff --git a/src/voicecall.c b/src/voicecall.c
index 2833e64..5feb2eb 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -2328,3 +2328,19 @@ void __ofono_voicecall_dial_cancel(struct ofono_voicecall *vc)
 
 	vc->dial_req->cb = NULL;
 }
+
+int __ofono_voicecall_send_tone(struct ofono_voicecall *vc,
+				const char *tone_str,
+				ofono_voicecall_cb_t cb, void *user_data)
+{
+	if (!vc->driver->send_tones)
+		return -ENOSYS;
+
+	/* Send DTMFs only if we have at least one connected call */
+	if (!voicecalls_can_dtmf(vc))
+		return -ENOENT;
+
+	vc->driver->send_tones(vc, tone_str, cb, user_data);
+
+	return 0;
+}
-- 
1.7.1.86.g0e460.dirty


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

* [PATCH 2/3] stk: Handle the Send DTMF proactive command.
  2010-10-06 10:35 [PATCH] doc: Play Tone command proposed d-bus API Andrzej Zaborowski
  2010-10-06 10:35 ` [PATCH 1/3] voicecall: __ofono_voicecall_send_tone internal api Andrzej Zaborowski
@ 2010-10-06 10:35 ` Andrzej Zaborowski
  2010-10-06 10:35 ` [PATCH 3/3][RfC] atmodem: Handle pauses in DTMF string Andrzej Zaborowski
  2010-10-07  0:05 ` [PATCH] doc: Play Tone command proposed d-bus API Denis Kenzior
  3 siblings, 0 replies; 8+ messages in thread
From: Andrzej Zaborowski @ 2010-10-06 10:35 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 6903 bytes --]

---
 src/stk.c |  168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 160 insertions(+), 8 deletions(-)

diff --git a/src/stk.c b/src/stk.c
index 80b4d23..84a22c9 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -70,7 +70,7 @@ struct ofono_stk {
 	gboolean respond_on_exit;
 	ofono_bool_t immediate_response;
 	guint remove_agent_source;
-	struct sms_submit_req *sms_submit_req;
+	struct extern_req *extern_req;
 	char *idle_mode_text;
 	struct timeval get_inkey_start_ts;
 };
@@ -83,7 +83,7 @@ struct envelope_op {
 			const unsigned char *data, int length);
 };
 
-struct sms_submit_req {
+struct extern_req {
 	struct ofono_stk *stk;
 	gboolean cancelled;
 };
@@ -660,7 +660,7 @@ static gboolean handle_command_more_time(const struct stk_command *cmd,
 
 static void send_sms_cancel(struct ofono_stk *stk)
 {
-	stk->sms_submit_req->cancelled = TRUE;
+	stk->extern_req->cancelled = TRUE;
 
 	if (!stk->pending_cmd->send_sms.alpha_id ||
 			!stk->pending_cmd->send_sms.alpha_id[0])
@@ -671,7 +671,7 @@ static void send_sms_cancel(struct ofono_stk *stk)
 
 static void send_sms_submit_cb(gboolean ok, void *data)
 {
-	struct sms_submit_req *req = data;
+	struct extern_req *req = data;
 	struct ofono_stk *stk = req->stk;
 	struct ofono_error failure = { .type = OFONO_ERROR_TYPE_FAILURE };
 	struct stk_response rsp;
@@ -697,6 +697,12 @@ static void send_sms_submit_cb(gboolean ok, void *data)
 		stk_command_cb(&failure, stk);
 }
 
+static void extern_req_start(struct ofono_stk *stk)
+{
+	stk->extern_req = g_new0(struct extern_req, 1);
+	stk->extern_req->stk = stk;
+}
+
 static gboolean handle_command_send_sms(const struct stk_command *cmd,
 					struct stk_response *rsp,
 					struct ofono_stk *stk)
@@ -715,15 +721,14 @@ static gboolean handle_command_send_sms(const struct stk_command *cmd,
 
 	sms = __ofono_atom_get_data(sms_atom);
 
-	stk->sms_submit_req = g_new0(struct sms_submit_req, 1);
-	stk->sms_submit_req->stk = stk;
+	extern_req_start(stk);
 
 	msg_list.data = (void *) &cmd->send_sms.gsm_sms;
 	msg_list.next = NULL;
 
 	if (__ofono_sms_txq_submit(sms, &msg_list, 0, NULL, send_sms_submit_cb,
-				stk->sms_submit_req, g_free) < 0) {
-		g_free(stk->sms_submit_req);
+				stk->extern_req, g_free) < 0) {
+		g_free(stk->extern_req);
 		rsp->result.type = STK_RESULT_TYPE_TERMINAL_BUSY;
 		return TRUE;
 	}
@@ -1824,6 +1829,148 @@ static gboolean handle_command_refresh(const struct stk_command *cmd,
 	return TRUE;
 }
 
+static void send_dtmf_cancel(struct ofono_stk *stk)
+{
+	stk->respond_on_exit = FALSE;
+	stk->extern_req->cancelled = TRUE;
+
+	if (stk->pending_cmd->send_dtmf.alpha_id &&
+			stk->pending_cmd->send_dtmf.alpha_id[0])
+		stk_alpha_id_unset(stk);
+}
+
+static void dtmf_sent_cb(const struct ofono_error *error, void *user_data)
+{
+	struct extern_req *req = user_data;
+	struct ofono_stk *stk = req->stk;
+	gboolean cancelled = req->cancelled;
+
+	g_free(req);
+
+	if (cancelled) {
+		DBG("Received a DTMF Sent callback after the "
+				"proactive command was cancelled");
+		return;
+	}
+
+	stk->respond_on_exit = FALSE;
+
+	if (stk->pending_cmd->send_dtmf.alpha_id &&
+			stk->pending_cmd->send_dtmf.alpha_id[0])
+		stk_alpha_id_unset(stk);
+
+	if (error->type == OFONO_ERROR_TYPE_FAILURE &&
+			error->error == ENOENT) {
+		struct stk_response rsp;
+		static unsigned char not_in_speech_call_result[] = { 0x07 };
+		static struct ofono_error failure =
+			{ .type = OFONO_ERROR_TYPE_FAILURE };
+
+		memset(&rsp, 0, sizeof(rsp));
+
+		rsp.result.type = STK_RESULT_TYPE_TERMINAL_BUSY;
+		rsp.result.additional_len = sizeof(not_in_speech_call_result);
+		rsp.result.additional = not_in_speech_call_result;
+
+		if (stk_respond(stk, &rsp, stk_command_cb))
+			stk_command_cb(&failure, stk);
+
+		return;
+	}
+
+	if (error->type == OFONO_ERROR_TYPE_FAILURE &&
+			error->error == ENOENT) {
+		send_simple_response(stk, STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD);
+		return;
+	}
+
+	if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
+		send_simple_response(stk, STK_RESULT_TYPE_SUCCESS);
+	else
+		send_simple_response(stk, STK_RESULT_TYPE_NOT_CAPABLE);
+}
+
+static gboolean handle_command_send_dtmf(const struct stk_command *cmd,
+						struct stk_response *rsp,
+						struct ofono_stk *stk)
+{
+	static unsigned char not_in_speech_call_result[] = { 0x07 };
+	struct ofono_voicecall *vc = NULL;
+	struct ofono_atom *vc_atom;
+	char dtmf[256], *digit;
+	char *dtmf_from = "01234567890abcABC";
+	char *dtmf_to = "01234567890*#,*#,";
+	int err, pos;
+
+	vc_atom = __ofono_modem_find_atom(__ofono_atom_get_modem(stk->atom),
+						OFONO_ATOM_TYPE_VOICECALL);
+	if (vc_atom)
+		vc = __ofono_atom_get_data(vc_atom);
+
+	if (!vc) {
+		rsp->result.type = STK_RESULT_TYPE_NOT_CAPABLE;
+		return TRUE;
+	}
+
+	/* Convert the DTMF string to phone number format */
+	for (pos = 0; cmd->send_dtmf.dtmf[pos] != 0; pos++) {
+		digit = strchr(dtmf_from, cmd->send_dtmf.dtmf[pos]);
+		if (!digit) {
+			rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+			return TRUE;
+		}
+
+		dtmf[pos] = dtmf_to[digit - dtmf_from];
+	}
+	dtmf[pos] = 0;
+
+	extern_req_start(stk);
+
+	err = __ofono_voicecall_send_tone(vc, dtmf,
+						dtmf_sent_cb, stk->extern_req);
+	if (err < 0)
+		g_free(stk->extern_req);
+
+	if (err == -EBUSY) {
+		rsp->result.type = STK_RESULT_TYPE_TERMINAL_BUSY;
+		return TRUE;
+	}
+
+	if (err == -ENOSYS) {
+		rsp->result.type = STK_RESULT_TYPE_NOT_CAPABLE;
+		return TRUE;
+	}
+
+	if (err == -ENOENT) {
+		rsp->result.type = STK_RESULT_TYPE_TERMINAL_BUSY;
+		rsp->result.additional_len = sizeof(not_in_speech_call_result);
+		rsp->result.additional = not_in_speech_call_result;
+		return TRUE;
+	}
+
+	if (err < 0) {
+		/*
+		 * We most likely got an out of memory error, tell SIM
+		 * to retry
+		 */
+		rsp->result.type = STK_RESULT_TYPE_TERMINAL_BUSY;
+		return TRUE;
+	}
+
+	if (cmd->send_dtmf.alpha_id && cmd->send_dtmf.alpha_id[0])
+		stk_alpha_id_set(stk, cmd->send_dtmf.alpha_id);
+
+	/*
+	 * Note that we don't strictly require an agent to be connected,
+	 * but to comply with 6.4.24 we need to send a End Session when
+	 * the user decides so.
+	 */
+	stk->respond_on_exit = TRUE;
+	stk->cancel_cmd = send_dtmf_cancel;
+
+	return FALSE;
+}
+
 static void stk_proactive_command_cancel(struct ofono_stk *stk)
 {
 	if (stk->immediate_response)
@@ -1996,6 +2143,11 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
 							&rsp, stk);
 		break;
 
+	case STK_COMMAND_TYPE_SEND_DTMF:
+		respond = handle_command_send_dtmf(stk->pending_cmd,
+							&rsp, stk);
+		break;
+
 	default:
 		rsp.result.type = STK_RESULT_TYPE_COMMAND_NOT_UNDERSTOOD;
 		break;
-- 
1.7.1.86.g0e460.dirty


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

* [PATCH 3/3][RfC] atmodem: Handle pauses in DTMF string
  2010-10-06 10:35 [PATCH] doc: Play Tone command proposed d-bus API Andrzej Zaborowski
  2010-10-06 10:35 ` [PATCH 1/3] voicecall: __ofono_voicecall_send_tone internal api Andrzej Zaborowski
  2010-10-06 10:35 ` [PATCH 2/3] stk: Handle the Send DTMF proactive command Andrzej Zaborowski
@ 2010-10-06 10:35 ` Andrzej Zaborowski
  2010-10-07  0:05 ` [PATCH] doc: Play Tone command proposed d-bus API Denis Kenzior
  3 siblings, 0 replies; 8+ messages in thread
From: Andrzej Zaborowski @ 2010-10-06 10:35 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 6609 bytes --]

---
 drivers/atmodem/voicecall.c |  162 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 134 insertions(+), 28 deletions(-)

diff --git a/drivers/atmodem/voicecall.c b/drivers/atmodem/voicecall.c
index 8b43865..cc75803 100644
--- a/drivers/atmodem/voicecall.c
+++ b/drivers/atmodem/voicecall.c
@@ -47,6 +47,9 @@
  /* Amount of time we give for CLIP to arrive before we commence CLCC poll */
 #define CLIP_INTERVAL 200
 
+ /* When +VTD returns 0, an unspecified manufacturer specific delay is used */
+#define TONE_DURATION 1000
+
 static const char *clcc_prefix[] = { "+CLCC:", NULL };
 static const char *none_prefix[] = { NULL };
 
@@ -59,6 +62,8 @@ struct voicecall_data {
 	unsigned int clcc_source;
 	GAtChat *chat;
 	unsigned int vendor;
+	struct tone_req *tr;
+	unsigned int tone_duration;
 };
 
 struct release_id_req {
@@ -75,7 +80,18 @@ struct change_state_req {
 	int affected_types;
 };
 
+struct tone_req {
+	struct ofono_voicecall *vc;
+	ofono_voicecall_cb_t cb;
+	void *data;
+	char *tone_str;
+	char *left;
+	int delay;
+	guint source;
+};
+
 static gboolean poll_clcc(gpointer user_data);
+static gboolean tone_request_run(gpointer user_data);
 
 static int class_to_call_type(int cls)
 {
@@ -522,52 +538,116 @@ static void at_deflect(struct ofono_voicecall *vc,
 	at_template(buf, vc, generic_cb, incoming_or_waiting, cb, data);
 }
 
-static void vts_cb(gboolean ok, GAtResult *result, gpointer user_data)
+static void tone_request_finish(struct tone_req *tr, GAtResult *result, int err)
 {
-	struct cb_data *cbd = user_data;
-	ofono_voicecall_cb_t cb = cbd->cb;
 	struct ofono_error error;
+	struct voicecall_data *vd = ofono_voicecall_get_data(tr->vc);
 
-	decode_at_error(&error, g_at_result_final_response(result));
-	cb(&error, cbd->data);
+	if (tr->source)
+		g_source_remove(tr->source);
+
+	if (result)
+		decode_at_error(&error, g_at_result_final_response(result));
+	else {
+		error.type = err ? OFONO_ERROR_TYPE_FAILURE :
+			OFONO_ERROR_TYPE_NO_ERROR;
+		error.error = err;
+	}
+
+	tr->cb(&error, tr->data);
+
+	g_free(vd->tr);
+	vd->tr = NULL;
 }
 
-static void at_send_dtmf(struct ofono_voicecall *vc, const char *dtmf,
-			ofono_voicecall_cb_t cb, void *data)
+static void vts_cb(gboolean ok, GAtResult *result, gpointer user_data)
 {
-	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
-	struct cb_data *cbd = cb_data_new(cb, data);
-	int len = strlen(dtmf);
+	struct tone_req *tr = user_data;
+
+	if (!ok) {
+		tone_request_finish(tr, result, 0);
+		return;
+	}
+
+	tr->source = g_timeout_add(tr->delay, tone_request_run, tr);
+}
+
+static gboolean tone_request_run(gpointer user_data)
+{
+	struct tone_req *tr = user_data;
+	struct voicecall_data *vd = ofono_voicecall_get_data(tr->vc);
+	static const char *dtmf = "0123456789#*ABCDabcd";
+	char buf[2048], *i;
 	int s;
-	int i;
-	char *buf;
 
-	if (!cbd)
-		goto error;
+	tr->source = 0;
 
-	/* strlen("+VTS=\"T\";") = 9 + initial AT + null */
-	buf = g_try_new(char, len * 9 + 3);
+	if (*tr->left == '\0') {
+		tone_request_finish(tr, NULL, 0);
+		return FALSE;
+	}
 
-	if (!buf)
-		goto error;
+	strcpy(buf, "AT");
+	i = buf + 2;
 
-	s = sprintf(buf, "AT+VTS=\"%c\"", dtmf[0]);
+	tr->delay = 0;
 
-	for (i = 1; i < len; i++)
-		s += sprintf(buf + s, ";+VTS=\"%c\"", dtmf[i]);
+	while (*tr->left && strchr(dtmf, *tr->left)) {
+		if (tr->delay)
+			*i++ = ';';
+		i += sprintf(i, "+VTS=\"%c\"", *tr->left++);
 
-	s = g_at_chat_send(vd->chat, buf, none_prefix,
-				vts_cb, cbd, g_free);
+		tr->delay += vd->tone_duration;
+	}
 
-	g_free(buf);
+	if (*tr->left && *tr->left != ',') {
+		tone_request_finish(tr, NULL, EINVAL);
+		return FALSE;
+	}
 
-	if (s > 0)
+	/*
+	 * Wait 3 seconds per PAUSE, same as for DTMF separator characters
+	 * passed in a telephone number according to TS 22.101 A.21,
+	 * although 27.007 claims this delay can be set using S8 and
+	 * defaults to 2 seconds.
+	 */
+	while (*tr->left == ',') {
+		tr->left++;
+		tr->delay += 3000;
+	}
+
+	if (i > buf + 2) {
+		s = g_at_chat_send(vd->chat, buf, none_prefix, vts_cb,
+					tr, NULL);
+
+		if (s <= 0)
+			tone_request_finish(tr, NULL, EIO);
+	} else
+		vts_cb(TRUE, NULL, tr);
+
+	return FALSE;
+}
+
+static void at_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 tone_req *tr = g_try_new0(struct tone_req, 1);
+
+	if (!tr || vd->tr) {
+		CALLBACK_WITH_FAILURE(cb, data);
 		return;
+	}
 
-error:
-	g_free(cbd);
+	tr->vc = vc;
+	tr->cb = cb;
+	tr->data = data;
+	tr->tone_str = g_strdup(dtmf);
+	tr->left = tr->tone_str;
 
-	CALLBACK_WITH_FAILURE(cb, data);
+	vd->tr = tr;
+
+	tone_request_run(tr);
 }
 
 static void ring_notify(GAtResult *result, gpointer user_data)
@@ -800,6 +880,26 @@ static void busy_notify(GAtResult *result, gpointer user_data)
 			clcc_poll_cb, vc, NULL);
 }
 
+static void vtd_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct ofono_voicecall *vc = user_data;
+	struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+	GAtResultIter iter;
+	int duration;
+
+	if (!ok)
+		return;
+
+	g_at_result_iter_init(&iter, result);
+	g_at_result_iter_next(&iter, "+VTD:");
+
+	if (!g_at_result_iter_next_number(&iter, &duration))
+		return;
+
+	if (duration)
+		vd->tone_duration = duration * 100;
+}
+
 static void at_voicecall_initialized(gboolean ok, GAtResult *result,
 					gpointer user_data)
 {
@@ -840,12 +940,15 @@ static int at_voicecall_probe(struct ofono_voicecall *vc, unsigned int vendor,
 
 	vd->chat = g_at_chat_clone(chat);
 	vd->vendor = vendor;
+	vd->tone_duration = TONE_DURATION;
 
 	ofono_voicecall_set_data(vc, vd);
 
 	g_at_chat_send(vd->chat, "AT+CRC=1", NULL, NULL, NULL, NULL);
 	g_at_chat_send(vd->chat, "AT+CLIP=1", NULL, NULL, NULL, NULL);
 	g_at_chat_send(vd->chat, "AT+COLP=1", NULL, NULL, NULL, NULL);
+	g_at_chat_send(vd->chat, "AT+VTD?", NULL,
+				vtd_query_cb, vc, NULL);
 	g_at_chat_send(vd->chat, "AT+CCWA=1", NULL,
 				at_voicecall_initialized, vc, NULL);
 
@@ -859,6 +962,9 @@ static void at_voicecall_remove(struct ofono_voicecall *vc)
 	if (vd->clcc_source)
 		g_source_remove(vd->clcc_source);
 
+	if (vd->tr)
+		tone_request_finish(vd->tr, NULL, ESHUTDOWN);
+
 	g_slist_foreach(vd->calls, (GFunc) g_free, NULL);
 	g_slist_free(vd->calls);
 
-- 
1.7.1.86.g0e460.dirty


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

* Re: [PATCH] doc: Play Tone command proposed d-bus API.
  2010-10-06 10:35 [PATCH] doc: Play Tone command proposed d-bus API Andrzej Zaborowski
                   ` (2 preceding siblings ...)
  2010-10-06 10:35 ` [PATCH 3/3][RfC] atmodem: Handle pauses in DTMF string Andrzej Zaborowski
@ 2010-10-07  0:05 ` Denis Kenzior
  3 siblings, 0 replies; 8+ messages in thread
From: Denis Kenzior @ 2010-10-07  0:05 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 253 bytes --]

Hi Andrew,

On 10/06/2010 05:35 AM, Andrzej Zaborowski wrote:
> ---
>  doc/stk-api.txt |   40 ++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 40 insertions(+), 0 deletions(-)
> 

Patch has been applied, thanks.

Regards,
-Denis

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

end of thread, other threads:[~2010-10-07  0:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-06 10:35 [PATCH] doc: Play Tone command proposed d-bus API Andrzej Zaborowski
2010-10-06 10:35 ` [PATCH 1/3] voicecall: __ofono_voicecall_send_tone internal api Andrzej Zaborowski
2010-10-06 10:35 ` [PATCH 2/3] stk: Handle the Send DTMF proactive command Andrzej Zaborowski
2010-10-06 10:35 ` [PATCH 3/3][RfC] atmodem: Handle pauses in DTMF string Andrzej Zaborowski
2010-10-07  0:05 ` [PATCH] doc: Play Tone command proposed d-bus API Denis Kenzior
  -- strict thread matches above, loose matches on Subject: below --
2010-09-08 17:59 Andrzej Zaborowski
2010-09-09 16:23 ` Marcel Holtmann
2010-09-10  1:12   ` andrzej zaborowski

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.