* [fix-isi-voicecall PATCHv5 0/4] Call state fixes
@ 2010-12-03 8:30 Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 1/4] isi/voicecall: fix status reporting Pekka.Pessi
2010-12-03 12:59 ` [fix-isi-voicecall PATCHv5 0/4] Call state fixes Aki Niemi
0 siblings, 2 replies; 6+ messages in thread
From: Pekka.Pessi @ 2010-12-03 8:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 96 bytes --]
Hi all,
Here are the isi voicecall patches again, rebased with the NULL fixes.
--Pekka
^ permalink raw reply [flat|nested] 6+ messages in thread
* [fix-isi-voicecall PATCHv5 1/4] isi/voicecall: fix status reporting
2010-12-03 8:30 [fix-isi-voicecall PATCHv5 0/4] Call state fixes Pekka.Pessi
@ 2010-12-03 8:30 ` Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 2/4] isi/voicecall: add call id to queued requests Pekka.Pessi
2010-12-03 12:59 ` [fix-isi-voicecall PATCHv5 0/4] Call state fixes Aki Niemi
1 sibling, 1 reply; 6+ messages in thread
From: Pekka.Pessi @ 2010-12-03 8:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 13003 bytes --]
From: Pekka Pessi <Pekka.Pessi@nokia.com>
Do not report incoming calls to the oFono core until they can be
answered.
Report MT_RELEASED or MO_RELEASED via ofono_voicecall_notify(),
TERMINATED calls via ofono_voicecall_disconnected().
---
drivers/isimodem/voicecall.c | 387 ++++++++++++++++++++---------------------
1 files changed, 189 insertions(+), 198 deletions(-)
diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
index 84b77d1..b89cbb3 100644
--- a/drivers/isimodem/voicecall.c
+++ b/drivers/isimodem/voicecall.c
@@ -62,13 +62,6 @@ struct isi_voicecall {
/* ------------------------------------------------------------------------- */
-static void isi_call_notify(struct ofono_voicecall *ovc,
- struct isi_call *call);
-static void isi_call_release(struct ofono_voicecall *, struct isi_call *);
-static struct ofono_call isi_call_as_ofono_call(struct isi_call const *);
-static int isi_call_status_to_clcc(struct isi_call const *call);
-static struct isi_call *isi_call_set_idle(struct isi_call *call);
-
typedef void GIsiIndication(GIsiClient *client,
const void *restrict data, size_t len,
uint16_t object, void *opaque);
@@ -80,9 +73,6 @@ typedef gboolean GIsiResponse(GIsiClient *client,
void const *restrict data, size_t len,
uint16_t object, void *opaque);
-static GIsiVerify isi_call_verify_cb;
-static gboolean isi_call_register(gpointer);
-
enum {
ISI_CALL_TIMEOUT = 1000,
};
@@ -205,6 +195,159 @@ static gboolean isi_ctx_return_success(struct isi_call_req_context *irc)
}
/* ------------------------------------------------------------------------- */
+/* Notify */
+
+enum clcc_status {
+ CLCC_STATUS_EARLY = -1,
+ CLCC_STATUS_ACTIVE = 0,
+ CLCC_STATUS_HOLD = 1,
+ CLCC_STATUS_DIALING = 2,
+ CLCC_STATUS_ALERTING = 3,
+ CLCC_STATUS_INCOMING = 4,
+ CLCC_STATUS_WAITING = 5,
+ CLCC_STATUS_DISCONNECTED = 6,
+};
+
+/** Get +CLCC status */
+static int isi_call_status_to_clcc(struct isi_voicecall const *ivc,
+ struct isi_call const *call)
+{
+ switch (call->status) {
+ case CALL_STATUS_CREATE:
+ return CLCC_STATUS_DIALING;
+
+ case CALL_STATUS_COMING:
+ return CLCC_STATUS_EARLY;
+
+ case CALL_STATUS_PROCEEDING:
+ if ((call->mode_info & CALL_MODE_ORIGINATOR))
+ return CLCC_STATUS_EARLY; /* MT */
+ else
+ return CLCC_STATUS_DIALING; /* MO */
+
+ case CALL_STATUS_MO_ALERTING:
+ return CLCC_STATUS_ALERTING;
+
+ case CALL_STATUS_MT_ALERTING:
+ return CLCC_STATUS_INCOMING;
+
+ case CALL_STATUS_WAITING:
+ return CLCC_STATUS_WAITING;
+
+ case CALL_STATUS_ANSWERED:
+ case CALL_STATUS_ACTIVE:
+ case CALL_STATUS_HOLD_INITIATED:
+ case CALL_STATUS_RECONNECT_PENDING:
+ case CALL_STATUS_SWAP_INITIATED:
+ return CLCC_STATUS_ACTIVE;
+
+ case CALL_STATUS_HOLD:
+ case CALL_STATUS_RETRIEVE_INITIATED:
+ return CLCC_STATUS_HOLD;
+
+ case CALL_STATUS_MO_RELEASE:
+ case CALL_STATUS_MT_RELEASE:
+ case CALL_STATUS_TERMINATED:
+ case CALL_STATUS_IDLE:
+ return CLCC_STATUS_DISCONNECTED;
+ }
+
+ return CLCC_STATUS_ACTIVE;
+}
+
+static struct ofono_call isi_call_as_ofono_call(struct isi_voicecall const *ivc,
+ struct isi_call const *call)
+{
+ struct ofono_call ocall = { call->id };
+ struct ofono_phone_number *number = &ocall.phone_number;
+
+ ocall.type = 0; /* Voice call */
+ ocall.direction = call->mode_info & CALL_MODE_ORIGINATOR;
+ ocall.status = isi_call_status_to_clcc(ivc, call);
+ memcpy(number->number, call->address, sizeof(number->number));
+ number->type = 0x80 | call->addr_type;
+ ocall.clip_validity = call->presentation & 3;
+
+ if (ocall.clip_validity == 0 && strlen(number->number) == 0)
+ ocall.clip_validity = 2;
+
+ return ocall;
+}
+
+static struct isi_call *isi_call_set_idle(struct isi_call *call)
+{
+ uint8_t id;
+
+ id = call->id;
+ memset(call, 0, sizeof(*call));
+ call->id = id;
+
+ return call;
+}
+
+static void isi_call_disconnected(struct ofono_voicecall *ovc,
+ struct isi_call *call)
+{
+ struct ofono_error error = { OFONO_ERROR_TYPE_NO_ERROR, 0 };
+ enum ofono_disconnect_reason reason = call->reason;
+
+ if (!reason)
+ reason = OFONO_DISCONNECT_REASON_ERROR;
+
+ DBG("disconnected id=%u reason=%u", call->id, reason);
+ ofono_voicecall_disconnected(ovc, call->id, reason, &error);
+ isi_call_set_idle(call);
+}
+
+static void isi_call_notify(struct ofono_voicecall *ovc,
+ struct isi_call *call)
+{
+ struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
+ struct isi_call_req_context *irc, **queue;
+ struct ofono_call ocall;
+
+ DBG("called with status=%s (0x%02X)",
+ call_status_name(call->status), call->status);
+
+ for (queue = &ivc->queue; (irc = *queue);) {
+ irc->step(irc, call->status);
+
+ if (*queue == irc)
+ queue = &irc->next;
+ }
+
+ ocall = isi_call_as_ofono_call(ivc, call);
+
+ DBG("id=%u,\"%s\",%u,\"%s\",%u,%u",
+ ocall.id,
+ ocall.direction ? "mt" : "mo",
+ ocall.status,
+ ocall.phone_number.number,
+ ocall.phone_number.type,
+ ocall.clip_validity);
+
+ if (ocall.status == CLCC_STATUS_EARLY)
+ return;
+
+ ofono_voicecall_notify(ovc, &ocall);
+
+ switch (call->status) {
+ case CALL_STATUS_MO_RELEASE:
+ call->reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
+ break;
+
+ case CALL_STATUS_MT_RELEASE:
+ call->reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
+ break;
+
+ case CALL_STATUS_IDLE:
+ case CALL_STATUS_TERMINATED:
+ isi_call_disconnected(ovc, call);
+ break;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
/* Decoding subblocks */
static void isi_call_any_address_sb_proc(struct isi_voicecall *ivc,
@@ -491,16 +634,8 @@ static void isi_call_status_ind_cb(GIsiClient *client,
}
}
- if (old != call->status) {
- if (call->status == CALL_STATUS_IDLE) {
- call->status = CALL_STATUS_TERMINATED;
- isi_call_notify(ovc, call);
- isi_call_set_idle(call);
- return;
- }
- }
-
- isi_call_notify(ovc, call);
+ if (old != call->status)
+ isi_call_notify(ovc, call);
}
static struct isi_call_req_context *
@@ -801,150 +936,6 @@ static gboolean isi_call_dtmf_send_resp(GIsiClient *client,
return isi_ctx_return_failure(irc);
}
-
-/* ------------------------------------------------------------------------- */
-/* Notify */
-
-static void isi_call_notify(struct ofono_voicecall *ovc,
- struct isi_call *call)
-{
- struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
- struct isi_call_req_context *irc, **queue;
- struct ofono_call ocall;
-
- DBG("called with status=%s (0x%02X)",
- call_status_name(call->status), call->status);
-
- for (queue = &ivc->queue; (irc = *queue);) {
- irc->step(irc, call->status);
- if (*queue == irc)
- queue = &irc->next;
- }
-
- switch (call->status) {
- case CALL_STATUS_IDLE:
- case CALL_STATUS_MO_RELEASE:
- case CALL_STATUS_MT_RELEASE:
- case CALL_STATUS_TERMINATED:
- isi_call_release(ovc, call);
- return;
- }
-
- ocall = isi_call_as_ofono_call(call);
-
- DBG("id=%u,%s,%u,\"%s\",%u,%u",
- ocall.id,
- ocall.direction ? "terminated" : "originated",
- ocall.status,
- ocall.phone_number.number,
- ocall.phone_number.type,
- ocall.clip_validity);
-
- ofono_voicecall_notify(ovc, &ocall);
-}
-
-static void isi_call_release(struct ofono_voicecall *ovc,
- struct isi_call *call)
-{
- struct ofono_error error = { OFONO_ERROR_TYPE_NO_ERROR, 0 };
- enum ofono_disconnect_reason reason;
-
- switch (call->status) {
- case CALL_STATUS_IDLE:
- reason = OFONO_DISCONNECT_REASON_UNKNOWN;
- break;
- case CALL_STATUS_MO_RELEASE:
- reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
- break;
- case CALL_STATUS_MT_RELEASE:
- reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
- break;
- case CALL_STATUS_TERMINATED:
- default:
- reason = OFONO_DISCONNECT_REASON_ERROR;
- break;
- }
-
- if (!call->reason) {
- call->reason = reason;
- DBG("disconnected id=%u reason=%u", call->id, reason);
- ofono_voicecall_disconnected(ovc, call->id, reason, &error);
- }
-
- if (!reason)
- isi_call_set_idle(call);
-}
-
-static struct ofono_call isi_call_as_ofono_call(struct isi_call const *call)
-{
- struct ofono_call ocall = { call->id };
- struct ofono_phone_number *number = &ocall.phone_number;
-
- ocall.type = 0; /* Voice call */
- ocall.direction = call->mode_info & CALL_MODE_ORIGINATOR;
- ocall.status = isi_call_status_to_clcc(call);
- memcpy(number->number, call->address, sizeof number->number);
- number->type = 0x80 | call->addr_type;
- ocall.clip_validity = call->presentation & 3;
- if (ocall.clip_validity == 0 && strlen(number->number) == 0)
- ocall.clip_validity = 2;
-
- return ocall;
-}
-
-/** Get +CLCC status */
-static int isi_call_status_to_clcc(struct isi_call const *call)
-{
- switch (call->status) {
- case CALL_STATUS_CREATE:
- return 2;
- case CALL_STATUS_COMING:
- return 4;
- case CALL_STATUS_PROCEEDING:
- if ((call->mode_info & CALL_MODE_ORIGINATOR))
- return 4; /* MT */
- else
- return 2; /* MO */
- case CALL_STATUS_MO_ALERTING:
- return 3;
- case CALL_STATUS_MT_ALERTING:
- return 4;
- case CALL_STATUS_WAITING:
- return 5;
-
- case CALL_STATUS_ANSWERED:
- case CALL_STATUS_ACTIVE:
- case CALL_STATUS_MO_RELEASE:
- case CALL_STATUS_MT_RELEASE:
- case CALL_STATUS_HOLD_INITIATED:
- return 0;
-
- case CALL_STATUS_HOLD:
- case CALL_STATUS_RETRIEVE_INITIATED:
- return 1;
-
- case CALL_STATUS_RECONNECT_PENDING:
- case CALL_STATUS_TERMINATED:
- case CALL_STATUS_SWAP_INITIATED:
- return 0;
- }
-
- return 0;
-}
-
-static struct isi_call *isi_call_set_idle(struct isi_call *call)
-{
- uint8_t id;
-
- if (call) {
- id = call->id;
- memset(call, 0, sizeof *call);
- call->id = id;
- }
-
- return call;
-}
-
/* ---------------------------------------------------------------------- */
static void isi_dial(struct ofono_voicecall *ovc,
@@ -1245,31 +1236,27 @@ static void isi_send_tones(struct ofono_voicecall *ovc, const char *tones,
isi_call_dtmf_send_req(ovc, CALL_ID_ALL, tones, cb, data);;
}
-static int isi_voicecall_probe(struct ofono_voicecall *ovc,
- unsigned int vendor, void *user)
+static gboolean isi_call_register(gpointer _ovc)
{
- GIsiModem *idx = user;
- struct isi_voicecall *ivc = g_try_new0(struct isi_voicecall, 1);
- int id;
-
- if (ivc == NULL)
- return -ENOMEM;
+ struct ofono_voicecall *ovc = _ovc;
+ struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
+ const char *debug = getenv("OFONO_ISI_DEBUG");
- for (id = 0; id <= 7; id++)
- ivc->calls[id].id = id;
+ if (debug != NULL && (!strcmp(debug, "all") || !strcmp(debug, "call")))
+ g_isi_client_set_debug(ivc->client, call_debug, NULL);
- ivc->client = g_isi_client_create(idx, PN_CALL);
- if (ivc->client == NULL) {
- g_free(ivc);
- return -ENOMEM;
- }
+ g_isi_subscribe(ivc->client,
+ CALL_STATUS_IND, isi_call_status_ind_cb,
+ ovc);
- ofono_voicecall_set_data(ovc, ivc);
+ if (isi_call_status_req(ovc, CALL_ID_ALL,
+ CALL_STATUS_MODE_ADDR_AND_ORIGIN,
+ NULL, NULL) == NULL)
+ DBG("Failed to request call status");
- if (!g_isi_verify(ivc->client, isi_call_verify_cb, ovc))
- DBG("Unable to verify reachability");
+ ofono_voicecall_register(ovc);
- return 0;
+ return FALSE;
}
static void isi_call_verify_cb(GIsiClient *client,
@@ -1288,28 +1275,32 @@ static void isi_call_verify_cb(GIsiClient *client,
g_idle_add(isi_call_register, ovc);
}
-static gboolean isi_call_register(gpointer _ovc)
+static int isi_voicecall_probe(struct ofono_voicecall *ovc,
+ unsigned int vendor, void *user)
{
- struct ofono_voicecall *ovc = _ovc;
- struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
+ GIsiModem *idx = user;
+ struct isi_voicecall *ivc;
+ int id;
- const char *debug = getenv("OFONO_ISI_DEBUG");
+ ivc = g_try_new0(struct isi_voicecall, 1);
+ if (ivc == NULL)
+ return -ENOMEM;
- if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "call") == 0))
- g_isi_client_set_debug(ivc->client, call_debug, NULL);
+ for (id = 1; id <= 7; id++)
+ ivc->calls[id].id = id;
- g_isi_subscribe(ivc->client,
- CALL_STATUS_IND, isi_call_status_ind_cb,
- ovc);
+ ivc->client = g_isi_client_create(idx, PN_CALL);
+ if (ivc->client == NULL) {
+ g_free(ivc);
+ return -ENOMEM;
+ }
- if (isi_call_status_req(ovc, CALL_ID_ALL,
- CALL_STATUS_MODE_ADDR_AND_ORIGIN,
- NULL, NULL) == NULL)
- DBG("Failed to request call status");
+ ofono_voicecall_set_data(ovc, ivc);
- ofono_voicecall_register(ovc);
+ if (g_isi_verify(ivc->client, isi_call_verify_cb, ovc) == NULL)
+ DBG("Unable to verify reachability");
- return FALSE;
+ return 0;
}
static void isi_voicecall_remove(struct ofono_voicecall *call)
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [fix-isi-voicecall PATCHv5 2/4] isi/voicecall: add call id to queued requests
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 1/4] isi/voicecall: fix status reporting Pekka.Pessi
@ 2010-12-03 8:30 ` Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 3/4] isi/voicecall: avoid side-effects of release Pekka.Pessi
0 siblings, 1 reply; 6+ messages in thread
From: Pekka.Pessi @ 2010-12-03 8:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 4781 bytes --]
From: Pekka Pessi <Pekka.Pessi@nokia.com>
---
drivers/isimodem/voicecall.c | 89 +++++++++++++++++++++++++++---------------
1 files changed, 57 insertions(+), 32 deletions(-)
diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
index b89cbb3..e7126a8 100644
--- a/drivers/isimodem/voicecall.c
+++ b/drivers/isimodem/voicecall.c
@@ -80,41 +80,62 @@ enum {
/* ------------------------------------------------------------------------- */
/* Request context for voicecall cb */
-struct isi_call_req_context;
-
-typedef void isi_call_req_step(struct isi_call_req_context *, int reason);
+typedef void isi_call_req_step(struct isi_call_req_context *,
+ int id, int status);
struct isi_call_req_context {
- struct isi_call_req_context *next, **prev;
+ struct isi_call_req_context *next;
+ struct isi_call_req_context **prev;
isi_call_req_step *step;
+ int id;
struct ofono_voicecall *ovc;
ofono_voicecall_cb_t cb;
void *data;
};
-static struct isi_call_req_context *
-isi_call_req(struct ofono_voicecall *ovc,
- void const *restrict req,
- size_t len,
- GIsiResponse *handler,
- ofono_voicecall_cb_t cb, void *data)
+static struct isi_call_req_context *isi_call_req_new(
+ struct ofono_voicecall *ovc,
+ ofono_voicecall_cb_t cb,
+ void *data)
{
- struct isi_voicecall *ivc;
struct isi_call_req_context *irc;
- ivc = ofono_voicecall_get_data(ovc);
-
irc = g_try_new0(struct isi_call_req_context, 1);
+ if (irc == NULL)
+ goto failed;
- if (irc) {
- irc->ovc = ovc;
- irc->cb = cb;
- irc->data = data;
+ irc->ovc = ovc;
+ irc->cb = cb;
+ irc->data = data;
- if (g_isi_request_make(ivc->client, req, len,
- ISI_CALL_TIMEOUT, handler, irc))
- return irc;
- }
+ return irc;
+
+failed:
+ if (cb)
+ CALLBACK_WITH_FAILURE(cb, data);
+
+ return NULL;
+}
+
+static struct isi_call_req_context *isi_call_req(struct ofono_voicecall *ovc,
+ void const *restrict req,
+ size_t len,
+ GIsiResponse *handler,
+ ofono_voicecall_cb_t cb,
+ void *data)
+{
+ struct isi_voicecall *ivc;
+ struct isi_call_req_context *irc;
+
+ irc = isi_call_req_new(ovc, cb, data);
+ if (irc == NULL)
+ return NULL;
+
+ ivc = ofono_voicecall_get_data(ovc);
+
+ if (g_isi_send(ivc->client, req, len,
+ ISI_CALL_TIMEOUT, handler, irc, NULL))
+ return irc;
g_free(irc);
@@ -125,7 +146,8 @@ isi_call_req(struct ofono_voicecall *ovc,
}
static void isi_ctx_queue(struct isi_call_req_context *irc,
- isi_call_req_step *next)
+ isi_call_req_step *next,
+ int id)
{
if (irc->prev == NULL) {
struct isi_voicecall *ivc = ofono_voicecall_get_data(irc->ovc);
@@ -139,6 +161,7 @@ static void isi_ctx_queue(struct isi_call_req_context *irc,
}
irc->step = next;
+ irc->id = id;
}
static void isi_ctx_remove(struct isi_call_req_context *irc)
@@ -187,7 +210,7 @@ static gboolean isi_ctx_return_failure(struct isi_call_req_context *irc)
static gboolean isi_ctx_return_success(struct isi_call_req_context *irc)
{
if (irc && irc->step) {
- irc->step(irc, 0);
+ irc->step(irc, 0, 0);
return TRUE;
}
@@ -310,7 +333,7 @@ static void isi_call_notify(struct ofono_voicecall *ovc,
call_status_name(call->status), call->status);
for (queue = &ivc->queue; (irc = *queue);) {
- irc->step(irc, call->status);
+ irc->step(irc, call->id, call->status);
if (*queue == irc)
queue = &irc->next;
@@ -1063,18 +1086,19 @@ static void isi_release_all_active(struct ofono_voicecall *ovc,
if (irc == NULL)
;
else if (waiting)
- isi_ctx_queue(irc, isi_wait_and_answer);
+ isi_ctx_queue(irc, isi_wait_and_answer, 0);
else if (hold)
- isi_ctx_queue(irc, isi_wait_and_retrieve);
+ isi_ctx_queue(irc, isi_wait_and_retrieve, 0);
} else
CALLBACK_WITH_FAILURE(cb, data);
}
static void isi_wait_and_answer(struct isi_call_req_context *irc,
- int event)
+ int id, int status)
{
- DBG("irc=%p event=%u", (void *)irc, event);
- switch (event) {
+ 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);
@@ -1083,10 +1107,11 @@ static void isi_wait_and_answer(struct isi_call_req_context *irc,
}
static void isi_wait_and_retrieve(struct isi_call_req_context *irc,
- int event)
+ int id, int status)
{
- DBG("irc=%p event=%u", (void *)irc, event);
- switch (event) {
+ DBG("irc=%p id=%u status=%u", (void *)irc, id, status);
+
+ switch (status) {
case CALL_STATUS_TERMINATED:
isi_retrieve(irc->ovc, irc->cb, irc->data);
isi_ctx_free(irc);
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [fix-isi-voicecall PATCHv5 3/4] isi/voicecall: avoid side-effects of release
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 2/4] isi/voicecall: add call id to queued requests Pekka.Pessi
@ 2010-12-03 8:30 ` Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 4/4] isi/voicecall: fix handling of waiting calls Pekka.Pessi
0 siblings, 1 reply; 6+ messages in thread
From: Pekka.Pessi @ 2010-12-03 8:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3661 bytes --]
From: Pekka Pessi <Pekka.Pessi@nokia.com>
If a call was held automatically when an another call was dialed or
answered, it gets retrieved when the other call is released unless
auto change features is explicitly disabled.
Drop cause_type parameter because it is never used.
Use cause code for busy when releasing incoming or waiting calls.
---
drivers/isimodem/voicecall.c | 32 ++++++++++++++++----------------
1 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
index e7126a8..9c1bec7 100644
--- a/drivers/isimodem/voicecall.c
+++ b/drivers/isimodem/voicecall.c
@@ -699,12 +699,13 @@ static gboolean isi_call_answer_resp(GIsiClient *client,
static struct isi_call_req_context *
isi_call_release_req(struct ofono_voicecall *ovc,
- uint8_t call_id, enum call_cause_type cause_type,
- uint8_t cause, ofono_voicecall_cb_t cb, void *data)
+ uint8_t call_id, uint8_t cause,
+ ofono_voicecall_cb_t cb, void *data)
{
uint8_t const req[] = {
- CALL_RELEASE_REQ, call_id, 1,
- CALL_CAUSE, 4, cause_type, cause,
+ CALL_RELEASE_REQ, call_id, 2,
+ CALL_CAUSE, 4, CALL_CAUSE_TYPE_CLIENT, cause,
+ CALL_STATE_AUTO_CHANGE, 4, 0, 0
};
size_t rlen = sizeof req;
@@ -1008,7 +1009,8 @@ static void isi_hangup_current(struct ofono_voicecall *ovc,
* active calls or calls in progress.
*/
struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
- int id = 0;
+ int id;
+ uint8_t cause = CALL_CAUSE_RELEASE_BY_USER;
for (id = 1; id <= 7; id++) {
if (ivc->calls[id].call_id & CALL_ID_WAITING)
@@ -1018,11 +1020,14 @@ static void isi_hangup_current(struct ofono_voicecall *ovc,
switch (ivc->calls[id].status) {
case CALL_STATUS_CREATE:
+ case CALL_STATUS_MT_ALERTING:
+ case CALL_STATUS_ANSWERED:
+ goto release_by_id;
+
case CALL_STATUS_COMING:
case CALL_STATUS_PROCEEDING:
case CALL_STATUS_MO_ALERTING:
- case CALL_STATUS_MT_ALERTING:
- case CALL_STATUS_ANSWERED:
+ cause = CALL_CAUSE_BUSY_USER_REQUEST;
goto release_by_id;
}
}
@@ -1030,15 +1035,14 @@ static void isi_hangup_current(struct ofono_voicecall *ovc,
id = CALL_ID_ACTIVE;
release_by_id:
- isi_call_release_req(ovc, id, CALL_CAUSE_TYPE_CLIENT,
- CALL_CAUSE_RELEASE_BY_USER, cb, data);
+ isi_call_release_req(ovc, id, cause, cb, data);
}
static void isi_release_all_held(struct ofono_voicecall *ovc,
ofono_voicecall_cb_t cb, void *data)
{
/* AT+CHLD=0 (w/out incoming calls) */
- isi_call_release_req(ovc, CALL_ID_HOLD, CALL_CAUSE_TYPE_CLIENT,
+ isi_call_release_req(ovc, CALL_ID_HOLD,
CALL_CAUSE_RELEASE_BY_USER, cb, data);
}
@@ -1047,8 +1051,7 @@ static void isi_set_udub(struct ofono_voicecall *ovc,
{
/* Release waiting calls */
isi_call_release_req(ovc, CALL_ID_WAITING,
- CALL_CAUSE_TYPE_CLIENT, CALL_CAUSE_BUSY_USER_REQUEST,
- cb, data);
+ CALL_CAUSE_BUSY_USER_REQUEST, cb, data);
}
static void isi_retrieve(struct ofono_voicecall *ovc,
@@ -1079,7 +1082,6 @@ static void isi_release_all_active(struct ofono_voicecall *ovc,
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);
@@ -1176,9 +1178,7 @@ static void isi_release_specific(struct ofono_voicecall *ovc, int id,
break;
}
- isi_call_release_req(ovc, id,
- CALL_CAUSE_TYPE_CLIENT, cause,
- cb, data);
+ isi_call_release_req(ovc, id, cause, cb, data);
} else
CALLBACK_WITH_FAILURE(cb, data);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [fix-isi-voicecall PATCHv5 4/4] isi/voicecall: fix handling of waiting calls
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 3/4] isi/voicecall: avoid side-effects of release Pekka.Pessi
@ 2010-12-03 8:30 ` Pekka.Pessi
0 siblings, 0 replies; 6+ messages in thread
From: Pekka.Pessi @ 2010-12-03 8:30 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 4524 bytes --]
From: Pekka Pessi <Pekka.Pessi@nokia.com>
Also, do not retrieve calls after isi_release_all_active() because
retrieving is now only an unwanted side-effect .
---
drivers/isimodem/voicecall.c | 114 ++++++++++++++++++++---------------------
1 files changed, 56 insertions(+), 58 deletions(-)
diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
index 9c1bec7..f2fd53a 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,
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [fix-isi-voicecall PATCHv5 0/4] Call state fixes
2010-12-03 8:30 [fix-isi-voicecall PATCHv5 0/4] Call state fixes Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 1/4] isi/voicecall: fix status reporting Pekka.Pessi
@ 2010-12-03 12:59 ` Aki Niemi
1 sibling, 0 replies; 6+ messages in thread
From: Aki Niemi @ 2010-12-03 12:59 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 265 bytes --]
On Fri, 2010-12-03 at 10:30 +0200, ext Pekka.Pessi(a)nokia.com wrote:
> Hi all,
>
> Here are the isi voicecall patches again, rebased with the NULL fixes.
Pushed the lot, thanks.
Are these fixes now also in the refactored gisi tree? ;)
Cheers,
Aki
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-12-03 12:59 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-03 8:30 [fix-isi-voicecall PATCHv5 0/4] Call state fixes Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 1/4] isi/voicecall: fix status reporting Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 2/4] isi/voicecall: add call id to queued requests Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 3/4] isi/voicecall: avoid side-effects of release Pekka.Pessi
2010-12-03 8:30 ` [fix-isi-voicecall PATCHv5 4/4] isi/voicecall: fix handling of waiting calls Pekka.Pessi
2010-12-03 12:59 ` [fix-isi-voicecall PATCHv5 0/4] Call state fixes Aki Niemi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox