* [PATCH v3 1/6] emulator: add RING for HFP AG
2011-04-13 16:05 [PATCH v3 0/6] emulator: add simple incoming call support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-13 16:05 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-19 18:57 ` Denis Kenzior
2011-04-13 16:05 ` [PATCH v3 2/6] voicecall: add API to find call by status =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
` (4 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2011-04-13 16:05 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3911 bytes --]
---
src/emulator.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 76 insertions(+), 13 deletions(-)
diff --git a/src/emulator.c b/src/emulator.c
index 2707592..9005c66 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -37,6 +37,8 @@
#define DUN_DNS_SERVER_1 "10.10.10.10"
#define DUN_DNS_SERVER_2 "10.10.10.11"
+#define RING_TIMEOUT 3
+
struct ofono_emulator {
struct ofono_atom *atom;
enum ofono_emulator_type type;
@@ -49,6 +51,7 @@ struct ofono_emulator {
int events_mode;
gboolean events_ind;
GSList *indicators;
+ guint callsetup_source;
};
struct indicator {
@@ -177,6 +180,43 @@ error:
g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
}
+static struct indicator *find_indicator(struct ofono_emulator *em,
+ const char *name, int *index)
+{
+ GSList *l;
+ int i;
+
+ for (i = 1, l = em->indicators; l; l = l->next, i++) {
+ struct indicator *ind = l->data;
+
+ if (g_str_equal(ind->name, name) == FALSE)
+ continue;
+
+ if (index)
+ *index = i;
+
+ return ind;
+ }
+
+ return NULL;
+}
+
+static gboolean send_callsetup_notification(gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ struct indicator *call_ind;
+
+ if (em->type == OFONO_EMULATOR_TYPE_HFP && em->slc == FALSE)
+ return TRUE;
+
+ call_ind = find_indicator(em, OFONO_EMULATOR_IND_CALL, NULL);
+
+ if (call_ind->value == OFONO_EMULATOR_CALL_INACTIVE)
+ g_at_server_send_unsolicited(em->server, "RING");
+
+ return TRUE;
+}
+
static void brsf_cb(GAtServer *server, GAtServerRequestType type,
GAtResult *result, gpointer user_data)
{
@@ -418,6 +458,11 @@ static void emulator_unregister(struct ofono_atom *atom)
em->source = 0;
}
+ if (em->callsetup_source) {
+ g_source_remove(em->callsetup_source);
+ em->callsetup_source = 0;
+ }
+
for (l = em->indicators; l; l = l->next) {
struct indicator *ind = l->data;
@@ -681,27 +726,45 @@ enum ofono_emulator_request_type ofono_emulator_request_get_type(
void ofono_emulator_set_indicator(struct ofono_emulator *em,
const char *name, int value)
{
- GSList *l;
int i;
char buf[20];
+ struct indicator *ind;
+ struct indicator *call_ind;
- for (i = 1, l = em->indicators; l; l = l->next, i++) {
- struct indicator *ind = l->data;
+ ind = find_indicator(em, name, &i);
- if (g_str_equal(ind->name, name) == FALSE)
- continue;
+ if (ind == NULL || ind->value == value || value < ind->min
+ || value > ind->max)
+ return;
- if (ind->value == value || value < ind->min
- || value > ind->max)
- return;
+ ind->value = value;
- ind->value = value;
+ call_ind = find_indicator(em, OFONO_EMULATOR_IND_CALL, NULL);
- if (em->events_mode == 3 && em->events_ind && em->slc) {
- sprintf(buf, "+CIEV: %d,%d", i, ind->value);
- g_at_server_send_info(em->server, buf, TRUE);
- }
+ if (em->events_mode == 3 && em->events_ind && em->slc) {
+ sprintf(buf, "+CIEV: %d,%d", i, ind->value);
+ g_at_server_send_unsolicited(em->server, buf);
+ }
+ /*
+ * Ring timer should be started when callsetup indicator is set to
+ * Incoming
+ * If there is no active call, a first RING should be sent just after
+ * the +CIEV
+ * It should be stopped for all other values of callsetup
+ */
+ if (g_str_equal(name, OFONO_EMULATOR_IND_CALLSETUP) == FALSE)
return;
+
+ if (value == OFONO_EMULATOR_CALLSETUP_INCOMING) {
+ if (call_ind->value == OFONO_EMULATOR_CALL_INACTIVE)
+ send_callsetup_notification(em);
+
+ em->callsetup_source = g_timeout_add_seconds(RING_TIMEOUT,
+ send_callsetup_notification, em);
+ } else if (value != OFONO_EMULATOR_CALLSETUP_INCOMING &&
+ em->callsetup_source) {
+ g_source_remove(em->callsetup_source);
+ em->callsetup_source = 0;
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v3 1/6] emulator: add RING for HFP AG
2011-04-13 16:05 ` [PATCH v3 1/6] emulator: add RING for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-19 18:57 ` Denis Kenzior
0 siblings, 0 replies; 14+ messages in thread
From: Denis Kenzior @ 2011-04-19 18:57 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1467 bytes --]
Hi Frédéric,
On 04/13/2011 11:05 AM, Frédéric Danis wrote:
> ---
> src/emulator.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++--------
> 1 files changed, 76 insertions(+), 13 deletions(-)
>
Patch has been applied, thanks. One thing you need to watch out for though:
> + /*
> + * Ring timer should be started when callsetup indicator is set to
> + * Incoming
> + * If there is no active call, a first RING should be sent just after
> + * the +CIEV
> + * It should be stopped for all other values of callsetup
> + */
> + if (g_str_equal(name, OFONO_EMULATOR_IND_CALLSETUP) == FALSE)
> return;
> +
> + if (value == OFONO_EMULATOR_CALLSETUP_INCOMING) {
> + if (call_ind->value == OFONO_EMULATOR_CALL_INACTIVE)
> + send_callsetup_notification(em);
> +
> + em->callsetup_source = g_timeout_add_seconds(RING_TIMEOUT,
> + send_callsetup_notification, em);
> + } else if (value != OFONO_EMULATOR_CALLSETUP_INCOMING &&
> + em->callsetup_source) {
> + g_source_remove(em->callsetup_source);
> + em->callsetup_source = 0;
It is quite possible for the following situation to occur:
Initial State:
Active Call A + Waiting Call B
User dials another number C
Which results in:
Held call A, Waiting call B and Dialing call C. This case is not
covered by the original spec, so you might need to be extra pedantic on
when you remove the callsetup_source.
> }
> }
Regards,
-Denis
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 2/6] voicecall: add API to find call by status
2011-04-13 16:05 [PATCH v3 0/6] emulator: add simple incoming call support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-13 16:05 ` [PATCH v3 1/6] emulator: add RING for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-13 16:05 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-19 18:58 ` Denis Kenzior
2011-04-13 16:05 ` [PATCH v3 3/6] emulator: add +CLIP support for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
` (3 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2011-04-13 16:05 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1306 bytes --]
---
src/ofono.h | 3 +++
src/voicecall.c | 16 ++++++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/src/ofono.h b/src/ofono.h
index 156bc40..82d7e34 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -270,6 +270,9 @@ int __ofono_voicecall_tone_send(struct ofono_voicecall *vc,
ofono_voicecall_tone_cb_t cb, void *user_data);
void __ofono_voicecall_tone_cancel(struct ofono_voicecall *vc, int id);
+struct ofono_call *__ofono_voicecall_find_call_with_status(
+ struct ofono_voicecall *vc, int status);
+
#include <ofono/sms.h>
struct sms;
diff --git a/src/voicecall.c b/src/voicecall.c
index 9878050..f2e03e5 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -1098,6 +1098,22 @@ static gboolean voicecalls_have_incoming(struct ofono_voicecall *vc)
return voicecalls_have_with_status(vc, CALL_STATUS_INCOMING);
}
+struct ofono_call *__ofono_voicecall_find_call_with_status(
+ struct ofono_voicecall *vc, int status)
+{
+ GSList *l;
+ struct voicecall *v;
+
+ for (l = vc->call_list; l; l = l->next) {
+ v = l->data;
+
+ if (v->call->status == status)
+ return v->call;
+ }
+
+ return NULL;
+}
+
static void voicecalls_multiparty_changed(GSList *old, GSList *new)
{
GSList *o, *n;
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v3 3/6] emulator: add +CLIP support for HFP AG
2011-04-13 16:05 [PATCH v3 0/6] emulator: add simple incoming call support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-13 16:05 ` [PATCH v3 1/6] emulator: add RING for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-13 16:05 ` [PATCH v3 2/6] voicecall: add API to find call by status =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-13 16:05 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-19 19:00 ` Denis Kenzior
2011-04-13 16:05 ` [PATCH v3 4/6] emulator: add +CCWA " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2011-04-13 16:05 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3585 bytes --]
---
src/emulator.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 81 insertions(+), 1 deletions(-)
diff --git a/src/emulator.c b/src/emulator.c
index 9005c66..8e18785 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -29,6 +29,7 @@
#include <glib.h>
#include "ofono.h"
+#include "common.h"
#include "gatserver.h"
#include "gatppp.h"
@@ -52,6 +53,7 @@ struct ofono_emulator {
gboolean events_ind;
GSList *indicators;
guint callsetup_source;
+ gboolean clip;
};
struct indicator {
@@ -201,6 +203,47 @@ static struct indicator *find_indicator(struct ofono_emulator *em,
return NULL;
}
+static struct ofono_call *find_call_with_status(struct ofono_emulator *em,
+ int status)
+{
+ struct ofono_modem *modem = __ofono_atom_get_modem(em->atom);
+ struct ofono_atom *vc_atom;
+ struct ofono_voicecall *vc;
+
+ vc_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_VOICECALL);
+ if (vc_atom == NULL)
+ return NULL;
+
+ vc = __ofono_atom_get_data(vc_atom);
+
+ return __ofono_voicecall_find_call_with_status(vc, status);
+}
+
+static void notify_ring(struct ofono_emulator *em)
+{
+ struct ofono_call *c;
+ const char *phone;
+ /*
+ * '+CLIP: "+",' + phone number + phone type on 3 digits max
+ * + terminating null
+ */
+ char str[OFONO_MAX_PHONE_NUMBER_LENGTH + 14 + 1];
+
+ g_at_server_send_unsolicited(em->server, "RING");
+
+ if (!em->clip)
+ return;
+
+ c = find_call_with_status(em, CALL_STATUS_INCOMING);
+
+ if (c && c->clip_validity == CLIP_VALIDITY_VALID) {
+ phone = phone_number_to_string(&c->phone_number);
+ sprintf(str, "+CLIP: \"%s\",%d", phone, c->phone_number.type);
+
+ g_at_server_send_unsolicited(em->server, str);
+ }
+}
+
static gboolean send_callsetup_notification(gpointer user_data)
{
struct ofono_emulator *em = user_data;
@@ -212,7 +255,7 @@ static gboolean send_callsetup_notification(gpointer user_data)
call_ind = find_indicator(em, OFONO_EMULATOR_IND_CALL, NULL);
if (call_ind->value == OFONO_EMULATOR_CALL_INACTIVE)
- g_at_server_send_unsolicited(em->server, "RING");
+ notify_ring(em);
return TRUE;
}
@@ -427,6 +470,42 @@ fail:
}
}
+static void clip_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtResultIter iter;
+ int val;
+
+ if (em->slc == FALSE)
+ goto fail;
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_SET:
+ g_at_result_iter_init(&iter, result);
+ g_at_result_iter_next(&iter, "");
+
+ if (!g_at_result_iter_next_number(&iter, &val))
+ goto fail;
+
+ if (val != 0 && val != 1)
+ goto fail;
+
+ /* check this is last parameter */
+ if (g_at_result_iter_skip_next(&iter))
+ goto fail;
+
+ em->clip = val;
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+ break;
+
+ default:
+fail:
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+ };
+}
+
static void emulator_add_indicator(struct ofono_emulator *em, const char* name,
int min, int max, int dflt)
{
@@ -512,6 +591,7 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
g_at_server_register(em->server, "+BRSF", brsf_cb, em, NULL);
g_at_server_register(em->server, "+CIND", cind_cb, em, NULL);
g_at_server_register(em->server, "+CMER", cmer_cb, em, NULL);
+ g_at_server_register(em->server, "+CLIP", clip_cb, em, NULL);
}
__ofono_atom_register(em->atom, emulator_unregister);
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v3 3/6] emulator: add +CLIP support for HFP AG
2011-04-13 16:05 ` [PATCH v3 3/6] emulator: add +CLIP support for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-19 19:00 ` Denis Kenzior
0 siblings, 0 replies; 14+ messages in thread
From: Denis Kenzior @ 2011-04-19 19:00 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1142 bytes --]
Hi Frédéric,
On 04/13/2011 11:05 AM, Frédéric Danis wrote:
> ---
> src/emulator.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 81 insertions(+), 1 deletions(-)
>
Patch has been applied, thanks. One more comment:
> +static void notify_ring(struct ofono_emulator *em)
> +{
> + struct ofono_call *c;
> + const char *phone;
> + /*
> + * '+CLIP: "+",' + phone number + phone type on 3 digits max
> + * + terminating null
> + */
> + char str[OFONO_MAX_PHONE_NUMBER_LENGTH + 14 + 1];
> +
> + g_at_server_send_unsolicited(em->server, "RING");
> +
> + if (!em->clip)
> + return;
> +
> + c = find_call_with_status(em, CALL_STATUS_INCOMING);
> +
> + if (c && c->clip_validity == CLIP_VALIDITY_VALID) {
The spec really doesn't cover this, but you might want to send the CLIP
even in withheld cases. Or is there a reason why you did it this way?
> + phone = phone_number_to_string(&c->phone_number);
> + sprintf(str, "+CLIP: \"%s\",%d", phone, c->phone_number.type);
> +
> + g_at_server_send_unsolicited(em->server, str);
> + }
> +}
> +
Regards,
-Denis
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 4/6] emulator: add +CCWA support for HFP AG
2011-04-13 16:05 [PATCH v3 0/6] emulator: add simple incoming call support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
` (2 preceding siblings ...)
2011-04-13 16:05 ` [PATCH v3 3/6] emulator: add +CLIP support for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-13 16:05 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-19 19:01 ` Denis Kenzior
2011-04-13 16:05 ` [PATCH v3 5/6] voicecall: add ATA support for HFP emulator =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-13 16:05 ` [PATCH v3 6/6] voicecall: add +CHUP " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
5 siblings, 1 reply; 14+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2011-04-13 16:05 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 4176 bytes --]
Conflicts:
src/emulator.c
---
src/emulator.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 76 insertions(+), 1 deletions(-)
diff --git a/src/emulator.c b/src/emulator.c
index 8e18785..86d9c4f 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -54,6 +54,7 @@ struct ofono_emulator {
GSList *indicators;
guint callsetup_source;
gboolean clip;
+ gboolean ccwa;
};
struct indicator {
@@ -219,6 +220,30 @@ static struct ofono_call *find_call_with_status(struct ofono_emulator *em,
return __ofono_voicecall_find_call_with_status(vc, status);
}
+static void notify_ccwa(struct ofono_emulator *em)
+{
+ struct ofono_call *c;
+ const char *phone;
+ /*
+ * '+CCWA: "+",' + phone number + phone type on 3 digits max
+ * + terminating null
+ */
+ char str[OFONO_MAX_PHONE_NUMBER_LENGTH + 14 + 1];
+
+ if (!em->ccwa)
+ return;
+
+ c = find_call_with_status(em, CALL_STATUS_WAITING);
+
+ if (c && c->clip_validity == CLIP_VALIDITY_VALID) {
+ phone = phone_number_to_string(&c->phone_number);
+ sprintf(str, "+CCWA: \"%s\",%d", phone, c->phone_number.type);
+
+ g_at_server_send_unsolicited(em->server, str);
+ } else
+ g_at_server_send_unsolicited(em->server, "+CCWA: \"\",128");
+}
+
static void notify_ring(struct ofono_emulator *em)
{
struct ofono_call *c;
@@ -256,6 +281,8 @@ static gboolean send_callsetup_notification(gpointer user_data)
if (call_ind->value == OFONO_EMULATOR_CALL_INACTIVE)
notify_ring(em);
+ else
+ notify_ccwa(em);
return TRUE;
}
@@ -506,6 +533,42 @@ fail:
};
}
+static void ccwa_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtResultIter iter;
+ int val;
+
+ if (em->slc == FALSE)
+ goto fail;
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_SET:
+ g_at_result_iter_init(&iter, result);
+ g_at_result_iter_next(&iter, "");
+
+ if (!g_at_result_iter_next_number(&iter, &val))
+ goto fail;
+
+ if (val != 0 && val != 1)
+ goto fail;
+
+ /* check this is last parameter */
+ if (g_at_result_iter_skip_next(&iter))
+ goto fail;
+
+ em->ccwa = val;
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+ break;
+
+ default:
+fail:
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+ };
+}
+
static void emulator_add_indicator(struct ofono_emulator *em, const char* name,
int min, int max, int dflt)
{
@@ -592,6 +655,7 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
g_at_server_register(em->server, "+CIND", cind_cb, em, NULL);
g_at_server_register(em->server, "+CMER", cmer_cb, em, NULL);
g_at_server_register(em->server, "+CLIP", clip_cb, em, NULL);
+ g_at_server_register(em->server, "+CCWA", ccwa_cb, em, NULL);
}
__ofono_atom_register(em->atom, emulator_unregister);
@@ -810,6 +874,7 @@ void ofono_emulator_set_indicator(struct ofono_emulator *em,
char buf[20];
struct indicator *ind;
struct indicator *call_ind;
+ gboolean callsetup;
ind = find_indicator(em, name, &i);
@@ -821,6 +886,16 @@ void ofono_emulator_set_indicator(struct ofono_emulator *em,
call_ind = find_indicator(em, OFONO_EMULATOR_IND_CALL, NULL);
+ callsetup = g_str_equal(name, OFONO_EMULATOR_IND_CALLSETUP);
+
+ /*
+ * When callsetup indicator goes to Incoming and there is an active call
+ * a +CCWA should be sent before +CIEV
+ */
+ if (callsetup && value == OFONO_EMULATOR_CALLSETUP_INCOMING &&
+ call_ind->value == OFONO_EMULATOR_CALL_ACTIVE)
+ send_callsetup_notification(em);
+
if (em->events_mode == 3 && em->events_ind && em->slc) {
sprintf(buf, "+CIEV: %d,%d", i, ind->value);
g_at_server_send_unsolicited(em->server, buf);
@@ -833,7 +908,7 @@ void ofono_emulator_set_indicator(struct ofono_emulator *em,
* the +CIEV
* It should be stopped for all other values of callsetup
*/
- if (g_str_equal(name, OFONO_EMULATOR_IND_CALLSETUP) == FALSE)
+ if (!callsetup)
return;
if (value == OFONO_EMULATOR_CALLSETUP_INCOMING) {
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v3 5/6] voicecall: add ATA support for HFP emulator
2011-04-13 16:05 [PATCH v3 0/6] emulator: add simple incoming call support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
` (3 preceding siblings ...)
2011-04-13 16:05 ` [PATCH v3 4/6] emulator: add +CCWA " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-13 16:05 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-19 19:01 ` Denis Kenzior
2011-04-13 16:05 ` [PATCH v3 6/6] voicecall: add +CHUP " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
5 siblings, 1 reply; 14+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2011-04-13 16:05 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3409 bytes --]
---
src/voicecall.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/src/voicecall.c b/src/voicecall.c
index f2e03e5..929ecba 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -2362,13 +2362,17 @@ void ofono_voicecall_driver_unregister(const struct ofono_voicecall_driver *d)
g_drivers = g_slist_remove(g_drivers, (void *) d);
}
-static void voicecall_unregister(struct ofono_atom *atom)
+static void emulator_remove_handler(struct ofono_atom *atom, void *data)
+{
+ struct ofono_emulator *em = __ofono_atom_get_data(atom);
+
+ ofono_emulator_remove_handler(em, data);
+}
+
+static void emulator_hfp_unregister(struct ofono_atom *atom)
{
- DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_voicecall *vc = __ofono_atom_get_data(atom);
struct ofono_modem *modem = __ofono_atom_get_modem(atom);
- const char *path = __ofono_atom_get_path(atom);
- GSList *l;
__ofono_modem_foreach_registered_atom(modem,
OFONO_ATOM_TYPE_EMULATOR_HFP,
@@ -2381,7 +2385,23 @@ static void voicecall_unregister(struct ofono_atom *atom)
OFONO_ATOM_TYPE_EMULATOR_HFP,
emulator_callheld_status_cb, 0);
+ __ofono_modem_foreach_registered_atom(modem,
+ OFONO_ATOM_TYPE_EMULATOR_HFP,
+ emulator_remove_handler,
+ "A");
+
__ofono_modem_remove_atom_watch(modem, vc->hfp_watch);
+}
+
+static void voicecall_unregister(struct ofono_atom *atom)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ struct ofono_voicecall *vc = __ofono_atom_get_data(atom);
+ struct ofono_modem *modem = __ofono_atom_get_modem(atom);
+ const char *path = __ofono_atom_get_path(atom);
+ GSList *l;
+
+ emulator_hfp_unregister(atom);
if (vc->sim_state_watch) {
ofono_sim_remove_state_watch(vc->sim, vc->sim_state_watch);
@@ -2547,12 +2567,54 @@ static void sim_watch(struct ofono_atom *atom,
sim_state_watch(ofono_sim_get_state(sim), vc);
}
+static void emulator_generic_cb(const struct ofono_error *error, void *data)
+{
+ struct ofono_emulator *em = data;
+ struct ofono_error result;
+
+ result.type = error->type;
+
+ ofono_emulator_send_final(em, &result);
+}
+
+static void emulator_ata_cb(struct ofono_emulator *em,
+ struct ofono_emulator_request *req, void *userdata)
+{
+ struct ofono_voicecall *vc = userdata;
+ struct ofono_error result;
+
+ result.error = 0;
+
+ switch (ofono_emulator_request_get_type(req)) {
+ case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
+ if (!voicecalls_have_incoming(vc))
+ goto fail;
+
+ if (vc->driver->answer == NULL)
+ goto fail;
+
+ vc->driver->answer(vc, emulator_generic_cb, em);
+ break;
+
+ default:
+fail:
+ result.type = OFONO_ERROR_TYPE_FAILURE;
+ ofono_emulator_send_final(em, &result);
+ };
+}
+
static void emulator_hfp_watch(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond,
void *data)
{
- if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED)
- notify_emulator_call_status(data);
+ struct ofono_emulator *em = __ofono_atom_get_data(atom);
+
+ if (cond != OFONO_ATOM_WATCH_CONDITION_REGISTERED)
+ return;
+
+ notify_emulator_call_status(data);
+
+ ofono_emulator_add_handler(em, "A", emulator_ata_cb, data, NULL);
}
void ofono_voicecall_register(struct ofono_voicecall *vc)
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v3 6/6] voicecall: add +CHUP support for HFP emulator
2011-04-13 16:05 [PATCH v3 0/6] emulator: add simple incoming call support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
` (4 preceding siblings ...)
2011-04-13 16:05 ` [PATCH v3 5/6] voicecall: add ATA support for HFP emulator =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-13 16:05 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-14 12:27 ` [PATCH v4] " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
5 siblings, 1 reply; 14+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2011-04-13 16:05 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5423 bytes --]
Update multirelease_callback to be used from DBus calls or HFP Emulator.
"release done" is configurable by multirelease caller.
---
src/voicecall.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 93 insertions(+), 5 deletions(-)
diff --git a/src/voicecall.c b/src/voicecall.c
index 929ecba..f5af3ac 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -44,9 +44,17 @@
GSList *g_drivers = NULL;
+typedef void (*ofono_voicecall_release_next_t)(struct ofono_voicecall *vc);
+
+struct multirelease {
+ ofono_voicecall_cb_t release_done;
+ struct ofono_emulator *em;
+};
+
struct ofono_voicecall {
GSList *call_list;
GSList *release_list;
+ struct multirelease multirelease;
GSList *multiparty_list;
GHashTable *en_list; /* emergency number list */
GSList *sim_en_list; /* Emergency numbers already read from SIM */
@@ -1234,6 +1242,15 @@ fallback:
multirelease_callback, vc);
}
+static void voicecalls_release_done(const struct ofono_error *error, void *data)
+{
+ struct ofono_voicecall *vc = data;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(vc->pending);
+ __ofono_dbus_pending_reply(&vc->pending, reply);
+}
+
static DBusMessage *manager_get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1602,7 +1619,7 @@ static DBusMessage *manager_hangup_all(DBusConnection *conn,
{
struct ofono_voicecall *vc = data;
- if (vc->pending)
+ if (vc->pending || vc->release_list)
return __ofono_error_busy(msg);
if (vc->driver->hangup_all == NULL &&
@@ -1619,6 +1636,9 @@ static DBusMessage *manager_hangup_all(DBusConnection *conn,
if (vc->driver->hangup_all == NULL) {
voicecalls_release_queue(vc, vc->call_list);
+
+ vc->multirelease.release_done = voicecalls_release_done;
+
voicecalls_release_next(vc);
} else
vc->driver->hangup_all(vc, generic_callback, vc);
@@ -1828,7 +1848,7 @@ static DBusMessage *multiparty_hangup(DBusConnection *conn,
{
struct ofono_voicecall *vc = data;
- if (vc->pending)
+ if (vc->pending || vc->release_list)
return __ofono_error_busy(msg);
if (vc->driver->release_specific == NULL)
@@ -1871,6 +1891,9 @@ static DBusMessage *multiparty_hangup(DBusConnection *conn,
/* Fall back to the old-fashioned way */
voicecalls_release_queue(vc, vc->multiparty_list);
+
+ vc->multirelease.release_done = voicecalls_release_done;
+
voicecalls_release_next(vc);
out:
@@ -2175,15 +2198,13 @@ static void generic_callback(const struct ofono_error *error, void *data)
static void multirelease_callback(const struct ofono_error *error, void *data)
{
struct ofono_voicecall *vc = data;
- DBusMessage *reply;
if (vc->release_list != NULL) {
voicecalls_release_next(vc);
return;
}
- reply = dbus_message_new_method_return(vc->pending);
- __ofono_dbus_pending_reply(&vc->pending, reply);
+ vc->multirelease.release_done(error, vc);
}
static void emit_en_list_changed(struct ofono_voicecall *vc)
@@ -2389,6 +2410,10 @@ static void emulator_hfp_unregister(struct ofono_atom *atom)
OFONO_ATOM_TYPE_EMULATOR_HFP,
emulator_remove_handler,
"A");
+ __ofono_modem_foreach_registered_atom(modem,
+ OFONO_ATOM_TYPE_EMULATOR_HFP,
+ emulator_remove_handler,
+ "+CHUP");
__ofono_modem_remove_atom_watch(modem, vc->hfp_watch);
}
@@ -2603,6 +2628,68 @@ fail:
};
}
+static void emulator_release_done(const struct ofono_error *error,
+ void *data)
+{
+ struct ofono_voicecall *vc = data;
+
+ emulator_generic_cb(error, vc->multirelease.em);
+}
+
+static void emulator_chup_cb(struct ofono_emulator *em,
+ struct ofono_emulator_request *req, void *userdata)
+{
+ struct ofono_voicecall *vc = userdata;
+ struct ofono_error result;
+ GSList *l;
+ struct voicecall *call;
+
+ result.error = 0;
+
+ switch (ofono_emulator_request_get_type(req)) {
+ case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
+ if (vc->release_list)
+ goto fail;
+
+ if (vc->driver->release_specific == NULL &&
+ vc->driver->hangup_active == NULL)
+ goto fail;
+
+ if (vc->driver->hangup_active) {
+ vc->driver->hangup_active(vc, emulator_generic_cb, em);
+ goto done;
+ }
+
+ for (l = vc->call_list; l; l = l->next) {
+ call = l->data;
+
+ if (call->call->status == CALL_STATUS_WAITING ||
+ call->call->status == CALL_STATUS_HELD)
+ continue;
+
+ vc->release_list = g_slist_prepend(vc->release_list,
+ l->data);
+ }
+
+ if (vc->release_list == NULL)
+ goto fail;
+
+ vc->multirelease.release_done = emulator_release_done;
+ vc->multirelease.em = em;
+
+ voicecalls_release_next(vc);
+
+done:
+ dial_request_user_cancel(vc, NULL);
+ break;
+
+ default:
+fail:
+ result.type = OFONO_ERROR_TYPE_FAILURE;
+ ofono_emulator_send_final(em, &result);
+ };
+}
+
static void emulator_hfp_watch(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond,
void *data)
@@ -2615,6 +2702,7 @@ static void emulator_hfp_watch(struct ofono_atom *atom,
notify_emulator_call_status(data);
ofono_emulator_add_handler(em, "A", emulator_ata_cb, data, NULL);
+ ofono_emulator_add_handler(em, "+CHUP", emulator_chup_cb, data, NULL);
}
void ofono_voicecall_register(struct ofono_voicecall *vc)
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v4] voicecall: add +CHUP support for HFP emulator
2011-04-13 16:05 ` [PATCH v3 6/6] voicecall: add +CHUP " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-14 12:27 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2011-04-21 21:24 ` Denis Kenzior
0 siblings, 1 reply; 14+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2011-04-14 12:27 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5327 bytes --]
Update multirelease_callback to be used from DBus calls or HFP Emulator.
"release done" is configurable by multirelease caller.
---
src/voicecall.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 86 insertions(+), 5 deletions(-)
diff --git a/src/voicecall.c b/src/voicecall.c
index 929ecba..e0377bd 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -44,9 +44,15 @@
GSList *g_drivers = NULL;
+struct multirelease {
+ ofono_voicecall_cb_t release_done;
+ struct ofono_emulator *em;
+};
+
struct ofono_voicecall {
GSList *call_list;
GSList *release_list;
+ struct multirelease multirelease;
GSList *multiparty_list;
GHashTable *en_list; /* emergency number list */
GSList *sim_en_list; /* Emergency numbers already read from SIM */
@@ -1234,6 +1240,15 @@ fallback:
multirelease_callback, vc);
}
+static void voicecalls_release_done(const struct ofono_error *error, void *data)
+{
+ struct ofono_voicecall *vc = data;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(vc->pending);
+ __ofono_dbus_pending_reply(&vc->pending, reply);
+}
+
static DBusMessage *manager_get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1602,7 +1617,7 @@ static DBusMessage *manager_hangup_all(DBusConnection *conn,
{
struct ofono_voicecall *vc = data;
- if (vc->pending)
+ if (vc->pending || vc->release_list)
return __ofono_error_busy(msg);
if (vc->driver->hangup_all == NULL &&
@@ -1619,6 +1634,7 @@ static DBusMessage *manager_hangup_all(DBusConnection *conn,
if (vc->driver->hangup_all == NULL) {
voicecalls_release_queue(vc, vc->call_list);
+ vc->multirelease.release_done = voicecalls_release_done;
voicecalls_release_next(vc);
} else
vc->driver->hangup_all(vc, generic_callback, vc);
@@ -1828,7 +1844,7 @@ static DBusMessage *multiparty_hangup(DBusConnection *conn,
{
struct ofono_voicecall *vc = data;
- if (vc->pending)
+ if (vc->pending || vc->release_list)
return __ofono_error_busy(msg);
if (vc->driver->release_specific == NULL)
@@ -1871,6 +1887,7 @@ static DBusMessage *multiparty_hangup(DBusConnection *conn,
/* Fall back to the old-fashioned way */
voicecalls_release_queue(vc, vc->multiparty_list);
+ vc->multirelease.release_done = voicecalls_release_done;
voicecalls_release_next(vc);
out:
@@ -2175,15 +2192,13 @@ static void generic_callback(const struct ofono_error *error, void *data)
static void multirelease_callback(const struct ofono_error *error, void *data)
{
struct ofono_voicecall *vc = data;
- DBusMessage *reply;
if (vc->release_list != NULL) {
voicecalls_release_next(vc);
return;
}
- reply = dbus_message_new_method_return(vc->pending);
- __ofono_dbus_pending_reply(&vc->pending, reply);
+ vc->multirelease.release_done(error, vc);
}
static void emit_en_list_changed(struct ofono_voicecall *vc)
@@ -2389,6 +2404,10 @@ static void emulator_hfp_unregister(struct ofono_atom *atom)
OFONO_ATOM_TYPE_EMULATOR_HFP,
emulator_remove_handler,
"A");
+ __ofono_modem_foreach_registered_atom(modem,
+ OFONO_ATOM_TYPE_EMULATOR_HFP,
+ emulator_remove_handler,
+ "+CHUP");
__ofono_modem_remove_atom_watch(modem, vc->hfp_watch);
}
@@ -2603,6 +2622,67 @@ fail:
};
}
+static void emulator_release_done(const struct ofono_error *error,
+ void *data)
+{
+ struct ofono_voicecall *vc = data;
+
+ emulator_generic_cb(error, vc->multirelease.em);
+}
+
+static void emulator_chup_cb(struct ofono_emulator *em,
+ struct ofono_emulator_request *req, void *userdata)
+{
+ struct ofono_voicecall *vc = userdata;
+ struct ofono_error result;
+ GSList *l;
+ struct voicecall *call;
+
+ result.error = 0;
+
+ switch (ofono_emulator_request_get_type(req)) {
+ case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
+ if (vc->release_list)
+ goto fail;
+
+ if (vc->driver->release_specific == NULL &&
+ vc->driver->hangup_active == NULL)
+ goto fail;
+
+ if (vc->driver->hangup_active) {
+ vc->driver->hangup_active(vc, emulator_generic_cb, em);
+ goto done;
+ }
+
+ for (l = vc->call_list; l; l = l->next) {
+ call = l->data;
+
+ if (call->call->status == CALL_STATUS_WAITING ||
+ call->call->status == CALL_STATUS_HELD)
+ continue;
+
+ vc->release_list = g_slist_prepend(vc->release_list,
+ l->data);
+ }
+
+ if (vc->release_list == NULL)
+ goto fail;
+
+ vc->multirelease.release_done = emulator_release_done;
+ vc->multirelease.em = em;
+ voicecalls_release_next(vc);
+
+done:
+ dial_request_user_cancel(vc, NULL);
+ break;
+
+ default:
+fail:
+ result.type = OFONO_ERROR_TYPE_FAILURE;
+ ofono_emulator_send_final(em, &result);
+ };
+}
+
static void emulator_hfp_watch(struct ofono_atom *atom,
enum ofono_atom_watch_condition cond,
void *data)
@@ -2615,6 +2695,7 @@ static void emulator_hfp_watch(struct ofono_atom *atom,
notify_emulator_call_status(data);
ofono_emulator_add_handler(em, "A", emulator_ata_cb, data, NULL);
+ ofono_emulator_add_handler(em, "+CHUP", emulator_chup_cb, data, NULL);
}
void ofono_voicecall_register(struct ofono_voicecall *vc)
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4] voicecall: add +CHUP support for HFP emulator
2011-04-14 12:27 ` [PATCH v4] " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2011-04-21 21:24 ` Denis Kenzior
0 siblings, 0 replies; 14+ messages in thread
From: Denis Kenzior @ 2011-04-21 21:24 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 493 bytes --]
Hi Frédéric,
On 04/14/2011 07:27 AM, Frédéric Danis wrote:
> Update multirelease_callback to be used from DBus calls or HFP Emulator.
> "release done" is configurable by multirelease caller.
> ---
> src/voicecall.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
> 1 files changed, 86 insertions(+), 5 deletions(-)
>
Patch has been applied, thanks. I did refactor it somewhat afterwards,
could you make sure I didn't screw anything up?
Regards,
-Denis
^ permalink raw reply [flat|nested] 14+ messages in thread