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