From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [RFC PATCH 2/3] voicecall: emergency call handling added
Date: Wed, 27 Oct 2010 22:48:31 -0500 [thread overview]
Message-ID: <4CC8F28F.6030500@gmail.com> (raw)
In-Reply-To: <6e335becb35a0d670ba6bbf658827637836a7b1c.1287763218.git.andras.domokos@nokia.com>
[-- Attachment #1: Type: text/plain, Size: 14980 bytes --]
Hi Andras,
On 10/25/2010 03:03 AM, Andras Domokos wrote:
> From: Andras Domokos <andras.domokos@nokia.com>
>
>
> Signed-off-by: Andras Domokos <andras.domokos@nokia.com>
> ---
> include/voicecall.h | 12 +++
> src/voicecall.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++----
> 2 files changed, 215 insertions(+), 18 deletions(-)
>
> diff --git a/include/voicecall.h b/include/voicecall.h
> index 2356fcf..d530148 100644
> --- a/include/voicecall.h
> +++ b/include/voicecall.h
> @@ -38,6 +38,9 @@ typedef void (*ofono_call_list_cb_t)(const struct ofono_error *error,
> const struct ofono_call *call_list,
> void *data);
>
> +typedef void (*ofono_voicecall_emergency_notify_cb_t)(ofono_bool_t state,
> + void *data);
> +
> /* Voice call related functionality, including ATD, ATA, +CHLD, CTFR, CLCC
> * and VTS.
> *
> @@ -116,6 +119,15 @@ void ofono_voicecall_set_data(struct ofono_voicecall *vc, void *data);
> void *ofono_voicecall_get_data(struct ofono_voicecall *vc);
> int ofono_voicecall_get_next_callid(struct ofono_voicecall *vc);
>
> +unsigned int __ofono_voicecall_add_emergency_watch(struct ofono_voicecall *vc,
> + ofono_voicecall_emergency_notify_cb_t notify,
> + void *data, ofono_destroy_func destroy);
> +void __ofono_voicecall_remove_emergency_watch(struct ofono_voicecall *vc,
> + unsigned int id);
> +ofono_bool_t ofono_voicecall_get_emergency_state(struct ofono_voicecall *vc);
> +void __ofono_voicecall_set_emergency_state(struct ofono_voicecall *vc,
> + int state);
> +
Just some general comments, but this patch seems to be backwards from
the earlier proposal. Namely EmergencyMode is a property on the Modem
interface, not on the VoiceCallManager. See doc/modem-api.txt,
Emergency property.
In general I think that the emergency_watch is unnecessary. Having a
reference counted emergency tracking inside the modem object and a modem
online state watch should be sufficient.
> #ifdef __cplusplus
> }
> #endif
> diff --git a/src/voicecall.c b/src/voicecall.c
> index 7b5fe3b..a619b30 100644
> --- a/src/voicecall.c
> +++ b/src/voicecall.c
> @@ -25,6 +25,7 @@
>
> #include <string.h>
> #include <stdio.h>
> +#include <stdlib.h>
> #include <time.h>
> #include <errno.h>
> #include <stdint.h>
> @@ -56,6 +57,9 @@ struct ofono_voicecall {
> void *driver_data;
> struct ofono_atom *atom;
> struct dial_request *dial_req;
> + struct ofono_watchlist *emergency_watches;
> + unsigned int emergency_state;
> + unsigned int modem_state_watch;
> };
>
> struct voicecall {
> @@ -85,6 +89,8 @@ static const char *default_en_list_no_sim[] = { "119", "118", "999", "110",
>
> static void generic_callback(const struct ofono_error *error, void *data);
> static void multirelease_callback(const struct ofono_error *err, void *data);
> +static const char *voicecall_build_path(struct ofono_voicecall *vc,
> + const struct ofono_call *call);
>
It is generally against the coding style to forward-declare static
functions. If this function is needed, please simply move it higher.
> static gint call_compare_by_id(gconstpointer a, gconstpointer b)
> {
> @@ -121,6 +127,145 @@ static void add_to_en_list(GSList **l, const char **list)
> *l = g_slist_prepend(*l, g_strdup(list[i++]));
> }
>
> +static gint number_compare(gconstpointer a, gconstpointer b)
> +{
> + const char *s1 = a, *s2 = b;
> + return strcmp(s1, s2);
> +}
> +
> +static ofono_bool_t emergency_number(struct ofono_voicecall *vc,
> + const char *number)
> +{
> + if (!number)
> + return FALSE;
> +
> + return g_slist_find_custom(vc->en_list,
> + number, number_compare) ? TRUE : FALSE;
> +}
> +
Please add this as a separate patch handling the 'Extend the voicecall
interface with a property indicating whether this call is an emergency
call' task.
> +static void notify_emergency_watches(struct ofono_voicecall *vc,
> + ofono_bool_t state)
> +{
> + struct ofono_watchlist_item *item;
> + GSList *l;
> + ofono_voicecall_emergency_notify_cb_t notify;
> +
> + if (vc->emergency_watches == NULL)
> + return;
> +
> + for (l = vc->emergency_watches->items; l; l = l->next) {
> + item = l->data;
> + notify = item->notify;
> + notify(state, item->notify_data);
> + }
> +}
> +
> +unsigned int __ofono_voicecall_add_emergency_watch(struct ofono_voicecall *vc,
> + ofono_voicecall_emergency_notify_cb_t notify,
> + void *data, ofono_destroy_func destroy)
> +{
> + struct ofono_watchlist_item *item;
> +
> + if (vc == NULL || notify == NULL)
> + return 0;
> +
> + item = g_new0(struct ofono_watchlist_item, 1);
> +
> + item->notify = notify;
> + item->destroy = destroy;
> + item->notify_data = data;
> +
> + return __ofono_watchlist_add_item(vc->emergency_watches, item);
> +}
> +
> +void __ofono_voicecall_remove_emergency_watch(struct ofono_voicecall *vc,
> + unsigned int id)
> +{
> + __ofono_watchlist_remove_item(vc->emergency_watches, id);
> +}
> +
> +ofono_bool_t ofono_voicecall_get_emergency_state(struct ofono_voicecall *vc)
> +{
> + return vc->emergency_state ? 1 : 0;
> +}
> +
> +void __ofono_voicecall_inc_emergency_state(struct ofono_voicecall *vc)
> +{
> + DBusConnection *conn = ofono_dbus_get_connection();
> + const char *path = __ofono_atom_get_path(vc->atom);
> + gboolean state = TRUE;
> +
> + if (!vc->emergency_state++) {
Please avoid such coding style. Parsing such a statement takes
considerable effort.
vc->emergency_state++;
if (vc->emergency_state > 1)
return;
ofono_dbus_signal...
would be much more readable.
> + ofono_dbus_signal_property_changed(conn, path,
> + OFONO_VOICECALL_INTERFACE,
> + "EmergencyMode",
> + DBUS_TYPE_BOOLEAN,
> + &state);
> + notify_emergency_watches(vc, state);
> + }
> +}
> +
> +void __ofono_voicecall_dec_emergency_state(struct ofono_voicecall *vc)
> +{
> + DBusConnection *conn = ofono_dbus_get_connection();
> + const char *path = __ofono_atom_get_path(vc->atom);
> + gboolean state = FALSE;
> +
> + if (!--vc->emergency_state) {
> + ofono_dbus_signal_property_changed(conn, path,
> + OFONO_VOICECALL_INTERFACE,
> + "EmergencyMode",
> + DBUS_TYPE_BOOLEAN,
> + &state);
> + notify_emergency_watches(vc, state);
> + }
> +}
> +
> +static ofono_bool_t clir_string_to_clir(const char *clirstr,
> + enum ofono_clir_option *clir);
> +static void manager_dial_callback(const struct ofono_error *error, void *data);
Again, please avoid forward declarations
> +static void modem_state_watch(enum ofono_modem_state state, void *data)
> +{
> + struct ofono_voicecall *vc = data;
> + struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom);
> + DBusMessage *reply;
> + const char *number;
> + struct ofono_phone_number ph;
> + const char *clirstr;
> + enum ofono_clir_option clir;
> +
> + if (!vc->pending)
> + return;
> +
> + if (strcmp(dbus_message_get_member(vc->pending), "Dial"))
> + return;
> +
> + if (dbus_message_get_args(vc->pending, NULL, DBUS_TYPE_STRING, &number,
> + DBUS_TYPE_STRING, &clirstr,
> + DBUS_TYPE_INVALID) == FALSE) {
> + reply = __ofono_error_invalid_args(vc->pending);
> + __ofono_dbus_pending_reply(&vc->pending, reply);
> + return;
> + }
> +
> + /* don't care here about non-emergency calls */
> + if (!emergency_number(vc, number))
> + return;
> +
> + if (!ofono_modem_get_online(modem)) {
> + reply = __ofono_error_failed(vc->pending);
> + __ofono_dbus_pending_reply(&vc->pending, reply);
> + __ofono_voicecall_dec_emergency_state(vc);
> + return;
> + }
> +
> + clir_string_to_clir(clirstr, &clir);
> + string_to_phone_number(number, &ph);
> +
> + vc->driver->dial(vc, &ph, clir, OFONO_CUG_OPTION_DEFAULT,
> + manager_dial_callback, vc);
> +}
> +
> static const char *disconnect_reason_to_string(enum ofono_disconnect_reason r)
> {
> switch (r) {
> @@ -718,7 +863,8 @@ static gboolean voicecalls_can_dtmf(struct ofono_voicecall *vc)
> return FALSE;
> }
>
> -static gboolean voicecalls_have_with_status(struct ofono_voicecall *vc, int status)
> +static gboolean voicecalls_have_with_status(struct ofono_voicecall *vc,
> + int status)
Why is this here? This chunk does not seem related to this patch
> {
> GSList *l;
> struct voicecall *v;
> @@ -918,6 +1064,7 @@ static DBusMessage *manager_get_properties(DBusConnection *conn,
> int i;
> GSList *l;
> char **list;
> + ofono_bool_t emergency_state;
>
> reply = dbus_message_new_method_return(msg);
>
> @@ -930,6 +1077,10 @@ static DBusMessage *manager_get_properties(DBusConnection *conn,
> OFONO_PROPERTIES_ARRAY_SIGNATURE,
> &dict);
>
> + emergency_state = ofono_voicecall_get_emergency_state(vc);
> + ofono_dbus_dict_append(&dict, "EmergencyMode",
> + DBUS_TYPE_BOOLEAN, &emergency_state);
> +
As mentioned before, Emergency was agreed to be on the Modem interface
> /* property EmergencyNumbers */
> list = g_new0(char *, g_slist_length(vc->en_list) + 1);
>
> @@ -1066,8 +1217,11 @@ static void manager_dial_callback(const struct ofono_error *error, void *data)
>
> dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
> DBUS_TYPE_INVALID);
> - } else
> + } else {
> + if (emergency_number(vc, number))
> + __ofono_voicecall_dec_emergency_state(vc);
> reply = __ofono_error_failed(vc->pending);
> + }
>
> __ofono_dbus_pending_reply(&vc->pending, reply);
>
> @@ -1118,6 +1272,14 @@ static DBusMessage *manager_dial(DBusConnection *conn,
>
> string_to_phone_number(number, &ph);
>
> + if (emergency_number(vc, number)) {
> + struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom);
> + ofono_bool_t online = ofono_modem_get_online(modem);
> + __ofono_voicecall_inc_emergency_state(vc);
> + if (!online)
> + return NULL;
> + }
> +
> vc->driver->dial(vc, &ph, clir, OFONO_CUG_OPTION_DEFAULT,
> manager_dial_callback, vc);
>
> @@ -1667,7 +1829,7 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id,
> {
> struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom);
> GSList *l;
> - struct voicecall *call;
> + struct voicecall *v;
Why? Please refrain from doing this. If you feel the variable naming
could be improved, then send a separate patch. As it is, it has no
bearing on emergency call handling...
> time_t ts;
> enum call_status prev_status;
>
> @@ -1684,48 +1846,52 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id,
> return;
> }
>
> - call = l->data;
> + v = l->data;
>
> ts = time(NULL);
> - prev_status = call->call->status;
> + prev_status = v->call->status;
>
> l = g_slist_find_custom(vc->multiparty_list, GUINT_TO_POINTER(id),
> call_compare_by_id);
>
> if (l) {
> vc->multiparty_list =
> - g_slist_remove(vc->multiparty_list, call);
> + g_slist_remove(vc->multiparty_list, v);
>
> if (vc->multiparty_list->next == NULL) { /* Size == 1 */
> - struct voicecall *v = vc->multiparty_list->data;
> + struct voicecall *v2 = vc->multiparty_list->data;
>
> - voicecall_emit_multiparty(v, FALSE);
> + voicecall_emit_multiparty(v2, FALSE);
> g_slist_free(vc->multiparty_list);
> vc->multiparty_list = 0;
> }
> }
>
> - vc->release_list = g_slist_remove(vc->release_list, call);
> + vc->release_list = g_slist_remove(vc->release_list, v);
>
> if (reason != OFONO_DISCONNECT_REASON_UNKNOWN)
> - voicecall_emit_disconnect_reason(call, reason);
> + voicecall_emit_disconnect_reason(v, reason);
>
> - voicecall_set_call_status(call, CALL_STATUS_DISCONNECTED);
> + voicecall_set_call_status(v, CALL_STATUS_DISCONNECTED);
>
> - if (!call->untracked) {
> + if (!v->untracked) {
> if (prev_status == CALL_STATUS_INCOMING ||
> prev_status == CALL_STATUS_WAITING)
> - __ofono_history_call_missed(modem, call->call, ts);
> + __ofono_history_call_missed(modem, v->call, ts);
> else
> - __ofono_history_call_ended(modem, call->call,
> - call->detect_time, ts);
> + __ofono_history_call_ended(modem, v->call,
> + v->detect_time, ts);
> }
>
> - voicecalls_emit_call_removed(vc, call);
> + voicecalls_emit_call_removed(vc, v);
> +
> + if (emergency_number(vc,
> + phone_number_to_string(&v->call->phone_number)))
> + __ofono_voicecall_dec_emergency_state(vc);
>
> - voicecall_dbus_unregister(vc, call);
> + voicecall_dbus_unregister(vc, v);
>
> - vc->call_list = g_slist_remove(vc->call_list, call);
> + vc->call_list = g_slist_remove(vc->call_list, v);
> }
>
> void ofono_voicecall_notify(struct ofono_voicecall *vc,
> @@ -1969,6 +2135,9 @@ static void voicecall_unregister(struct ofono_atom *atom)
> vc->sim_watch = 0;
> }
>
> + __ofono_watchlist_free(vc->emergency_watches);
> + vc->emergency_watches = NULL;
> +
> if (vc->dial_req)
> dial_request_finish(vc);
>
> @@ -1985,6 +2154,7 @@ static void voicecall_unregister(struct ofono_atom *atom)
> static void voicecall_remove(struct ofono_atom *atom)
> {
> struct ofono_voicecall *vc = __ofono_atom_get_data(atom);
> + struct ofono_modem *modem = __ofono_atom_get_modem(atom);
>
> DBG("atom: %p", atom);
>
> @@ -2012,6 +2182,11 @@ static void voicecall_remove(struct ofono_atom *atom)
> vc->sim = NULL;
> }
>
> + if (vc->modem_state_watch) {
> + __ofono_modem_remove_state_watch(modem, vc->modem_state_watch);
> + vc->modem_state_watch = 0;
> + }
> +
> g_free(vc);
> }
>
> @@ -2122,6 +2297,10 @@ void ofono_voicecall_register(struct ofono_voicecall *vc)
> }
>
> ofono_modem_add_interface(modem, OFONO_VOICECALL_MANAGER_INTERFACE);
> + vc->emergency_watches = __ofono_watchlist_new(g_free);
> + vc->modem_state_watch = __ofono_modem_add_state_watch(modem,
> + modem_state_watch,
> + vc, NULL);
>
> /*
> * Start out with the 22.101 mandated numbers, if we have a SIM and
> @@ -2208,6 +2387,9 @@ static void dial_request_cb(const struct ofono_error *error, void *data)
>
> if (v == NULL) {
> dial_request_finish(vc);
> + if (emergency_number(vc,
> + phone_number_to_string(&vc->dial_req->ph)))
> + __ofono_voicecall_inc_emergency_state(vc);
> return;
> }
>
> @@ -2233,6 +2415,9 @@ static void dial_request_cb(const struct ofono_error *error, void *data)
>
> static void dial_request(struct ofono_voicecall *vc)
> {
> + if (emergency_number(vc, phone_number_to_string(&vc->dial_req->ph)))
> + __ofono_voicecall_inc_emergency_state(vc);
> +
> vc->driver->dial(vc, &vc->dial_req->ph, OFONO_CLIR_OPTION_DEFAULT,
> OFONO_CUG_OPTION_DEFAULT, dial_request_cb, vc);
> }
Regards,
-Denis
next prev parent reply other threads:[~2010-10-28 3:48 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-22 16:47 Emergency Calls Andras Domokos
2010-10-22 16:47 ` [RFC PATCH 1/3] modem: modem state watch added Andras Domokos
2010-10-28 3:31 ` Denis Kenzior
2010-10-22 16:47 ` [RFC PATCH 2/3] voicecall: emergency call handling added Andras Domokos
2010-10-28 3:48 ` Denis Kenzior [this message]
2010-10-29 9:29 ` Andras Domokos
2010-10-29 12:36 ` Marcel Holtmann
2010-10-29 17:32 ` Denis Kenzior
2010-11-01 9:03 ` Mika.Liljeberg
2010-11-01 9:41 ` Marcel Holtmann
2010-11-01 11:11 ` Mika.Liljeberg
2010-11-01 11:23 ` Andras Domokos
2010-10-22 16:47 ` [RFC PATCH 3/3] modem: emergency state " Andras Domokos
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4CC8F28F.6030500@gmail.com \
--to=denkenz@gmail.com \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox