All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v0] Report cell technology capability for Option HSO modems
@ 2010-06-10 13:19 Daniel Wagner
  2010-06-10 21:51 ` Denis Kenzior
  0 siblings, 1 reply; 2+ messages in thread
From: Daniel Wagner @ 2010-06-10 13:19 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 7726 bytes --]

Option modem use OCTI and OSSYSI commands
for reporting the cell capability.
---
The log to this patch: http://pastebin.com/xrbrUGeL

Unfortunalty, I couldn't get away without OSSYSI updating the netreg
info. 

v0: based on "[RFC v3] Readout technology form Option HSO modems"

 drivers/atmodem/network-registration.c |  121 +++++++++++++++++++++-----------
 1 files changed, 81 insertions(+), 40 deletions(-)

diff --git a/drivers/atmodem/network-registration.c b/drivers/atmodem/network-registration.c
index f5ccbb1..d7617b1 100644
--- a/drivers/atmodem/network-registration.c
+++ b/drivers/atmodem/network-registration.c
@@ -54,7 +54,12 @@ struct netreg_data {
 	int signal_index; /* If strength is reported via CIND */
 	int signal_min; /* min strength reported via CIND */
 	int signal_max; /* max strength reported via CIND */
+	int status;
+	int lac;
+	int ci;
 	int tech;
+	int ossysi; /* option hso 2G/3G info */
+	int octi; /* option hso 2G info */
 	unsigned int vendor;
 };
 
@@ -73,7 +78,7 @@ static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data)
 {
 	struct cb_data *cbd = user_data;
 	ofono_netreg_status_cb_t cb = cbd->cb;
-	int status, lac, ci, tech;
+	int tech;
 	struct ofono_error error;
 	struct netreg_data *nd = cbd->user;
 
@@ -84,16 +89,16 @@ static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data)
 		return;
 	}
 
-	if (at_util_parse_reg(result, "+CREG:", NULL, &status,
-				&lac, &ci, &tech, nd->vendor) == FALSE) {
+	if (at_util_parse_reg(result, "+CREG:", NULL, &nd->status,
+			&nd->lac, &nd->ci, &tech, nd->vendor) == FALSE) {
 		CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
 		return;
 	}
 
-	if ((status == 1 || status == 5) && (tech == -1))
+	if ((nd->status == 1 || nd->status == 5) && (tech == -1))
 		tech = nd->tech;
 
-	cb(&error, status, lac, ci, tech, cbd->data);
+	cb(&error, nd->status, nd->lac, nd->ci, tech, cbd->data);
 }
 
 static void at_registration_status(struct ofono_netreg *netreg,
@@ -533,36 +538,88 @@ static void option_osigq_notify(GAtResult *result, gpointer user_data)
 				at_util_convert_signal_strength(strength));
 }
 
-static void option_ouwcti_notify(GAtResult *result, gpointer user_data)
+static void option_ossysi_octi_to_tech(struct netreg_data *nd)
 {
-	int mode;
+	int tech = -1;
+	switch (nd->ossysi) {
+	case 0: /* 2G */
+		switch (nd->octi) {
+		case 1:	/* GSM */
+			tech = 0;
+			break;
+		case 2: /* GPRS */
+			tech = 1;
+			break;
+		case 3:	/* EDGE */
+			tech = 3;
+		}
+		break;
+	case 2: /* 3G */
+		/* UMTS */
+		tech = 2;
+		break;
+	case 3: /* Unknown */
+		/* reset all ossysi and octi */
+		nd->octi = -1;
+		nd->ossysi = -1;
+		break;
+	}
+
+	nd->tech = tech;
+
+	DBG("ossysi %d octi %d tech %d",
+		nd->ossysi, nd->octi, nd->tech);
+}
+
+static void option_ossysi_notify(GAtResult *result, gpointer user_data)
+{
+	struct ofono_netreg *netreg = user_data;
+	struct netreg_data *nd = ofono_netreg_get_data(netreg);
 	GAtResultIter iter;
 
 	g_at_result_iter_init(&iter, result);
 
-	if (!g_at_result_iter_next(&iter, "_OUWCTI:"))
+	if (!g_at_result_iter_next(&iter, "_OSSYSI:"))
 		return;
 
-	if (!g_at_result_iter_next_number(&iter, &mode))
+	if (!g_at_result_iter_next_number(&iter, &nd->ossysi))
 		return;
 
-	ofono_info("OWCTI mode: %d", mode);
+	option_ossysi_octi_to_tech(nd);
+
+	/*
+	 * OSSYSI can appear after a CREG and netreg isn't updated
+	 * until the next CREG which can take an undefined long time.
+	 */
+	ofono_netreg_status_notify(netreg, nd->status, nd->lac,
+				nd->ci, nd->tech);
 }
 
 static void option_octi_notify(GAtResult *result, gpointer user_data)
 {
-	int mode;
+	struct ofono_netreg *netreg = user_data;
+	struct netreg_data *nd = ofono_netreg_get_data(netreg);
 	GAtResultIter iter;
+	int mode;
 
 	g_at_result_iter_init(&iter, result);
 
 	if (!g_at_result_iter_next(&iter, "_OCTI:"))
 		return;
 
-	if (!g_at_result_iter_next_number(&iter, &mode))
+	if (!g_at_result_iter_next_number(&iter, &nd->octi))
 		return;
 
-	ofono_info("OCTI mode: %d", mode);
+	/* Handle query responses too */
+	if (!g_at_result_iter_next_number(&iter, &mode) == FALSE)
+		nd->octi = mode;
+
+	option_ossysi_octi_to_tech(nd);
+
+	/*
+	 * OCTI seem to appear always before a CREG or
+	 * is followed by a OSSYSI which will update netreg.
+	 */
 }
 
 static void ciev_notify(GAtResult *result, gpointer user_data)
@@ -624,22 +681,6 @@ static void cind_cb(gboolean ok, GAtResult *result, gpointer user_data)
 	cb(&error, strength, cbd->data);
 }
 
-static void option_ossysi_notify(GAtResult *result, gpointer user_data)
-{
-	int mode;
-	GAtResultIter iter;
-
-	g_at_result_iter_init(&iter, result);
-
-	if (!g_at_result_iter_next(&iter, "_OSSYSI:"))
-		return;
-
-	if (!g_at_result_iter_next_number(&iter, &mode))
-		return;
-
-	ofono_info("OSSYSI mode: %d", mode);
-}
-
 static void huawei_rssi_notify(GAtResult *result, gpointer user_data)
 {
 	struct ofono_netreg *netreg = user_data;
@@ -806,17 +847,17 @@ static void nw_cnti_notify(GAtResult *result, gpointer user_data)
 static void creg_notify(GAtResult *result, gpointer user_data)
 {
 	struct ofono_netreg *netreg = user_data;
-	int status, lac, ci, tech;
+	int tech;
 	struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
-	if (at_util_parse_reg_unsolicited(result, "+CREG:", &status,
-				&lac, &ci, &tech, nd->vendor) == FALSE)
+	if (at_util_parse_reg_unsolicited(result, "+CREG:", &nd->status,
+				&nd->lac, &nd->ci, &tech, nd->vendor) == FALSE)
 		return;
 
-	if ((status == 1 || status == 5) && tech == -1)
+	if ((nd->status == 1 || nd->status == 5) && tech == -1)
 		tech = nd->tech;
 
-	ofono_netreg_status_notify(netreg, status, lac, ci, tech);
+	ofono_netreg_status_notify(netreg, nd->status, nd->lac, nd->ci, tech);
 }
 
 static void cind_support_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -909,16 +950,12 @@ static void at_creg_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
 	case OFONO_VENDOR_OPTION_HSO:
 		g_at_chat_send(nd->chat, "AT_OSSYS=1", none_prefix,
 				NULL, NULL, NULL);
-		g_at_chat_send(nd->chat, "AT_OUWCTI=1", none_prefix,
-				NULL, NULL, NULL);
 		g_at_chat_send(nd->chat, "AT_OCTI=1", none_prefix,
 				NULL, NULL, NULL);
 		g_at_chat_send(nd->chat, "AT_OSQI=1", none_prefix,
 				NULL, NULL, NULL);
 		g_at_chat_register(nd->chat, "_OSIGQ:", option_osigq_notify,
 					FALSE, netreg, NULL);
-		g_at_chat_register(nd->chat, "_OUWCTI:", option_ouwcti_notify,
-					FALSE, netreg, NULL);
 		g_at_chat_register(nd->chat, "_OCTI:", option_octi_notify,
 					FALSE, netreg, NULL);
 		g_at_chat_register(nd->chat, "_OSSYSI:", option_ossysi_notify,
@@ -926,12 +963,11 @@ static void at_creg_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
 
 		g_at_chat_send(nd->chat, "AT_OSSYS?", none_prefix,
 				NULL, NULL, NULL);
-		g_at_chat_send(nd->chat, "AT_OWCTI?", none_prefix,
-				NULL, NULL, NULL);
 		g_at_chat_send(nd->chat, "AT_OCTI?", none_prefix,
 				NULL, NULL, NULL);
 		g_at_chat_send(nd->chat, "AT_OSQI?", none_prefix,
 				NULL, NULL, NULL);
+
 		break;
 	case OFONO_VENDOR_MBM:
 		g_at_chat_send(nd->chat, "AT*ERINFO=1", none_prefix,
@@ -1021,7 +1057,12 @@ static int at_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
 
 	nd->chat = chat;
 	nd->vendor = vendor;
+	nd->status = -1;
+	nd->lac = -1;
+	nd->ci = -1;
 	nd->tech = -1;
+	nd->ossysi = -1;
+	nd->octi = -1;
 	ofono_netreg_set_data(netreg, nd);
 
 	g_at_chat_send(chat, "AT+CREG=?", creg_prefix,
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-06-10 21:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-10 13:19 [PATCH v0] Report cell technology capability for Option HSO modems Daniel Wagner
2010-06-10 21:51 ` Denis Kenzior

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.