--- include/types.h | 2 + src/voicecall.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 239 insertions(+), 3 deletions(-)
diff --git a/include/types.h b/include/types.h index d25f409..b639c8a 100644 --- a/include/types.h +++ b/include/types.h @@ -96,6 +96,8 @@ struct ofono_call { char name[OFONO_MAX_CALLER_NAME_LENGTH + 1]; int clip_validity; int cnap_validity; + ofono_bool_t remote_held; + ofono_bool_t remote_multiparty; }; struct ofono_network_time { diff --git a/src/voicecall.c b/src/voicecall.c index d6e8539..1fa9f41 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -53,6 +53,14 @@ struct ofono_voicecall { struct ofono_sim_context *sim_context; unsigned int sim_watch; unsigned int sim_state_watch; + struct ofono_ssn *ssn; + unsigned int ssn_mt_fwd_watch; + unsigned int ssn_mt_hold_watch; + unsigned int ssn_mt_unhold_watch; + unsigned int ssn_mt_mpty_watch; + unsigned int ssn_mo_fwd_watch; + unsigned int ssn_mo_local_bar_watch; + unsigned int ssn_mo_remote_bar_watch; const struct ofono_voicecall_driver *driver; void *driver_data; struct ofono_atom *atom; @@ -400,6 +408,12 @@ static void append_voicecall_properties(struct voicecall *v, ofono_dbus_dict_append(dict, "Multiparty", DBUS_TYPE_BOOLEAN, &mpty); + ofono_dbus_dict_append(dict, "RemoteHeld", DBUS_TYPE_BOOLEAN, + &call->remote_held); + + ofono_dbus_dict_append(dict, "RemoteMultiparty", DBUS_TYPE_BOOLEAN, + &call->remote_multiparty); + if (v->message) ofono_dbus_dict_append(dict, "Information", DBUS_TYPE_STRING, &v->message); @@ -1869,9 +1883,11 @@ static GDBusMethodTable manager_methods[] = { }; static GDBusSignalTable manager_signals[] = { - { "PropertyChanged", "sv" }, - { "CallAdded", "oa{sv}" }, - { "CallRemoved", "o" }, + { "Forwarded", "s" }, + { "BarringActive", "s" }, + { "PropertyChanged", "sv" }, + { "CallAdded", "oa{sv}" }, + { "CallRemoved", "o" }, { } }; @@ -2169,6 +2185,46 @@ void ofono_voicecall_driver_unregister(const struct ofono_voicecall_driver *d) g_drivers = g_slist_remove(g_drivers, (void *) d); } +static void voicecall_ssn_watches_remove(struct ofono_voicecall *vc) +{ + if (vc->ssn_mt_fwd_watch) { + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_mt_fwd_watch); + vc->ssn_mt_fwd_watch = 0; + } + + if (vc->ssn_mt_hold_watch) { + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_mt_hold_watch); + vc->ssn_mt_hold_watch = 0; + } + + if (vc->ssn_mt_unhold_watch) { + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_mt_unhold_watch); + vc->ssn_mt_unhold_watch = 0; + } + + if (vc->ssn_mt_mpty_watch) { + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_mt_mpty_watch); + vc->ssn_mt_mpty_watch = 0; + } + + if (vc->ssn_mo_fwd_watch) { + __ofono_ssn_mt_watch_remove(vc->ssn, vc->ssn_mo_fwd_watch); + vc->ssn_mo_fwd_watch = 0; + } + + if (vc->ssn_mo_local_bar_watch) { + __ofono_ssn_mt_watch_remove(vc->ssn, + vc->ssn_mo_local_bar_watch); + vc->ssn_mo_local_bar_watch = 0; + } + + if (vc->ssn_mo_remote_bar_watch) { + __ofono_ssn_mo_watch_remove(vc->ssn, + vc->ssn_mo_remote_bar_watch); + vc->ssn_mo_remote_bar_watch = 0; + } +} + static void voicecall_unregister(struct ofono_atom *atom) { DBusConnection *conn = ofono_dbus_get_connection(); @@ -2182,6 +2238,9 @@ static void voicecall_unregister(struct ofono_atom *atom) vc->sim_watch = 0; } + if (vc->ssn) + voicecall_ssn_watches_remove(vc); + if (vc->dial_req) dial_request_finish(vc); @@ -2239,6 +2298,11 @@ static void voicecall_remove(struct ofono_atom *atom) g_queue_free(vc->toneq); } + if (vc->ssn) { + ofono_ssn_free(vc->ssn); + vc->ssn = NULL; + } + g_free(vc); } @@ -2258,6 +2322,8 @@ struct ofono_voicecall *ofono_voicecall_create(struct ofono_modem *modem, if (vc == NULL) return NULL; + vc->ssn = ofono_ssn_new(modem, vendor, driver, data); + vc->toneq = g_queue_new(); vc->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_VOICECALL, @@ -2351,6 +2417,171 @@ static void sim_watch(struct ofono_atom *atom, sim_state_watch(ofono_sim_get_state(sim), vc); } +static void ssn_mt_forwarded_notify(unsigned int id, int code1, int idx, + const struct ofono_phone_number *ph, + void *data) +{ + struct ofono_voicecall *vc = data; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(vc->atom); + char *info = "incoming"; + + g_dbus_emit_signal(conn, path, OFONO_VOICECALL_MANAGER_INTERFACE, + "Forwarded", + DBUS_TYPE_STRING, &info, + DBUS_TYPE_INVALID); +} + +static struct voicecall *voicecall_select(struct ofono_voicecall *vc, + unsigned int id, int code) +{ + struct voicecall *v = NULL; + GSList *l; + + for (l = vc->call_list; l; l = l->next) { + struct voicecall *v1 = l->data; + + if (id == 0 && g_slist_length(vc->call_list) == 1) { + if (code == SS_MT_VOICECALL_RETRIEVED && + v1->call->remote_held == TRUE) { + v = v1; + break; + } else if (code == SS_MT_VOICECALL_ON_HOLD && + v1->call->remote_held == FALSE) { + v = v1; + break; + } else if (code == SS_MT_MULTIPARTY_VOICECALL && + v1->call->remote_multiparty == FALSE) { + v = v1; + break; + } + } else if (v1->call->id == id) { + v = v1; + break; + } + } + + return v; +} + +static void ssn_mt_remote_held_notify(unsigned int id, int code1, int idx, + const struct ofono_phone_number *ph, + void *data) +{ + struct ofono_voicecall *vc = data; + struct voicecall *v = voicecall_select(vc, id, code1); + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path; + + if (v == NULL) + return; + + if (code1 == SS_MT_VOICECALL_ON_HOLD) + v->call->remote_held = TRUE; + else + v->call->remote_held = FALSE; + + path = voicecall_build_path(vc, v->call); + + ofono_dbus_signal_property_changed(conn, path, + OFONO_VOICECALL_INTERFACE, + "RemoteHeld", DBUS_TYPE_BOOLEAN, + &v->call->remote_held); +} + +static void ssn_mt_remote_multiparty_notify(unsigned int id, int code1, int idx, + const struct ofono_phone_number *ph, + void *data) +{ + struct ofono_voicecall *vc = data; + struct voicecall *v = voicecall_select(vc, id, code1); + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path; + + if (v == NULL) + return; + + v->call->remote_multiparty = TRUE; + + path = voicecall_build_path(vc, v->call); + + ofono_dbus_signal_property_changed(conn, path, + OFONO_VOICECALL_INTERFACE, + "RemoteMultiparty", DBUS_TYPE_BOOLEAN, + &v->call->remote_multiparty); +} + +static void ssn_mo_call_barred_notify(unsigned int id, int code2, + int idx, void *data) +{ + struct ofono_voicecall *vc = data; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(vc->atom); + const char *info; + + if (code2 == SS_MO_INCOMING_BARRING) + info = "remote"; + else + info = "local"; + + g_dbus_emit_signal(conn, path, OFONO_VOICECALL_MANAGER_INTERFACE, + "BarringActive", + DBUS_TYPE_STRING, &info, + DBUS_TYPE_INVALID); +} + +static void ssn_mo_forwarded_notify(unsigned int id, int code2, + int idx, void *data) +{ + struct ofono_voicecall *vc = data; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(vc->atom); + char *info = "outgoing"; + + g_dbus_emit_signal(conn, path, OFONO_VOICECALL_MANAGER_INTERFACE, + "Forwarded", + DBUS_TYPE_STRING, &info, + DBUS_TYPE_INVALID); +} + +static void voicecall_ssn_watches_add(struct ofono_voicecall *vc) +{ + vc->ssn_mt_fwd_watch = __ofono_ssn_mt_watch_add(vc->ssn, + SS_MT_CALL_FORWARDED, + ssn_mt_forwarded_notify, + vc, NULL); + + vc->ssn_mt_hold_watch = __ofono_ssn_mt_watch_add(vc->ssn, + SS_MT_VOICECALL_ON_HOLD, + ssn_mt_remote_held_notify, + vc, NULL); + + vc->ssn_mt_unhold_watch = __ofono_ssn_mt_watch_add(vc->ssn, + SS_MT_VOICECALL_RETRIEVED, + ssn_mt_remote_held_notify, + vc, NULL); + + vc->ssn_mt_mpty_watch = __ofono_ssn_mt_watch_add(vc->ssn, + SS_MT_MULTIPARTY_VOICECALL, + ssn_mt_remote_multiparty_notify, + vc, NULL); + + vc->ssn_mo_fwd_watch = __ofono_ssn_mo_watch_add(vc->ssn, + SS_MO_CALL_FORWARDED, + ssn_mo_forwarded_notify, + vc, NULL); + + vc->ssn_mo_local_bar_watch = __ofono_ssn_mo_watch_add(vc->ssn, + SS_MO_OUTGOING_BARRING, + ssn_mo_call_barred_notify, + vc, NULL); + + vc->ssn_mo_remote_bar_watch = __ofono_ssn_mo_watch_add(vc->ssn, + SS_MO_INCOMING_BARRING, + ssn_mo_call_barred_notify, + vc, NULL); +} + void ofono_voicecall_register(struct ofono_voicecall *vc) { DBusConnection *conn = ofono_dbus_get_connection(); @@ -2377,6 +2608,9 @@ void ofono_voicecall_register(struct ofono_voicecall *vc) add_to_en_list(&vc->en_list, default_en_list_no_sim); add_to_en_list(&vc->en_list, default_en_list); + if (vc->ssn != NULL) + voicecall_ssn_watches_add(vc); + vc->sim_watch = __ofono_modem_add_atom_watch(modem, OFONO_ATOM_TYPE_SIM, sim_watch, vc, NULL); -- 1.7.0.4 _______________________________________________ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono