* [PATCH 0/4] Emergency Calls
@ 2010-12-20 13:21 Andras Domokos
2010-12-20 13:21 ` [RFC PATCH 1/3] modem: add Emergency property Andras Domokos
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Andras Domokos @ 2010-12-20 13:21 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1194 bytes --]
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(-)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [RFC PATCH 1/3] modem: add Emergency property
2010-12-20 13:21 [PATCH 0/4] Emergency Calls Andras Domokos
@ 2010-12-20 13:21 ` Andras Domokos
2010-12-20 13:22 ` [RFC PATCH 2/3] modem: move dial request_cb function Andras Domokos
2010-12-20 13:22 ` [RFC PATCH 3/3] voicecall: add emergency call handling Andras Domokos
2 siblings, 0 replies; 4+ messages in thread
From: Andras Domokos @ 2010-12-20 13:21 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 11094 bytes --]
---
src/dbus.c | 7 ++
src/modem.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/ofono.h | 5 ++
3 files changed, 216 insertions(+), 3 deletions(-)
diff --git a/src/dbus.c b/src/dbus.c
index c24615f..3be8d22 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -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();
diff --git a/src/modem.c b/src/modem.c
index 2f9387c..1ad72bd 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -61,6 +61,8 @@ enum modem_state {
struct ofono_modem {
char *path;
enum modem_state modem_state;
+ enum modem_state modem_state_pre_emergency;
+ ofono_bool_t modem_state_pending;
GSList *atoms;
struct ofono_watchlist *atom_watches;
GSList *interface_list;
@@ -73,6 +75,7 @@ struct ofono_modem {
guint timeout;
ofono_bool_t online;
struct ofono_watchlist *online_watches;
+ unsigned int emergency;
GHashTable *properties;
struct ofono_sim *sim;
unsigned int sim_watch;
@@ -401,6 +404,11 @@ static void modem_change_state(struct ofono_modem *modem,
modem->modem_state = new_state;
+ if (modem->emergency > 0)
+ modem->modem_state_pre_emergency = new_state;
+
+ modem->modem_state_pending = FALSE;
+
if (old_state > new_state)
flush_atoms(modem, new_state);
@@ -440,11 +448,25 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *user)
switch (new_state) {
case OFONO_SIM_STATE_NOT_PRESENT:
+ if (modem->emergency != 0) {
+ modem->modem_state_pre_emergency = MODEM_STATE_PRE_SIM;
+ break;
+ }
+
modem_change_state(modem, MODEM_STATE_PRE_SIM);
break;
case OFONO_SIM_STATE_INSERTED:
break;
case OFONO_SIM_STATE_READY:
+ if (modem->emergency != 0) {
+ modem->modem_state_pre_emergency = MODEM_STATE_OFFLINE;
+
+ if (modem->driver->set_online == NULL)
+ modem->modem_state_pre_emergency = MODEM_STATE_ONLINE;
+
+ break;
+ }
+
modem_change_state(modem, MODEM_STATE_OFFLINE);
/*
@@ -482,6 +504,73 @@ void __ofono_modem_remove_online_watch(struct ofono_modem *modem,
__ofono_watchlist_remove_item(modem->online_watches, id);
}
+static void modem_change_online(struct ofono_modem *modem,
+ enum modem_state new_state)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ enum modem_state old_state = modem->modem_state;
+ ofono_bool_t new_online = new_state == MODEM_STATE_ONLINE;
+
+ DBG("old state: %d, new state: %d", old_state, new_state);
+
+ modem->modem_state = new_state;
+ modem->modem_state_pending = FALSE;
+ modem->online = new_online;
+
+ ofono_dbus_signal_property_changed(conn, modem->path,
+ OFONO_MODEM_INTERFACE, "Online",
+ DBUS_TYPE_BOOLEAN, &modem->online);
+
+ notify_online_watches(modem);
+}
+
+static void emergency_online_cb(const struct ofono_error *error, void *data)
+{
+ struct ofono_modem *modem = data;
+
+ DBG("modem: %p", modem);
+
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
+ modem->modem_state != MODEM_STATE_ONLINE) {
+ modem_change_online(modem, MODEM_STATE_ONLINE);
+ } else {
+ modem->modem_state_pending = FALSE;
+ notify_online_watches(modem);
+ }
+}
+
+static void emergency_offline_cb(const struct ofono_error *error, void *data)
+{
+ struct ofono_modem *modem = data;
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = ofono_modem_get_path(modem);
+ gboolean state = FALSE;
+
+ DBG("modem: %p", modem);
+
+ if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
+ modem->modem_state == MODEM_STATE_ONLINE) {
+ modem_change_online(modem, modem->modem_state_pre_emergency);
+ } else {
+ modem->modem_state_pending = FALSE;
+ notify_online_watches(modem);
+ }
+
+ modem->emergency--;
+ if (modem->emergency != 0) {
+ modem->modem_state_pending = TRUE;
+ modem->driver->set_online(modem, TRUE,
+ emergency_online_cb, modem);
+ return;
+ }
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_MODEM_INTERFACE,
+ "Emergency",
+ DBUS_TYPE_BOOLEAN,
+ &state);
+}
+
static void online_cb(const struct ofono_error *error, void *data)
{
struct ofono_modem *modem = data;
@@ -495,9 +584,18 @@ static void online_cb(const struct ofono_error *error, void *data)
__ofono_dbus_pending_reply(&modem->pending, reply);
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR &&
+ modem->emergency != 0) {
+ modem->modem_state_pending = FALSE;
+ notify_online_watches(modem);
+ return;
+ }
+
if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
modem->modem_state == MODEM_STATE_OFFLINE)
modem_change_state(modem, MODEM_STATE_ONLINE);
+ else
+ modem->modem_state_pending = FALSE;
}
static void offline_cb(const struct ofono_error *error, void *data)
@@ -512,9 +610,99 @@ static void offline_cb(const struct ofono_error *error, void *data)
__ofono_dbus_pending_reply(&modem->pending, reply);
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR &&
+ modem->emergency != 0) {
+ modem->modem_state_pending = FALSE;
+ notify_online_watches(modem);
+ return;
+ }
+
if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
- modem->modem_state == MODEM_STATE_ONLINE)
+ modem->modem_state == MODEM_STATE_ONLINE) {
modem_change_state(modem, MODEM_STATE_OFFLINE);
+
+ if (modem->emergency != 0) {
+ modem->modem_state_pending = TRUE;
+ modem->driver->set_online(modem, TRUE,
+ emergency_online_cb, modem);
+ }
+ } else {
+ modem->modem_state_pending = FALSE;
+ }
+}
+
+ofono_bool_t ofono_modem_get_emergency(struct ofono_modem *modem)
+{
+ if (modem == NULL)
+ return FALSE;
+
+ return modem->emergency != 0;
+}
+
+void ofono_modem_inc_emergency(struct ofono_modem *modem)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = ofono_modem_get_path(modem);
+ gboolean state = TRUE;
+
+ DBG("modem: %p", modem);
+
+ modem->emergency++;
+ if (modem->emergency > 1)
+ return;
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_MODEM_INTERFACE,
+ "Emergency",
+ DBUS_TYPE_BOOLEAN,
+ &state);
+
+ if (modem->modem_state_pending == TRUE)
+ return;
+
+ if (modem->modem_state == MODEM_STATE_ONLINE) {
+ modem->modem_state_pre_emergency = MODEM_STATE_ONLINE;
+ return;
+ }
+
+ modem->modem_state_pre_emergency = modem->modem_state;
+ modem->modem_state_pending = TRUE;
+ modem->driver->set_online(modem, TRUE, emergency_online_cb, modem);
+}
+
+void ofono_modem_dec_emergency(struct ofono_modem *modem)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = ofono_modem_get_path(modem);
+ gboolean state = FALSE;
+
+ DBG("modem: %p", modem);
+
+ if (modem->emergency == 0) {
+ ofono_error("Emergency reference counter already 0 on path %s",
+ modem->path);
+ return;
+ }
+
+ if (modem->emergency > 1) {
+ modem->emergency--;
+ return;
+ }
+
+ if (modem->modem_state_pre_emergency != MODEM_STATE_ONLINE) {
+ modem->modem_state_pending = TRUE;
+ modem->driver->set_online(modem, FALSE,
+ emergency_offline_cb, modem);
+ return;
+ }
+
+ modem->emergency--;
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_MODEM_INTERFACE,
+ "Emergency",
+ DBUS_TYPE_BOOLEAN,
+ &state);
}
static DBusMessage *set_property_online(struct ofono_modem *modem,
@@ -529,7 +717,10 @@ static DBusMessage *set_property_online(struct ofono_modem *modem,
dbus_message_iter_get_basic(var, &online);
- if (modem->pending != NULL)
+ if (modem->emergency > 0)
+ return __ofono_error_emergency_active(msg);
+
+ if (modem->modem_state_pending == TRUE)
return __ofono_error_busy(msg);
if (driver->set_online == NULL)
@@ -542,6 +733,7 @@ static DBusMessage *set_property_online(struct ofono_modem *modem,
return dbus_message_new_method_return(msg);
modem->pending = dbus_message_ref(msg);
+ modem->modem_state_pending = TRUE;
driver->set_online(modem, online,
online ? online_cb : offline_cb, modem);
@@ -551,7 +743,7 @@ static DBusMessage *set_property_online(struct ofono_modem *modem,
ofono_bool_t ofono_modem_get_online(struct ofono_modem *modem)
{
- if (modem == NULL)
+ if (modem == NULL || modem->modem_state_pending == TRUE)
return FALSE;
return modem->online;
@@ -565,6 +757,7 @@ void __ofono_modem_append_properties(struct ofono_modem *modem,
int i;
GSList *l;
struct ofono_atom *devinfo_atom;
+ ofono_bool_t val;
ofono_dbus_dict_append(dict, "Online", DBUS_TYPE_BOOLEAN,
&modem->online);
@@ -572,6 +765,10 @@ void __ofono_modem_append_properties(struct ofono_modem *modem,
ofono_dbus_dict_append(dict, "Powered", DBUS_TYPE_BOOLEAN,
&modem->powered);
+ val = ofono_modem_get_emergency(modem);
+ ofono_dbus_dict_append(dict, "Emergency",
+ DBUS_TYPE_BOOLEAN, &val);
+
devinfo_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_DEVINFO);
/* We cheat a little here and don't check the registered status */
@@ -650,6 +847,9 @@ static int set_powered(struct ofono_modem *modem, ofono_bool_t powered)
if (modem->powered_pending == powered)
return -EALREADY;
+ if (modem->emergency > 0)
+ return -EPERM;
+
/* Remove the atoms even if the driver is no longer available */
if (powered == FALSE)
modem_change_state(modem, MODEM_STATE_POWER_OFF);
@@ -1575,6 +1775,7 @@ static void modem_unregister(struct ofono_modem *modem)
if (modem->pending) {
dbus_message_unref(modem->pending);
modem->pending = NULL;
+ modem->modem_state_pending = FALSE;
}
if (modem->interface_update) {
diff --git a/src/ofono.h b/src/ofono.h
index 792134b..336d25b 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -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);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [RFC PATCH 2/3] modem: move dial request_cb function
2010-12-20 13:21 [PATCH 0/4] Emergency Calls Andras Domokos
2010-12-20 13:21 ` [RFC PATCH 1/3] modem: add Emergency property Andras Domokos
@ 2010-12-20 13:22 ` Andras Domokos
2010-12-20 13:22 ` [RFC PATCH 3/3] voicecall: add emergency call handling Andras Domokos
2 siblings, 0 replies; 4+ messages in thread
From: Andras Domokos @ 2010-12-20 13:22 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2445 bytes --]
---
src/voicecall.c | 70 +++++++++++++++++++++++++++---------------------------
1 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/src/voicecall.c b/src/voicecall.c
index dbf3e9a..0120cd0 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -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,
--
1.7.0.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [RFC PATCH 3/3] voicecall: add emergency call handling
2010-12-20 13:21 [PATCH 0/4] Emergency Calls Andras Domokos
2010-12-20 13:21 ` [RFC PATCH 1/3] modem: add Emergency property Andras Domokos
2010-12-20 13:22 ` [RFC PATCH 2/3] modem: move dial request_cb function Andras Domokos
@ 2010-12-20 13:22 ` Andras Domokos
2 siblings, 0 replies; 4+ messages in thread
From: Andras Domokos @ 2010-12-20 13:22 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 7232 bytes --]
---
src/voicecall.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 121 insertions(+), 1 deletions(-)
diff --git a/src/voicecall.c b/src/voicecall.c
index 0120cd0..370f760 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -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);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-12-20 13:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-20 13:21 [PATCH 0/4] Emergency Calls Andras Domokos
2010-12-20 13:21 ` [RFC PATCH 1/3] modem: add Emergency property Andras Domokos
2010-12-20 13:22 ` [RFC PATCH 2/3] modem: move dial request_cb function Andras Domokos
2010-12-20 13:22 ` [RFC PATCH 3/3] voicecall: add emergency call handling Andras Domokos
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.