From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [isi-voicecall-fix PATCHv3 2/6] isi/voicecall: fix status reporting
Date: Mon, 22 Nov 2010 08:14:34 -0600 [thread overview]
Message-ID: <4CEA7ACA.8070703@gmail.com> (raw)
In-Reply-To: <1289927124-30133-2-git-send-email-Pekka.Pessi@nokia.com>
[-- Attachment #1: Type: text/plain, Size: 14622 bytes --]
Hi Pekka,
On 11/16/2010 11:05 AM, Pekka.Pessi(a)nokia.com wrote:
> From: Pekka Pessi <Pekka.Pessi@nokia.com>
>
> Report early incoming calls as waiting or incoming, depending on the
> state of other calls.
>
> Report MT_RELEASED or MO_RELEASED via ofono_voicecall_notify(),
> TERMINATED calls via ofono_voicecall_disconnected().
> ---
> drivers/isimodem/voicecall.c | 401 +++++++++++++++++++++---------------------
> 1 files changed, 203 insertions(+), 198 deletions(-)
>
> diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
> index c3365f6..c450f12 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,174 @@ static gboolean isi_ctx_return_success(struct isi_call_req_context *irc)
> }
>
> /* ------------------------------------------------------------------------- */
> +/* Notify */
> +
> +enum clcc_status {
> + 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, /* Nonstandard */
> +};
Please follow M11 completely here, particularly the tabs before the values.
> +
> +static int isi_call_waiting_or_incoming(struct isi_voicecall const *ivc)
> +{
> + int id;
> +
> + for (id = 1; id <= 7; id++) {
> + switch (ivc->calls[id].status) {
> + case CALL_STATUS_ANSWERED:
> + case CALL_STATUS_ACTIVE:
> + case CALL_STATUS_HOLD_INITIATED:
> + case CALL_STATUS_HOLD:
> + case CALL_STATUS_RETRIEVE_INITIATED:
> + case CALL_STATUS_RECONNECT_PENDING:
> + case CALL_STATUS_SWAP_INITIATED:
> + return CLCC_STATUS_WAITING;
> + }
> + }
> +
> + return CLCC_STATUS_INCOMING;
> +}
> +
> +/** 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 isi_call_waiting_or_incoming(ivc);
> +
> + case CALL_STATUS_PROCEEDING:
> + if ((call->mode_info & CALL_MODE_ORIGINATOR))
> + return isi_call_waiting_or_incoming(ivc); /* 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);
Please watch out for the sizeof usage.
> + 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);
sizeof use again
> + 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);
> +
> + 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);
Is the break statement missing here?
> + }
> +}
> +
> +/* ------------------------------------------------------------------------- */
> /* Decoding subblocks */
>
> static void isi_call_any_address_sb_proc(struct isi_voicecall *ivc,
> @@ -491,16 +649,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 +951,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,
> @@ -1244,31 +1250,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)
> - 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 && (strcmp(debug, "all") == 0 || strcmp(debug, "call") == 0))
> + g_isi_client_set_debug(ivc->client, call_debug, NULL);
>
> - ivc->client = g_isi_client_create(idx, PN_CALL);
> - if (!ivc->client) {
> - 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))
> + 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,
> @@ -1287,28 +1289,31 @@ 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 = g_try_new0(struct isi_voicecall, 1);
> + int id;
>
> - const char *debug = getenv("OFONO_ISI_DEBUG");
> + if (!ivc)
> + 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) {
> + g_free(ivc);
> + return -ENOMEM;
> + }
>
> - if (!isi_call_status_req(ovc, CALL_ID_ALL,
> - CALL_STATUS_MODE_ADDR_AND_ORIGIN,
> - 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))
> + DBG("Unable to verify reachability");
>
> - return FALSE;
> + return 0;
> }
>
> static void isi_voicecall_remove(struct ofono_voicecall *call)
Regards,
-Denis
next prev parent reply other threads:[~2010-11-22 14:14 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-16 17:05 [isi-voicecall-fix PATCHv3 1/6] voicecall: fix dial result handling Pekka.Pessi
2010-11-16 17:05 ` [isi-voicecall-fix PATCHv3 2/6] isi/voicecall: fix status reporting Pekka.Pessi
2010-11-16 17:05 ` [isi-voicecall-fix PATCHv3 3/6] isi/voicecall: save call id when queueing requests Pekka.Pessi
2010-11-16 17:05 ` [isi-voicecall-fix PATCHv3 4/6] isi/voicecall: fix answering early incoming calls Pekka.Pessi
2010-11-16 17:05 ` [isi-voicecall-fix PATCHv3 5/6] isi/voicecall: release COMING calls with BUSY cause Pekka.Pessi
2010-11-16 17:05 ` [isi-voicecall-fix PATCHv3 6/6] isi/voicecall: fix isi_release_all_active() Pekka.Pessi
2010-11-22 14:21 ` [isi-voicecall-fix PATCHv3 5/6] isi/voicecall: release COMING calls with BUSY cause Denis Kenzior
2010-11-22 14:19 ` [isi-voicecall-fix PATCHv3 4/6] isi/voicecall: fix answering early incoming calls Denis Kenzior
2010-11-22 16:22 ` Pekka Pessi
2010-11-22 16:38 ` Denis Kenzior
2010-11-22 14:16 ` [isi-voicecall-fix PATCHv3 3/6] isi/voicecall: save call id when queueing requests Denis Kenzior
2010-11-22 14:14 ` Denis Kenzior [this message]
2010-11-22 16:09 ` [isi-voicecall-fix PATCHv3 2/6] isi/voicecall: fix status reporting Pekka Pessi
2010-11-22 16:37 ` Denis Kenzior
2010-11-22 13:43 ` [isi-voicecall-fix PATCHv3 1/6] voicecall: fix dial result handling Denis Kenzior
2010-11-22 16:50 ` Pekka Pessi
2010-11-22 17:27 ` Denis Kenzior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4CEA7ACA.8070703@gmail.com \
--to=denkenz@gmail.com \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox