[RFC] Readout technology from Option HSO modems

Daniel Wagner wagi at monom.org
Fri Jun 4 07:59:44 PDT 2010


According MM the OSSYSI commands returns
the information which command has to
be considered for details.

OSSYSI 0 -> TECH_GPRS (use OCTI for details)
OSSYSI 2 -> TECH_UMTS (use OWCTI for details)

OCTI 1 -> GSM
OCTI 2 -> GPRS
OCTI 3 -> EDGE

OWCTI 1 -> UMTS
OWCTI 2 -> HSDPA
OWCTI 3 -> HSUPA
OWCTI 4 -> HSPA
---
 drivers/atmodem/network-registration.c |   97 ++++++++++++++++++++++++++++++-
 src/network.c                          |    8 +-
 2 files changed, 97 insertions(+), 8 deletions(-)

diff --git a/drivers/atmodem/network-registration.c b/drivers/atmodem/network-registration.c
index d0fa039..90e1820 100644
--- a/drivers/atmodem/network-registration.c
+++ b/drivers/atmodem/network-registration.c
@@ -55,9 +55,50 @@ struct netreg_data {
 	int signal_min; /* min strength reported via CIND */
 	int signal_max; /* max strength reported via CIND */
 	int tech;
+	int octi; /* option hso gprs band info */
+	int owcti; /* option hso umts band info */
+	int ossysi; /* option hso main tech switch */
 	unsigned int vendor;
 };
 
+
+static int option_octi_owcti_to_tech(struct netreg_data *nd)
+{
+	int tech = -1;
+
+	switch (nd->ossysi) {
+	case 0: /* GPRS */
+		switch (nd->octi) {
+		case 1:	/* GSM */
+			tech = 0;
+			break;
+		case 2: /* GPRS */
+			tech = 1;
+			break;
+		case 3:	/* EDGE */
+			tech = 3;
+		}
+		break;
+	case 2: /* UMTS */
+		switch (nd->owcti) {
+		case 1: /* UMTS */
+			tech = 2;
+			break;
+		case 2: /* HSDPA */
+			tech = 4;
+			break;
+		case 3: /* HSUPA */
+			tech = 5;
+			break;
+		case 4: /* HSPA */
+			tech = 6;
+		}
+		break;
+	}
+
+	return tech;
+}
+
 static void extract_mcc_mnc(const char *str, char *mcc, char *mnc)
 {
 	/* Three digit country code */
@@ -90,8 +131,15 @@ static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data)
 		return;
 	}
 
-	if ((status == 1 || status == 5) && (tech == -1))
-		tech = nd->tech;
+
+	if ((status == 1 || status == 5) && tech == -1) {
+		switch (nd->vendor) {
+		case OFONO_VENDOR_OPTION_HSO:
+			tech = option_octi_owcti_to_tech(nd);
+		default:
+			tech = nd->tech;
+		}
+	}
 
 	cb(&error, status, lac, ci, tech, cbd->data);
 }
