From ba9f38b09ee44c275d6824e83966d1c061c54e45 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Wed, 28 Oct 2009 14:36:14 -0500 Subject: [PATCH] Fix: Take care of the logic for Dialing The logic for dialing a call while other calls are in the system is a bit more complicated than what was implemented. There are several cases to consider: - Active Call and Held Call In this situation we cannot dial, the user must drop one of the calls. - Active Call and Waiting Call -> We have to put the active call on hold, unfortunately there is no standard command to do so without affecting the waiting call. If the modem has a vendor specific implementation, then try to use that. - Active Call only -> Put the active call on hold. We use the swap_without_accept implementation (if exists) to be safe, otherwise we fall back to hold active calls. - No Active calls -> Simply dial --- src/voicecall.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/voicecall.c b/src/voicecall.c index ca78aaa..65ec517 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -932,6 +932,33 @@ static void dial_callback(const struct ofono_error *error, void *data) emit_call_list_changed(vc); } +static void swap_before_dial(const struct ofono_error *error, void *data) +{ + struct ofono_voicecall *vc = data; + const char *number; + const char *clirstr; + struct ofono_phone_number ph; + enum ofono_clir_option clir; + + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { + ofono_debug("Couldn't swap for dialing because: %s", + telephony_error_to_str(error)); + __ofono_dbus_pending_reply(&vc->pending, + __ofono_error_failed(vc->pending)); + return; + } + + dbus_message_get_args(vc->pending, NULL, DBUS_TYPE_STRING, &number, + DBUS_TYPE_STRING, &clirstr, + DBUS_TYPE_INVALID); + + string_to_phone_number(number, &ph); + clir_string_to_clir(clirstr, &clir); + + vc->driver->dial(vc, &ph, clir, OFONO_CUG_OPTION_DEFAULT, + dial_callback, vc); +} + static DBusMessage *manager_dial(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -940,6 +967,7 @@ static DBusMessage *manager_dial(DBusConnection *conn, struct ofono_phone_number ph; const char *clirstr; enum ofono_clir_option clir; + gboolean have_active; if (vc->pending) return __ofono_error_busy(msg); @@ -961,10 +989,45 @@ static DBusMessage *manager_dial(DBusConnection *conn, if (!vc->driver->dial) return __ofono_error_not_implemented(msg); - if (voicecalls_have_active(vc) && - voicecalls_have_held(vc)) + have_active = voicecalls_have_active(vc); + + if (have_active && voicecalls_have_held(vc)) return __ofono_error_failed(msg); + /* There are three cases we need to watch out for: + * - No Active Calls - Just Dial + * - Active Call - We have to swap first + * - Active and Waiting call - If we can swap without accepting, + * then do so, otherwise we should fail. + */ + + if (have_active && voicecalls_have_waiting(vc)) { + if (vc->driver->swap_without_accept == NULL) + return __ofono_error_failed(msg); + + vc->pending = dbus_message_ref(msg); + + vc->driver->swap_without_accept(vc, swap_before_dial, vc); + + return NULL; + } + + if (have_active) { + if (vc->driver->swap_without_accept == NULL && + vc->driver->hold_all_active == NULL) + return __ofono_error_failed(msg); + + vc->pending = dbus_message_ref(msg); + + if (vc->driver->swap_without_accept) + vc->driver->swap_without_accept(vc, swap_before_dial, + vc); + else + vc->driver->hold_all_active(vc, swap_before_dial, vc); + + return NULL; + } + vc->pending = dbus_message_ref(msg); string_to_phone_number(number, &ph); -- 2.7.4