2011-09-27 10:22:42

by Dmitriy Paliy

[permalink] [raw]
Subject: [PATCH BlueZ v2 0/5] Replace SendDTMF by StartDTMF/StopDTMF in maemo6

Hi,

This version contains few fixes, like use of static function and DTMF
definitions for tone-generator daemon.

Br,
Dmitriy



2011-09-27 13:42:17

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 0/5] Replace SendDTMF by StartDTMF/StopDTMF in maemo6

Hi Dmitriy,

On Tue, Sep 27, 2011, Dmitriy Paliy wrote:
> This version contains few fixes, like use of static function and DTMF
> definitions for tone-generator daemon.

Thanks. All five patches have been applied.

Johan

2011-09-27 10:22:45

by Dmitriy Paliy

[permalink] [raw]
Subject: [PATCH BlueZ v2 3/5] Add playback of tones to handsfree

StartEventTone and StopTone method calls to tone generator are added
to maemo6 telephony driver. Such implements playback of DTMF tones
in handsfree to notify user.
---
audio/telephony-maemo6.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index 1f3cdef..6bbbc11 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -118,6 +118,21 @@ enum net_registration_status {
#define OHM_INTERFACE "com.nokia.NonGraphicFeedback1"
#define OHM_PATH "/com/nokia/NonGraphicFeedback1"

+/* tone-genenerator D-Bus definitions */
+#define TONEGEN_BUS_NAME "com.Nokia.Telephony.Tones"
+#define TONEGEN_INTERFACE "com.Nokia.Telephony.Tones"
+#define TONEGEN_PATH "/com/Nokia/Telephony/Tones"
+
+/* tone-generator DTMF definitions */
+#define DTMF_ASTERISK 10
+#define DTMF_HASHMARK 11
+#define DTMF_A 12
+#define DTMF_B 13
+#define DTMF_C 14
+#define DTMF_D 15
+
+#define FEEDBACK_TONE_DURATION 200
+
struct csd_call {
char *object_path;
int status;
@@ -158,6 +173,10 @@ static GSList *pending = NULL;
/* Reference count for determining the call indicator status */
static GSList *active_calls = NULL;

+/* Queue of DTMF tones to play */
+static GSList *tones = NULL;
+static guint create_tones_timer = 0;
+
static char *msisdn = NULL; /* Subscriber number */
static char *vmbx = NULL; /* Voice mailbox number */

@@ -777,11 +796,111 @@ static void start_dtmf(void *telephony_device, char tone)
telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
}

+static int tonegen_startevent(char tone)
+{
+ int ret;
+ dbus_uint32_t event_tone;
+ dbus_int32_t dbm0 = -15;
+ dbus_uint32_t duration = 150;
+
+ switch (tone) {
+ case '*':
+ event_tone = DTMF_ASTERISK;
+ break;
+ case '#':
+ event_tone = DTMF_HASHMARK;
+ break;
+ case 'A':
+ event_tone = DTMF_A;
+ break;
+ case 'B':
+ event_tone = DTMF_B;
+ break;
+ case 'C':
+ event_tone = DTMF_C;
+ break;
+ case 'D':
+ event_tone = DTMF_D;
+ break;
+ default:
+ event_tone = atoi(&tone);
+ }
+
+ ret = send_method_call(TONEGEN_BUS_NAME, TONEGEN_PATH,
+ TONEGEN_INTERFACE, "StartEventTone",
+ NULL, NULL,
+ DBUS_TYPE_UINT32, &event_tone,
+ DBUS_TYPE_INT32, &dbm0,
+ DBUS_TYPE_UINT32, &duration,
+ DBUS_TYPE_INVALID);
+ return ret;
+}
+
+static gboolean stop_feedback_tone(gpointer user_data)
+{
+ if (g_slist_length(tones) > 0) {
+ gpointer ptone;
+ int ret;
+
+ send_method_call(TONEGEN_BUS_NAME, TONEGEN_PATH,
+ TONEGEN_INTERFACE, "StopTone",
+ NULL, NULL,
+ DBUS_TYPE_INVALID);
+
+ ptone = g_slist_nth_data(tones, 0);
+ tones = g_slist_remove(tones, ptone);
+
+ ret = tonegen_startevent(GPOINTER_TO_UINT(ptone));
+ if (ret < 0)
+ goto done;
+
+ return TRUE;
+ }
+done:
+ return FALSE;
+}
+
+static void tones_timer_notify(gpointer data)
+{
+ send_method_call(TONEGEN_BUS_NAME, TONEGEN_PATH,
+ TONEGEN_INTERFACE, "StopTone",
+ NULL, NULL,
+ DBUS_TYPE_INVALID);
+ g_slist_free(tones);
+ tones = NULL;
+
+ create_tones_timer = 0;
+}
+
+static void start_feedback_tone(char tone)
+{
+ if (!create_tones_timer) {
+ int ret;
+
+ ret = tonegen_startevent(tone);
+ if (ret < 0)
+ return;
+
+ create_tones_timer = g_timeout_add_full(G_PRIORITY_DEFAULT,
+ FEEDBACK_TONE_DURATION,
+ stop_feedback_tone,
+ NULL,
+ tones_timer_notify);
+ } else {
+ glong dtmf_tone = tone;
+
+ DBG("add %c to queue", tone);
+ tones = g_slist_append(tones, GUINT_TO_POINTER(dtmf_tone));
+ }
+}
+
void telephony_transmit_dtmf_req(void *telephony_device, char tone)
{
DBG("telephony-maemo6: transmit dtmf: %c", tone);

start_dtmf(telephony_device, tone);
+
+ start_feedback_tone(tone);
}

void telephony_subscriber_number_req(void *telephony_device)
--
1.7.4.1


2011-09-27 10:22:47

by Dmitriy Paliy

[permalink] [raw]
Subject: [PATCH BlueZ v2 5/5] Fix remove feedback DTMF tones timer on call release

User feedback DTMF tones queue is freed and timer removed when call
is released.
---
audio/telephony-maemo6.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index 30803ce..874cba1 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -1317,6 +1317,9 @@ static void call_set_status(struct csd_call *call, dbus_uint32_t status)
if (g_slist_length(active_calls) == 0)
telephony_update_indicator(maemo_indicators, "call",
EV_CALL_INACTIVE);
+
+ if (create_tones_timer)
+ g_source_remove(create_tones_timer);
break;
case CSD_CALL_STATUS_HOLD_INITIATED:
break;
--
1.7.4.1


2011-09-27 10:22:44

by Dmitriy Paliy

[permalink] [raw]
Subject: [PATCH BlueZ v2 2/5] Fix error handling in start_dtmf_reply

If csd replyed with error to StartDTMF, then StopDTMF method call
is not sent.
---
audio/telephony-maemo6.c | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index ad5d06f..1f3cdef 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -734,10 +734,25 @@ void telephony_dial_number_req(void *telephony_device, const char *number)

static void start_dtmf_reply(DBusPendingCall *call, void *user_data)
{
- send_method_call(CSD_CALL_BUS_NAME, CSD_CALL_PATH,
+ DBusError err;
+ DBusMessage *reply;
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&err);
+ if (dbus_set_error_from_message(&err, reply)) {
+ error("csd replied with an error: %s, %s",
+ err.name, err.message);
+
+ dbus_error_free(&err);
+ } else
+ send_method_call(CSD_CALL_BUS_NAME, CSD_CALL_PATH,
CSD_CALL_INTERFACE, "StopDTMF",
NULL, NULL,
DBUS_TYPE_INVALID);
+
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
}

static void start_dtmf(void *telephony_device, char tone)
--
1.7.4.1


2011-09-27 10:22:46

by Dmitriy Paliy

[permalink] [raw]
Subject: [PATCH BlueZ v2 4/5] Fix play DTMF feeback tones only for active call

Check on active call is added for playing of DTMF feedback tones to
notify user. Network DTMF tones are handled by modem, and therefore
there is no need in special check for those.
---
audio/telephony-maemo6.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index 6bbbc11..30803ce 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -900,7 +900,10 @@ void telephony_transmit_dtmf_req(void *telephony_device, char tone)

start_dtmf(telephony_device, tone);

- start_feedback_tone(tone);
+ if (!find_call_with_status(CSD_CALL_STATUS_ACTIVE))
+ error("No active call");
+ else
+ start_feedback_tone(tone);
}

