From: Pekka Pessi <pekka.pe...@nokia.com>

Handle to-be-waiting calls properly.
---
 drivers/isimodem/voicecall.c |   66 +++++++++++++++++++++++++++++------------
 1 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
index cdd5d11..360994a 100644
--- a/drivers/isimodem/voicecall.c
+++ b/drivers/isimodem/voicecall.c
@@ -292,6 +292,23 @@ static int isi_call_status_to_clcc(struct isi_voicecall 
const *ivc,
        return CLCC_STATUS_ACTIVE;
 }
 
+static gboolean is_call_waiting(struct isi_voicecall const *ivc,
+                               struct isi_call const *call)
+{
+       if (!(call->mode_info & CALL_MODE_ORIGINATOR))
+               return FALSE;
+
+       switch (call->status) {
+       case CALL_STATUS_COMING:
+       case CALL_STATUS_PROCEEDING:
+               return isi_call_waiting_or_incoming(ivc) == CLCC_STATUS_WAITING;
+       case CALL_STATUS_WAITING:
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static struct ofono_call isi_call_as_ofono_call(struct isi_voicecall const 
*ivc,
                                                struct isi_call const *call)
 {
@@ -1119,35 +1136,40 @@ static isi_call_req_step isi_wait_and_answer, 
isi_wait_and_retrieve;
 static void isi_release_all_active(struct ofono_voicecall *ovc,
                                        ofono_voicecall_cb_t cb, void *data)
 {
-       /* AT+CHLD=1 */
        struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
-       int id = 0, waiting = 0, active = 0, hold = 0;
+       struct isi_call_req_context *irc;
+       int id;
+       int waiting_id = 0;
+       int active = 0;
+       int hold = 0;
 
        for (id = 1; id <= 7; id++) {
-               if (ivc->calls[id].call_id & CALL_ID_WAITING)
-                       waiting++;
+               if (is_call_waiting(ivc, &ivc->calls[id]))
+                       waiting_id = id;
+
                if (ivc->calls[id].call_id & CALL_ID_HOLD)
                        hold++;
+
                if (ivc->calls[id].call_id & CALL_ID_ACTIVE)
                        active++;
        }
 
-       if (active) {
-               struct isi_call_req_context *irc;
-
-               irc = isi_call_release_req(ovc, CALL_ID_ACTIVE,
-                                               CALL_CAUSE_TYPE_CLIENT,
-                                               CALL_CAUSE_RELEASE_BY_USER,
-                                               cb, data);
-
-               if (irc == NULL)
-                       ;
-               else if (waiting)
-                       isi_ctx_queue(irc, isi_wait_and_answer, 0);
-               else if (hold)
-                       isi_ctx_queue(irc, isi_wait_and_retrieve, 0);
-       } else
+       if (!active) {
                CALLBACK_WITH_FAILURE(cb, data);
+               return;
+       }
+
+       irc = isi_call_release_req(ovc, CALL_ID_ACTIVE,
+                                       CALL_CAUSE_TYPE_CLIENT,
+                                       CALL_CAUSE_RELEASE_BY_USER,
+                                       cb, data);
+       if (!irc)
+               return;
+
+       if (waiting_id)
+               isi_ctx_queue(irc, isi_wait_and_answer, waiting_id);
+       else if (hold)
+               isi_ctx_queue(irc, isi_wait_and_retrieve, 0);
 }
 
 static void isi_wait_and_answer(struct isi_call_req_context *irc,
@@ -1155,8 +1177,10 @@ static void isi_wait_and_answer(struct 
isi_call_req_context *irc,
 {
        DBG("irc=%p event=%u", (void *)irc, event);
        switch (event) {
+       case CALL_STATUS_MO_RELEASE:
+       case CALL_STATUS_MT_RELEASE:
        case CALL_STATUS_TERMINATED:
-               isi_answer(irc->ovc, irc->cb, irc->data);
+               isi_call_answer_req(irc->ovc, irc->id, irc->cb, irc->data);
                isi_ctx_free(irc);
                break;
        }
@@ -1167,6 +1191,8 @@ static void isi_wait_and_retrieve(struct 
isi_call_req_context *irc,
 {
        DBG("irc=%p event=%u", (void *)irc, event);
        switch (event) {
+       case CALL_STATUS_MO_RELEASE:
+       case CALL_STATUS_MT_RELEASE:
        case CALL_STATUS_TERMINATED:
                isi_retrieve(irc->ovc, irc->cb, irc->data);
                isi_ctx_free(irc);
-- 
1.7.1

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to