Hi Andras,

On 10/25/2010 03:03 AM, Andras Domokos wrote:
> From: Andras Domokos <andras.domo...@nokia.com>
> 
> 
> Signed-off-by: Andras Domokos <andras.domo...@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
_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to