Open Source Telephony
 help / color / mirror / Atom feed
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

  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