All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.