@@ -116,6 +164,18 @@ static void at_registration_status(struct ofono_netreg *netreg,
 		g_at_chat_send(nd->chat, "AT*ERINFO?", none_prefix,
 				NULL, NULL, NULL);
 
+	/*
+	 * Send OSSYS, OCTI and OWCTI to find out the current tech
+	 */
+	if (nd->vendor == OFONO_VENDOR_OPTION_HSO) {
+		g_at_chat_send(nd->chat, "AT_OSSYS?", 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_OWCTI?", none_prefix,
+				NULL, NULL, NULL);
+	}
+
 	if (g_at_chat_send(nd->chat, "AT+CREG?", creg_prefix,
 				at_creg_cb, cbd, g_free) > 0)
 		return;
@@ -519,6 +579,8 @@ static void option_osigq_notify(GAtResult *result, gpointer user_data)
 
 static void option_owcti_notify(GAtResult *result, gpointer user_data)
 {
+	struct ofono_netreg *netreg = user_data;
+	struct netreg_data *nd = ofono_netreg_get_data(netreg);
 	int mode;
 	GAtResultIter iter;
 
@@ -530,11 +592,17 @@ static void option_owcti_notify(GAtResult *result, gpointer user_data)
 	if (!g_at_result_iter_next_number(&iter, &mode))
 		return;
 
+	nd->owcti = mode;
+	ofono_netreg_status_notify(netreg, -1, -1, -1,
+				option_octi_owcti_to_tech(nd));
+
 	ofono_info("OWCTI mode: %d", mode);
 }
 
 static void option_octi_notify(GAtResult *result, gpointer user_data)
 {
+	struct ofono_netreg *netreg = user_data;
+	struct netreg_data *nd = ofono_netreg_get_data(netreg);
 	int mode;
 	GAtResultIter iter;
 
@@ -546,6 +614,10 @@ static void option_octi_notify(GAtResult *result, gpointer user_data)
 	if (!g_at_result_iter_next_number(&iter, &mode))
 		return;
 
+	nd->octi = mode;
+	ofono_netreg_status_notify(netreg, -1, -1, -1,
+				option_octi_owcti_to_tech(nd));
+
 	ofono_info("OCTI mode: %d", mode);
 }
 
@@ -610,6 +682,8 @@ static void cind_cb(gboolean ok, GAtResult *result, gpointer user_data)
 
 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);
 	int mode;
 	GAtResultIter iter;
 
@@ -621,6 +695,10 @@ static void option_ossysi_notify(GAtResult *result, gpointer user_data)
 	if (!g_at_result_iter_next_number(&iter, &mode))
 		return;
 
+	nd->ossysi = mode;
+	ofono_netreg_status_notify(netreg, -1, -1, -1,
+				option_octi_owcti_to_tech(nd));
+
 	ofono_info("OSSYSI mode: %d", mode);
 }
 
@@ -754,8 +832,14 @@ static void creg_notify(GAtResult *result, gpointer user_data)
 				&lac, &ci, &tech, nd->vendor) == FALSE)
 		return;
 
-	if ((status == 1 || status == 5) && tech == -1)
-		tech = nd->tech;
+	if ((status == 1 || status == 5) && tech == -1) {
+		switch (nd->vendor) {
+		case OFONO_VENDOR_OPTION_HSO:
+			tech = option_octi_owcti_to_tech(nd);
+		default:
+			tech = nd->tech;
+		}
+	}
 
 	ofono_netreg_status_notify(netreg, status, lac, ci, tech);
 }
@@ -873,6 +957,8 @@ static void at_creg_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
 				NULL, NULL, NULL);
 		g_at_chat_send(nd->chat, "AT_OCTI?", 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_OSQI?", none_prefix,
 				NULL, NULL, NULL);
 
@@ -975,6 +1061,9 @@ static int at_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
 	nd->chat = chat;
 	nd->vendor = vendor;
 	nd->tech = -1;
+	nd->octi = -1;
+	nd->owcti = -1;
+	nd->ossysi = -1;
 	ofono_netreg_set_data(netreg, nd);
 
 	g_at_chat_send(chat, "AT+CREG=?", creg_prefix,
diff --git a/src/network.c b/src/network.c
index 87a73e3..932039d 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1033,16 +1033,16 @@ void ofono_netreg_status_notify(struct ofono_netreg *netreg, int status,
 	if (!netreg)
 		return;
 
-	if (netreg->status != status)
+	if (status != -1 && netreg->status != status)
 		set_registration_status(netreg, status);
 
-	if (netreg->location != lac)
+	if (lac != -1 && netreg->location != lac)
 		set_registration_location(netreg, lac);
 
-	if (netreg->cellid != ci)
+	if (ci != -1 && netreg->cellid != ci)
 		set_registration_cellid(netreg, ci);
 
-	if (netreg->technology != tech)
+	if (tech != -1 && netreg->technology != tech)
 		set_registration_technology(netreg, tech);
 
 	if (netreg->status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
-- 
1.6.6.1



More information about the ofono mailing list