summaryrefslogtreecommitdiffstats
path: root/drivers/isimodem/voicecall.c
diff options
context:
space:
mode:
authorPekka Pessi <Pekka.Pessi@nokia.com>2010-12-03 10:30:50 +0200
committerAki Niemi <aki.niemi@nokia.com>2010-12-03 14:52:40 +0200
commita67c5cf4c5493ceb17167bda641ddbff597c16a0 (patch)
treef16f06513b527c0789ddadc164a8c538373cd396 /drivers/isimodem/voicecall.c
parentbe2778cb9913bad89c827a335c2ef664afc3df51 (diff)
downloadofono-a67c5cf4c5493ceb17167bda641ddbff597c16a0.tar.bz2
isi/voicecall: fix handling of waiting calls
Also, do not retrieve calls after isi_release_all_active() because retrieving is now only an unwanted side-effect .
Diffstat (limited to 'drivers/isimodem/voicecall.c')
-rw-r--r--drivers/isimodem/voicecall.c114
1 files changed, 56 insertions, 58 deletions
diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
index 9c1bec72..f2fd53aa 100644
--- a/drivers/isimodem/voicecall.c
+++ b/drivers/isimodem/voicecall.c
@@ -1060,65 +1060,59 @@ static void isi_retrieve(struct ofono_voicecall *ovc,
isi_call_control_req(ovc, CALL_ID_HOLD, CALL_OP_RETRIEVE, 0, cb, data);
}
-static isi_call_req_step isi_wait_and_answer, isi_wait_and_retrieve;
+static void isi_wait_and_answer(struct isi_call_req_context *irc,
+ int id, int status)
+{
+ DBG("irc=%p id=%d status=%d", (void *)irc, id, status);
+
+ if (id != irc->id)
+ return;
+
+ switch (status) {
+ case CALL_STATUS_MT_ALERTING:
+ isi_call_answer_req(irc->ovc, irc->id, irc->cb, irc->data);
+ isi_ctx_free(irc);
+ break;
+
+ default:
+ isi_ctx_return_failure(irc);
+ break;
+ }
+}
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;
for (id = 1; id <= 7; id++) {
if (ivc->calls[id].call_id & CALL_ID_WAITING)
- waiting++;
- if (ivc->calls[id].call_id & CALL_ID_HOLD)
- hold++;
+ waiting_id = id;
+
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_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);
-}
-
-static void isi_wait_and_answer(struct isi_call_req_context *irc,
- int id, int status)
-{
- DBG("irc=%p id=%d status=%d", (void *)irc, id, status);
-
- switch (status) {
- case CALL_STATUS_TERMINATED:
- isi_answer(irc->ovc, irc->cb, irc->data);
- isi_ctx_free(irc);
- break;
+ return;
}
-}
-static void isi_wait_and_retrieve(struct isi_call_req_context *irc,
- int id, int status)
-{
- DBG("irc=%p id=%u status=%u", (void *)irc, id, status);
+ irc = isi_call_release_req(ovc, CALL_ID_ACTIVE,
+ CALL_CAUSE_RELEASE_BY_USER,
+ cb, data);
+ if (irc == NULL)
+ return;
- switch (status) {
- case CALL_STATUS_TERMINATED:
- isi_retrieve(irc->ovc, irc->cb, irc->data);
- isi_ctx_free(irc);
- break;
- }
+ if (waiting_id)
+ isi_ctx_queue(irc, isi_wait_and_answer, waiting_id);
+
+ /* Retrieving held calls is currently a unwanted side-effect */
}
static void isi_hold_all_active(struct ofono_voicecall *ovc,
@@ -1126,34 +1120,38 @@ static void isi_hold_all_active(struct ofono_voicecall *ovc,
{
/* AT+CHLD=2 */
struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
- int id = 0, op = 0, waiting = 0, active = 0, hold = 0;
+ int id;
+ int waiting = 0;
+ int active = 0;
+ int hold = 0;
+ int op;
for (id = 1; id <= 7; id++) {
if (ivc->calls[id].call_id & CALL_ID_WAITING)
waiting++;
- if (ivc->calls[id].call_id & CALL_ID_HOLD)
+ else if (ivc->calls[id].call_id & CALL_ID_HOLD)
hold++;
- if (ivc->calls[id].call_id & CALL_ID_ACTIVE)
+ else if (ivc->calls[id].call_id & CALL_ID_ACTIVE)
active++;
}
if (waiting) {
isi_call_answer_req(ovc, CALL_ID_WAITING, cb, data);
- } else if (hold) {
- if (active) {
+ return;
+ }
+
+ if (active) {
+ if (hold)
op = CALL_OP_SWAP;
- id = CALL_ID_ACTIVE;
- } else {
- op = CALL_OP_RETRIEVE;
- id = CALL_ID_HOLD;
- }
- isi_call_control_req(ovc, id, op, 0, cb, data);
- } else if (active) {
- id = CALL_ID_ACTIVE, op = CALL_OP_HOLD;
- isi_call_control_req(ovc, id, op, 0, cb, data);
- } else {
+ else
+ op = CALL_OP_HOLD;
+
+ isi_call_control_req(ovc, CALL_ID_ACTIVE, op, 0, cb, data);
+
+ } else if (hold)
+ isi_retrieve(ovc, cb, data);
+ else
CALLBACK_WITH_FAILURE(cb, data);
- }
}
static void isi_release_specific(struct ofono_voicecall *ovc, int id,