void telephony_subscriber_number_req(void *telephony_device)
--
1.7.4.1


2011-09-27 10:22:43

by Dmitriy Paliy

[permalink] [raw]
Subject: [PATCH BlueZ v2 1/5] Replace SendDTMF by StartDTMF/StopDTMF in maemo6

SendDTMF method call is replaced by StartDTMF/StopDTMF in maemo6 telephony
driver. StartDTMF/StopDTMF places DTMF tone in queue on modem side playing
it minimum required time. When using SendDTMF, modem ignores new tone
until currently playing one is not finished.

Downside of StartDTMF/StopDTMF combination is absence of audio feedback to
hands-free.
---
audio/telephony-maemo6.c | 30 +++++++++++++++++++++++-------
1 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/audio/telephony-maemo6.c b/audio/telephony-maemo6.c
index a5845c4..ad5d06f 100644
--- a/audio/telephony-maemo6.c
+++ b/audio/telephony-maemo6.c
@@ -732,17 +732,26 @@ void telephony_dial_number_req(void *telephony_device, const char *number)
CME_ERROR_AG_FAILURE);
}

-void telephony_transmit_dtmf_req(void *telephony_device, char tone)
+static void start_dtmf_reply(DBusPendingCall *call, void *user_data)
{
- int ret;
- char buf[2] = { tone, '\0' }, *buf_ptr = buf;
+ send_method_call(CSD_CALL_BUS_NAME, CSD_CALL_PATH,
+ CSD_CALL_INTERFACE, "StopDTMF",
+ NULL, NULL,
+ DBUS_TYPE_INVALID);
+}

- DBG("telephony-maemo6: transmit dtmf: %s", buf);
+static void start_dtmf(void *telephony_device, char tone)
+{
+ int ret;

+ /*
+ * Stop tone immediately, modem will place it in queue and play
+ * required time.
+ */
ret = send_method_call(CSD_CALL_BUS_NAME, CSD_CALL_PATH,
- CSD_CALL_INTERFACE, "SendDTMF",
- NULL, NULL,
- DBUS_TYPE_STRING, &buf_ptr,
+ CSD_CALL_INTERFACE, "StartDTMF",
+ start_dtmf_reply, NULL,
+ DBUS_TYPE_BYTE, &tone,
DBUS_TYPE_INVALID);
if (ret < 0) {
telephony_transmit_dtmf_rsp(telephony_device,
@@ -753,6 +762,13 @@ void telephony_transmit_dtmf_req(void *telephony_device, char tone)
telephony_transmit_dtmf_rsp(telephony_device, CME_ERROR_NONE);
}

+void telephony_transmit_dtmf_req(void *telephony_device, char tone)
+{
+ DBG("telephony-maemo6: transmit dtmf: %c", tone);
+
+ start_dtmf(telephony_device, tone);
+}
+
void telephony_subscriber_number_req(void *telephony_device)
{
DBG("telephony-maemo6: subscriber number request");
--
1.7.4.1