diff options
author | Luiz Augusto von Dentz <luiz.dentz-von@nokia.com> | 2011-01-10 15:05:45 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2011-01-10 21:35:40 +0200 |
commit | 9d7109c994bec237bdf1fff158d9400cbfb1b5c9 (patch) | |
tree | 2a58b08be7b7bb73449a7b84110030a46280d969 /audio | |
parent | a6099d662b4304e9255c53ab28f23358bb893cba (diff) |
telephony-ofono: add support for Three Way Calling feature
The Three Way Calling additionally support AT+CHLD values 0,3 and 4.
Diffstat (limited to 'audio')
-rw-r--r-- | audio/telephony-ofono.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c index fb32ca9a2..4e78801fa 100644 --- a/audio/telephony-ofono.c +++ b/audio/telephony-ofono.c @@ -48,6 +48,7 @@ struct voice_call { char *obj_path; int status; gboolean originating; + gboolean conference; char *number; guint watch; }; @@ -289,6 +290,33 @@ static int swap_calls(void) NULL, NULL, DBUS_TYPE_INVALID); } +static int create_conference(void) +{ + DBG(""); + return send_method_call(OFONO_BUS_NAME, modem_obj_path, + OFONO_VCMANAGER_INTERFACE, + "CreateMultiparty", + NULL, NULL, DBUS_TYPE_INVALID); +} + +static int release_conference(void) +{ + DBG(""); + return send_method_call(OFONO_BUS_NAME, modem_obj_path, + OFONO_VCMANAGER_INTERFACE, + "HangupMultiparty", + NULL, NULL, DBUS_TYPE_INVALID); +} + +static int call_transfer(void) +{ + DBG(""); + return send_method_call(OFONO_BUS_NAME, modem_obj_path, + OFONO_VCMANAGER_INTERFACE, + "Transfer", + NULL, NULL, DBUS_TYPE_INVALID); +} + void telephony_terminate_call_req(void *telephony_device) { struct voice_call *call; @@ -309,6 +337,8 @@ void telephony_terminate_call_req(void *telephony_device) alerting = find_vc_with_status(CALL_STATUS_ALERTING); if (call->status == CALL_STATUS_HELD && alerting) err = release_call(alerting); + else if (call->conference) + err = release_conference(); else err = release_call(call); @@ -431,15 +461,19 @@ void telephony_list_current_calls_req(void *telephony_device) for (l = calls, i = 1; l != NULL; l = l->next, i++) { struct voice_call *vc = l->data; - int direction; + int direction, multiparty; direction = vc->originating ? CALL_DIR_OUTGOING : CALL_DIR_INCOMING; - DBG("call %s direction %d", vc->number, direction); + multiparty = vc->conference ? + CALL_MULTIPARTY_YES : CALL_MULTIPARTY_NO; + + DBG("call %s direction %d multiparty %d", vc->number, + direction, multiparty); telephony_list_current_call_ind(i, direction, vc->status, - CALL_MODE_VOICE, CALL_MULTIPARTY_NO, + CALL_MODE_VOICE, multiparty, vc->number, number_type(vc->number)); } @@ -515,6 +549,14 @@ void telephony_call_hold_req(void *telephony_device, const char *cmd) err = swap_calls(); } break; + case '3': + if (find_vc_with_status(CALL_STATUS_HELD) || + find_vc_with_status(CALL_STATUS_WAITING)) + err = create_conference(); + break; + case '4': + err = call_transfer(); + break; default: DBG("Unknown call hold request"); break; @@ -679,6 +721,12 @@ static gboolean handle_vc_property_changed(DBusConnection *conn, "callheld", EV_CALLHELD_ON_HOLD); } + } else if (g_str_equal(property, "Multiparty")) { + dbus_bool_t multiparty; + + dbus_message_iter_get_basic(&sub, &multiparty); + DBG("Multiparty %s", multiparty ? "True" : "False"); + vc->conference = multiparty; } return TRUE; @@ -700,6 +748,7 @@ static struct voice_call *call_new(const char *path, DBusMessageIter *properties == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry, value; const char *property, *cli, *state; + dbus_bool_t multiparty; dbus_message_iter_recurse(properties, &entry); dbus_message_iter_get_basic(&entry, &property); @@ -724,6 +773,10 @@ static struct voice_call *call_new(const char *path, DBusMessageIter *properties vc->status = CALL_STATUS_WAITING; else if (g_str_equal(state, "held")) vc->status = CALL_STATUS_HELD; + } else if (g_str_equal(property, "Multiparty")) { + dbus_message_iter_get_basic(&value, &multiparty); + DBG("Multipary %s", multiparty ? "True" : "False"); + vc->conference = multiparty; } dbus_message_iter_next(properties); @@ -880,7 +933,8 @@ static int parse_network_properties(DBusMessageIter *properties) AG_FEATURE_REJECT_A_CALL | AG_FEATURE_ENHANCED_CALL_STATUS | AG_FEATURE_ENHANCED_CALL_CONTROL | - AG_FEATURE_EXTENDED_ERROR_RESULT_CODES; + AG_FEATURE_EXTENDED_ERROR_RESULT_CODES | + AG_FEATURE_THREE_WAY_CALLING; while (dbus_message_iter_get_arg_type(properties) == DBUS_TYPE_DICT_ENTRY) { |