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.
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