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