From: Pekka Pessi <pekka.pe...@nokia.com> Watch supplementary service notifications from barring services, remote party putting call on hold, retrieving or join call into a multiparty conference.
The barring indications augment the DisconnectReason and they contain additional information about the reason why a call is rejected or why it is not connected. --- src/voicecall.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 147 insertions(+), 0 deletions(-) diff --git a/src/voicecall.c b/src/voicecall.c index 6246787..e176e02 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -52,6 +52,12 @@ struct ofono_voicecall { struct ofono_sim *sim; unsigned int sim_watch; unsigned int sim_state_watch; + struct ofono_ssn *ssn; + unsigned int ssn_watch; + unsigned int ssn_hold_watch; + unsigned int ssn_retrieve_watch; + unsigned int ssn_mpty_watch; + unsigned int ssn_wait_watch; const struct ofono_voicecall_driver *driver; void *driver_data; struct ofono_atom *atom; @@ -69,6 +75,7 @@ struct voicecall { uint8_t icon_id; gboolean untracked; gboolean dial_result_handled; + dbus_bool_t mt_hold; }; struct dial_request { @@ -399,6 +406,8 @@ static void append_voicecall_properties(struct voicecall *v, ofono_dbus_dict_append(dict, "Multiparty", DBUS_TYPE_BOOLEAN, &mpty); + ofono_dbus_dict_append(dict, "OnHold", DBUS_TYPE_BOOLEAN, &v->mt_hold); + if (v->message) ofono_dbus_dict_append(dict, "Information", DBUS_TYPE_STRING, &v->message); @@ -655,6 +664,19 @@ static const char *voicecall_build_path(struct ofono_voicecall *vc, return path; } +static struct voicecall *voicecall_by_id(struct ofono_voicecall *vc, int id) +{ + GSList *l; + + l = g_slist_find_custom(vc->call_list, GUINT_TO_POINTER(id), + call_compare_by_id); + if (l == NULL) + return NULL; + + return l->data; +} + + static void voicecall_emit_disconnect_reason(struct voicecall *call, enum ofono_disconnect_reason reason) { @@ -2181,6 +2203,19 @@ static void voicecall_unregister(struct ofono_atom *atom) vc->sim_watch = 0; } + if (vc->ssn_watch) { + __ofono_modem_remove_atom_watch(modem, vc->ssn_watch); + vc->ssn_watch = 0; + } + + if (vc->ssn) { + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_hold_watch); + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_retrieve_watch); + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_mpty_watch); + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_wait_watch); + vc->ssn = NULL; + } + if (vc->dial_req) dial_request_finish(vc); @@ -2278,6 +2313,108 @@ struct ofono_voicecall *ofono_voicecall_create(struct ofono_modem *modem, return vc; } +static void ssn_mo_watch(int index, int mo_code, void *user) +{ + struct ofono_voicecall *vc = user; + struct voicecall *call; + DBusConnection *conn; + char const *path; + char const *member; + + call = voicecall_by_id(vc, index); + if (call == NULL) { + ofono_error("Got MO SSN notify %u for unknown call", mo_code); + return; + } + + conn = ofono_dbus_get_connection(); + path = voicecall_build_path(vc, call->call); + + switch (mo_code) { + case OFONO_SS_MO_CALL_WAITING: + member = "Waiting"; + break; + case OFONO_SS_MO_INCOMING_BARRING: + member = "IncomingBarred"; + break; + case OFONO_SS_MO_OUTGOING_BARRING: + member = "OutgoingBarred"; + break; + default: + return; + } + + g_dbus_emit_signal(conn, path, OFONO_VOICECALL_INTERFACE, + member, DBUS_TYPE_INVALID); +} + +static void ssn_mt_watch(int index, int mt_code, + const struct ofono_phone_number *ph, + void *user) +{ + struct ofono_voicecall *vc = user; + struct voicecall *call; + DBusConnection *conn; + char const *path; + dbus_bool_t mt_hold; + + call = voicecall_by_id(vc, index); + if (call == NULL) { + ofono_error("Got MT SSN notify %u for unknown call", mt_code); + return; + } + + conn = ofono_dbus_get_connection(); + path = voicecall_build_path(vc, call->call); + + switch (mt_code) { + case OFONO_SS_MT_VOICECALL_ON_HOLD: + call->mt_hold = mt_hold = TRUE; + break; + + case OFONO_SS_MT_VOICECALL_RETRIEVED: + call->mt_hold = mt_hold = FALSE; + break; + + case OFONO_SS_MT_MULTIPARTY_VOICECALL: + g_dbus_emit_signal(conn, path, OFONO_VOICECALL_INTERFACE, + "JoinedMultiparty", DBUS_TYPE_INVALID); + return; + + default: + return; + } + + ofono_dbus_signal_property_changed(conn, path, + OFONO_VOICECALL_INTERFACE, "OnHold", + DBUS_TYPE_BOOLEAN, &mt_hold); +} + +static void ssn_watch(struct ofono_atom *atom, + enum ofono_atom_watch_condition cond, void *data) +{ + struct ofono_voicecall *vc = data; + + if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) { + vc->ssn = NULL; + return; + } + + vc->ssn = __ofono_atom_get_data(atom); + + vc->ssn_hold_watch = __ofono_ssn_mt_watch_add(vc->ssn, + OFONO_SS_MT_VOICECALL_ON_HOLD, ssn_mt_watch, vc, NULL); + + vc->ssn_retrieve_watch = __ofono_ssn_mt_watch_add(vc->ssn, + OFONO_SS_MT_VOICECALL_RETRIEVED, ssn_mt_watch, vc, NULL); + + vc->ssn_mpty_watch = __ofono_ssn_mt_watch_add(vc->ssn, + OFONO_SS_MT_MULTIPARTY_VOICECALL, ssn_mt_watch, vc, NULL); + + vc->ssn_wait_watch = __ofono_ssn_mo_watch_add(vc->ssn, + OFONO_SS_MO_CALL_WAITING, ssn_mo_watch, vc, NULL); +} + static void sim_state_watch(enum ofono_sim_state new_state, void *user) { struct ofono_voicecall *vc = user; @@ -2338,6 +2475,7 @@ void ofono_voicecall_register(struct ofono_voicecall *vc) struct ofono_modem *modem = __ofono_atom_get_modem(vc->atom); const char *path = __ofono_atom_get_path(vc->atom); struct ofono_atom *sim_atom; + struct ofono_atom *ssn_atom; if (!g_dbus_register_interface(conn, path, OFONO_VOICECALL_MANAGER_INTERFACE, @@ -2367,6 +2505,15 @@ void ofono_voicecall_register(struct ofono_voicecall *vc) if (sim_atom && __ofono_atom_get_registered(sim_atom)) sim_watch(sim_atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, vc); + vc->ssn_watch = __ofono_modem_add_atom_watch(modem, + OFONO_ATOM_TYPE_SSN, + ssn_watch, vc, NULL); + + ssn_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM); + + if (ssn_atom && __ofono_atom_get_registered(ssn_atom)) + ssn_watch(ssn_atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, vc); + __ofono_atom_register(vc->atom, voicecall_unregister); } -- 1.7.1 _______________________________________________ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono