Emergency Calls
cover Emergency Calls
Steps in handling emergency calls:
- subscribe to modem online notifications
- emergency call detected (phone number is an emergency number)
- increment emergency mode
- advertise "Emergency" property change on D-Bus (first call)
- set modem online (minimal setup) if mode was offline
- adevertise "Online" property change on D-Bus
- if modem is not online postpone making the call, otherwise make the emergency call
- when modem online notification comes and there is postponed emergency call request, make the emergency call
- when an emergency call ends decrement emergency mode
- set modem to pre emergency call state (last call)
- advertise "Online" property change on D-Bus (if any)
- advertise "Emergency" property change on D-Bus (last call)
Andras Domokos (3):
modem: add Emergency property
modem: move dial request_cb function
voicecall: add emergency call handling
src/dbus.c | 7 ++ src/modem.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/ofono.h | 5 ++ src/voicecall.c | 186 ++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 369 insertions(+), 36 deletions(-)
RFC PATCH 1/3 modem: add Emergency property
--- src/dbus.c | 7 ++ src/modem.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/ofono.h | 5 ++ 3 files changed, 216 insertions(+), 3 deletions(-)
src/dbus.c +7 -0
@@ -345,6 +345,13 @@ DBusMessage *__ofono_error_access_denied(DBusMessage *msg) "Operation not permitted"); } +DBusMessage *__ofono_error_emergency_active (DBusMessage *msg) +{ +return g_dbus_create_error (msg,OFONO_ERROR_INTERFACE +".EmergencyActive" , +"Emergency state active" ); +} +void __ofono_dbus_pending_reply (DBusMessage **msg,DBusMessage *reply) {DBusConnection *conn =ofono_dbus_get_connection ();
src/modem.c +204 -3
301 lines not on this page · raw message
src/ofono.h +5 -0
@@ -58,6 +58,7 @@ DBusMessage *__ofono_error_not_attached(DBusMessage *msg);DBusMessage *__ofono_error_attach_in_progress (DBusMessage *msg);DBusMessage *__ofono_error_canceled (DBusMessage *msg);DBusMessage *__ofono_error_access_denied (DBusMessage *msg); +DBusMessage *__ofono_error_emergency_active (DBusMessage *msg);void __ofono_dbus_pending_reply (DBusMessage **msg,DBusMessage *reply);
@@ -186,6 +187,10 @@ unsigned int __ofono_modem_add_online_watch(struct ofono_modem *modem,void __ofono_modem_remove_online_watch (struct ofono_modem *modem,unsigned int id); +ofono_bool_t ofono_modem_get_emergency (struct ofono_modem *modem); +void ofono_modem_inc_emergency (struct ofono_modem *modem); +void ofono_modem_dec_emergency (struct ofono_modem *modem); +#include <ofono/call-barring.h> gboolean __ofono_call_barring_is_busy (struct ofono_call_barring *cb);
Signature · 1 line
1.7.0.4
RFC PATCH 2/3 modem: move dial request_cb function
In reply to Andras Domokos--- src/voicecall.c | 70 +++++++++++++++++++++++++++--------------------------- 1 files changed, 35 insertions(+), 35 deletions(-)
src/voicecall.c +35 -35
@@ -2209,6 +2209,41 @@ static void sim_watch(struct ofono_atom *atom,sim_state_watch (ofono_sim_get_state (sim), vc); } +static void dial_request_cb (const struct ofono_error *error,void *data) +{ +struct ofono_voicecall *vc = data; +gboolean need_to_emit; +struct voicecall *v; + + v =dial_handle_result (vc, error, +phone_number_to_string (&vc->dial_req->ph), + &need_to_emit); + +if (v ==NULL ) { +dial_request_finish (vc); +return ; + } + + v->message = vc->dial_req->message; + v->icon_id = vc->dial_req->icon_id; + + vc->dial_req->message =NULL ; + vc->dial_req->call = v; + +/* +* TS 102 223 Section 6.4.13: The terminal shall not store +* in the UICC the call set-up details (called party number +* and associated parameters) +*/ + v->untracked = TRUE; + +if (v->call->status ==CALL_STATUS_ACTIVE ) +dial_request_finish (vc); + +if (need_to_emit) +voicecalls_emit_call_added (vc, v); +} +void ofono_voicecall_register (struct ofono_voicecall *vc) {DBusConnection *conn =ofono_dbus_get_connection ();
@@ -2301,41 +2336,6 @@ ofono_bool_t __ofono_voicecall_is_busy(struct ofono_voicecall *vc,return TRUE; } -static void dial_request_cb (const struct ofono_error *error,void *data) -{ -struct ofono_voicecall *vc = data; -gboolean need_to_emit; -struct voicecall *v; - - v =dial_handle_result (vc, error, -phone_number_to_string (&vc->dial_req->ph), - &need_to_emit); - -if (v ==NULL ) { -dial_request_finish (vc); -return ; - } - - v->message = vc->dial_req->message; - v->icon_id = vc->dial_req->icon_id; - - vc->dial_req->message =NULL ; - vc->dial_req->call = v; - -/* -* TS 102 223 Section 6.4.13: The terminal shall not store -* in the UICC the call set-up details (called party number -* and associated parameters) -*/ - v->untracked = TRUE; - -if (v->call->status ==CALL_STATUS_ACTIVE ) -dial_request_finish (vc); - -if (need_to_emit) -voicecalls_emit_call_added (vc, v); -} -static void dial_request (struct ofono_voicecall *vc) { vc->driver->dial(vc, &vc->dial_req->ph, OFONO_CLIR_OPTION_DEFAULT,
Signature · 1 line
1.7.0.4
RFC PATCH 3/3 voicecall: add emergency call handling
In reply to Andras Domokos--- src/voicecall.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 121 insertions(+), 1 deletions(-)
src/voicecall.c +121 -1
@@ -52,6 +52,7 @@ struct ofono_voicecall {struct ofono_sim *sim;unsigned int sim_watch;unsigned int sim_state_watch; +unsigned int modem_online_watch;const struct ofono_voicecall_driver *driver;void *driver_data;struct ofono_atom *atom;
@@ -134,6 +135,22 @@ 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 ==NULL ) +return FALSE; + +return g_slist_find_custom (vc->en_list, + number, number_compare) ? TRUE : FALSE; +} +static const char *disconnect_reason_to_string (enum ofono_disconnect_reason r) {switch (r) {
@@ -1134,6 +1151,7 @@ handled:static void manager_dial_callback (const struct ofono_error *error,void *data) {struct ofono_voicecall *vc = data; +struct ofono_modem *modem =__ofono_atom_get_modem (vc->atom);DBusMessage *reply;const char *number;gboolean need_to_emit;
@@ -1152,8 +1170,12 @@ 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_modem_dec_emergency (modem); + reply =__ofono_error_failed (vc->pending); + }__ofono_dbus_pending_reply (&vc->pending, reply);
@@ -1165,6 +1187,7 @@ static DBusMessage *manager_dial(DBusConnection *conn, DBusMessage *msg, void *data) {struct ofono_voicecall *vc = data; +struct ofono_modem *modem =__ofono_atom_get_modem (vc->atom);const char *number;struct ofono_phone_number ph;const char *clirstr;
@@ -1204,6 +1227,16 @@ static DBusMessage *manager_dial(DBusConnection *conn,string_to_phone_number (number, &ph); +if (emergency_number (vc, number)) { +int online; + +ofono_modem_inc_emergency (modem); + + online =ofono_modem_get_online (modem); +if (online != TRUE) +return NULL ; + } + vc->driver->dial (vc, &ph, clir,OFONO_CUG_OPTION_DEFAULT , manager_dial_callback, vc);
@@ -1757,6 +1790,7 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id, const struct ofono_error *error) {struct ofono_modem *modem =__ofono_atom_get_modem (vc->atom); +const char *number;GSList *l;struct voicecall *call;time_t ts;
@@ -1776,6 +1810,7 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id, } call = l->data; + number =phone_number_to_string (&call->call->phone_number); ts =time (NULL ); prev_status = call->call->status;
@@ -1814,6 +1849,9 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id,voicecalls_emit_call_removed (vc, call); +if (emergency_number (vc, number)) +ofono_modem_dec_emergency (modem); +voicecall_dbus_unregister (vc, call); vc->call_list =g_slist_remove (vc->call_list, call);
@@ -2074,6 +2112,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);
@@ -2115,6 +2154,12 @@ static void voicecall_remove(struct ofono_atom *atom)g_queue_free (vc->toneq); } +if (vc->modem_online_watch) { +__ofono_modem_remove_online_watch (modem, + vc->modem_online_watch); + vc->modem_online_watch =0 ; + } +g_free (vc); }
@@ -2212,6 +2257,7 @@ static void sim_watch(struct ofono_atom *atom,static void dial_request_cb (const struct ofono_error *error,void *data) {struct ofono_voicecall *vc = data; +struct ofono_modem *modem =__ofono_atom_get_modem (vc->atom);gboolean need_to_emit;struct voicecall *v;
@@ -2221,6 +2267,10 @@ 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_modem_dec_emergency (modem);return ; }
@@ -2244,6 +2294,61 @@ static void dial_request_cb(const struct ofono_error *error, void *data)voicecalls_emit_call_added (vc, v); } +static void modem_online_watch (ofono_bool_t online,void *data) +{ +struct ofono_voicecall *vc = data; +struct ofono_modem *modem =__ofono_atom_get_modem (vc->atom); +static ofono_bool_t modem_online = FALSE; +static ofono_bool_t modem_online_prev; +const char *number; +struct ofono_phone_number ph; +const char *clirstr; +enum ofono_clir_option clir; + + modem_online_prev = modem_online; + modem_online = online; + +if (ofono_modem_get_emergency (modem) != TRUE) +return ; + +if (vc->dial_req) + vc->driver->dial (vc, &vc->dial_req->ph, +OFONO_CLIR_OPTION_DEFAULT , +OFONO_CUG_OPTION_DEFAULT , + dial_request_cb, vc); + +if (vc->pending ==NULL ) +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) +return ; + +if (emergency_number (vc, number) == FALSE) +return ; + +if (online == FALSE) { +if (online == modem_online_prev) { +DBusMessage *reply =__ofono_error_failed (vc->pending); + +__ofono_dbus_pending_reply (&vc->pending, reply); +ofono_modem_dec_emergency (modem); + } + +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); +} +void ofono_voicecall_register (struct ofono_voicecall *vc) {DBusConnection *conn =ofono_dbus_get_connection ();
@@ -2262,6 +2367,9 @@ void ofono_voicecall_register(struct ofono_voicecall *vc) }ofono_modem_add_interface (modem,OFONO_VOICECALL_MANAGER_INTERFACE ); + vc->modem_online_watch =__ofono_modem_add_online_watch (modem, + modem_online_watch, + vc,NULL );/* * Start out with the 22.101 mandated numbers, if we have a SIM and
@@ -2338,6 +2446,18 @@ ofono_bool_t __ofono_voicecall_is_busy(struct ofono_voicecall *vc,static void dial_request (struct ofono_voicecall *vc) { +struct ofono_modem *modem =__ofono_atom_get_modem (vc->atom); + +if (emergency_number (vc,phone_number_to_string (&vc->dial_req->ph))) { +int online; + +ofono_modem_inc_emergency (modem); + + online =ofono_modem_get_online (modem); +if (online != TRUE) +return ; + } + vc->driver->dial (vc, &vc->dial_req->ph,OFONO_CLIR_OPTION_DEFAULT ,OFONO_CUG_OPTION_DEFAULT , dial_request_cb, vc); }
Signature · 1 line
1.7.0.4