To find out which the current technology is on we have to issue OCTI and OWCTI. OCTI returns 2G information and OWCTI returns 3G information. OWCTI overrules OCTI.
The OSSYSI unsolicited command tells which of information should be considered. Unfortunately, AT_OSSYSI? only returns error. OSSYSI 0 -> TECH_GPRS (use OCTI for details) OSSYSI 2 -> TECH_UMTS (use OUWCTI for details) OCTI 1 -> GSM OCTI 2 -> GPRS OCTI 3 -> EDGE OUWCTI 1 -> UMTS OUWCTI 2 -> HSDPA OUWCTI 3 -> HSUPA OUWCTI 4 -> HSPA --- I have uploaded the log ouput here http://pastebin.com/xHkS9kfP Walking around our building I can force the modem to switch from UMTS to EDGE and back. Between the switching OCTI and OUWCTI both report the value 0, which I read as no technology. option_octi_ouwcti_to_tech returns then -1. Which is fine I guess, but there will be no Technology property changed signal send out: static void set_registration_technology(struct ofono_netreg *netreg, int tech) { const char *tech_str = registration_tech_to_string(tech); DBusConnection *conn = ofono_dbus_get_connection(); const char *path = __ofono_atom_get_path(netreg->atom); netreg->technology = tech; if (netreg->technology == -1) return; [...] } I see that if netreg->technology is -1 then there won't be a Technolgy property at all in get_properties. While this is okay for modems which don't support this feature at all, I think this is the wrong behaviour in this case when the modem switches from EDGE to nothing. What do you thing about introducing an empty Technology (e.g. "")? v2: back to original version. rely only on notifications v1: fire OCTI, OWCTI in cregs callback. v0: initial version drivers/atmodem/network-registration.c | 115 +++++++++++++++++++++++++++++--- 1 files changed, 105 insertions(+), 10 deletions(-) diff --git a/drivers/atmodem/network-registration.c b/drivers/atmodem/network-registration.c index f5ccbb1..77c02c4 100644 --- a/drivers/atmodem/network-registration.c +++ b/drivers/atmodem/network-registration.c @@ -54,10 +54,86 @@ 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 details */ + int ouwcti; /* otpion hso 3G info details */ unsigned int vendor; }; +static int option_octi_to_tech(struct netreg_data *nd) +{ + int tech = -1; + switch (nd->octi) { + case 1: /* GSM */ + tech = 0; + break; + case 2: /* GPRS */ + tech = 1; + break; + case 3: /* EDGE */ + tech = 3; + } + + return tech; +} + +static int option_ouwcti_to_tech(struct netreg_data *nd) +{ + int tech = -1; + + switch (nd->ouwcti) { + case 1: /* UMTS */ + tech = 2; + break; + case 2: /* HSDPA */ + tech = 4; + break; + case 3: /* HSUPA */ + tech = 5; + break; + case 4: /* HSPA */ + tech = 6; + } + + return tech; +} + +static void option_octi_ouwcti_to_tech(struct netreg_data *nd) +{ + int tech = -1; + int tech_2g, tech_3g; + + switch (nd->ossysi) { + case -1: + tech_2g = option_octi_to_tech(nd); + tech_3g = option_ouwcti_to_tech(nd); + + /* 3G tech takes precedence over 2G tech */ + if (tech_3g == -1) + tech = tech_2g; + else + tech = tech_3g; + break; + case 0: /* 2G */ + tech = option_octi_to_tech(nd); + break; + case 2: /* 3G */ + tech = option_ouwcti_to_tech(nd); + break; + case 3: /* Unknown */ + break; + } + + DBG("ossysi %d octi %d ouwcti %d tech %d", + nd->ossysi, nd->octi, nd->ouwcti, tech); + + nd->tech = tech; +} + static void extract_mcc_mnc(const char *str, char *mcc, char *mnc) { /* Three digit country code */ @@ -535,7 +611,8 @@ static void option_osigq_notify(GAtResult *result, gpointer user_data) static void option_ouwcti_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; g_at_result_iter_init(&iter, result); @@ -543,15 +620,19 @@ static void option_ouwcti_notify(GAtResult *result, gpointer user_data) if (!g_at_result_iter_next(&iter, "_OUWCTI:")) return; - if (!g_at_result_iter_next_number(&iter, &mode)) + if (!g_at_result_iter_next_number(&iter, &nd->ouwcti)) return; - ofono_info("OWCTI mode: %d", mode); + option_octi_ouwcti_to_tech(nd); + if (nd->ouwcti > 0) + 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; g_at_result_iter_init(&iter, result); @@ -559,10 +640,14 @@ static void option_octi_notify(GAtResult *result, gpointer user_data) 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); + option_octi_ouwcti_to_tech(nd); + if (nd->octi > 0) + ofono_netreg_status_notify(netreg, + nd->status, nd->lac, nd->ci, nd->tech); + } static void ciev_notify(GAtResult *result, gpointer user_data) @@ -626,7 +711,8 @@ static void cind_cb(gboolean ok, GAtResult *result, gpointer user_data) static void option_ossysi_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; g_at_result_iter_init(&iter, result); @@ -634,10 +720,13 @@ static void option_ossysi_notify(GAtResult *result, gpointer user_data) 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("OSSYSI mode: %d", mode); + option_octi_ouwcti_to_tech(nd); + if (nd->tech > 0) + ofono_netreg_status_notify(netreg, + nd->status, nd->lac, nd->ci, nd->tech); } static void huawei_rssi_notify(GAtResult *result, gpointer user_data) @@ -926,7 +1015,7 @@ 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, + g_at_chat_send(nd->chat, "AT_OUWCTI?", none_prefix, NULL, NULL, NULL); g_at_chat_send(nd->chat, "AT_OCTI?", none_prefix, NULL, NULL, NULL); @@ -1021,7 +1110,13 @@ 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; + nd->ouwcti = -1; ofono_netreg_set_data(netreg, nd); g_at_chat_send(chat, "AT+CREG=?", creg_prefix, -- 1.6.6.1 _______________________________________________ ofono mailing list [email protected] http://lists.ofono.org/listinfo/ofono
