From 89c4ea6130dc15c816d6c201b3fdfb72b55c1a59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Jan 2011 15:03:12 +0100 Subject: [PATCH] atmodem: Add support for technology reporting via CNTI --- drivers/atmodem/network-registration.c | 113 +++++++++++++++++-------- 1 file changed, 77 insertions(+), 36 deletions(-) diff --git a/drivers/atmodem/network-registration.c b/drivers/atmodem/network-registration.c index 7a39fc9a..7b04f19b 100644 --- a/drivers/atmodem/network-registration.c +++ b/drivers/atmodem/network-registration.c @@ -38,6 +38,7 @@ #include "gatchat.h" #include "gatresult.h" +#include "common.h" #include "atmodem.h" #include "vendor.h" @@ -82,7 +83,7 @@ static int option_parse_tech(GAtResult *result) { GAtResultIter iter; int s, octi, ouwcti; - int tech = -1; + int tech; g_at_result_iter_init(&iter, result); @@ -106,28 +107,31 @@ static int option_parse_tech(GAtResult *result) switch (octi) { case 1: /* GSM */ - tech = 0; + tech = ACCESS_TECHNOLOGY_GSM; break; case 2: /* GPRS */ - tech = 1; + tech = ACCESS_TECHNOLOGY_GSM; break; case 3: /* EDGE */ - tech = 3; + tech = ACCESS_TECHNOLOGY_GSM_EGPRS; + break; + default: + tech = -1; break; } switch (ouwcti) { case 1: /* UMTS */ - tech = 2; + tech = ACCESS_TECHNOLOGY_UTRAN; break; case 2: /* HSDPA */ - tech = 4; + tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA; break; case 3: /* HSUPA */ - tech = 5; + tech = ACCESS_TECHNOLOGY_UTRAN_HSUPA; break; case 4: /* HSPA */ - tech = 6; + tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA; break; } @@ -267,7 +271,7 @@ static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data) /* Default to GSM */ if (g_at_result_iter_next_number(&iter, &tech) == FALSE) - tech = 0; + tech = ACCESS_TECHNOLOGY_GSM; strncpy(op.name, name, OFONO_MAX_OPERATOR_NAME_LENGTH); op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0'; @@ -462,7 +466,7 @@ static void cops_list_cb(gboolean ok, GAtResult *result, gpointer user_data) extract_mcc_mnc(n, list[num].mcc, list[num].mnc); if (!g_at_result_iter_next_number(&iter, &tech)) - tech = 0; + tech = ACCESS_TECHNOLOGY_GSM; list[num].tech = tech; @@ -961,10 +965,10 @@ static void mbm_erinfo_notify(GAtResult *result, gpointer user_data) /* Convert to tech values from 27.007 */ switch (gsm) { case 1: /* GSM */ - nd->tech = 0; + nd->tech = ACCESS_TECHNOLOGY_GSM; break; case 2: /* EDGE */ - nd->tech = 3; + nd->tech = ACCESS_TECHNOLOGY_GSM_EGPRS; break; default: nd->tech = -1; @@ -972,20 +976,35 @@ static void mbm_erinfo_notify(GAtResult *result, gpointer user_data) switch (umts) { case 1: /* UMTS */ - nd->tech = 2; + nd->tech = ACCESS_TECHNOLOGY_UTRAN; break; case 2: /* UMTS + HSDPA */ - nd->tech = 4; - break; - default: + nd->tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA; break; } } +static int cnti_to_tech(const char *cnti) +{ + if (g_str_equal(cnti, "GSM") == TRUE || + g_str_equal(cnti, "GPRS") == TRUE) + return ACCESS_TECHNOLOGY_GSM; + else if (g_str_equal(cnti, "EDGE") == TRUE) + return ACCESS_TECHNOLOGY_GSM_EGPRS; + else if (g_str_equal(cnti, "UMTS") == TRUE) + return ACCESS_TECHNOLOGY_UTRAN; + else if (g_str_equal(cnti, "HSDPA") == TRUE) + return ACCESS_TECHNOLOGY_UTRAN_HSDPA; + else if (g_str_equal(cnti, "HSUPA") == TRUE) + return ACCESS_TECHNOLOGY_UTRAN_HSUPA; + + return -1; +} + static void gobi_cnti_notify(GAtResult *result, gpointer user_data) { - //struct ofono_netreg *netreg = user_data; - //struct netreg_data *nd = ofono_netreg_get_data(netreg); + struct ofono_netreg *netreg = user_data; + struct netreg_data *nd = ofono_netreg_get_data(netreg); GAtResultIter iter; const char *tech; int option; @@ -1004,13 +1023,13 @@ static void gobi_cnti_notify(GAtResult *result, gpointer user_data) if (g_at_result_iter_next_unquoted_string(&iter, &tech) == FALSE) return; - ofono_info("CNTI: %s", tech); + nd->tech = cnti_to_tech(tech); } static void nw_cnti_notify(GAtResult *result, gpointer user_data) { - //struct ofono_netreg *netreg = user_data; - //struct netreg_data *nd = ofono_netreg_get_data(netreg); + struct ofono_netreg *netreg = user_data; + struct netreg_data *nd = ofono_netreg_get_data(netreg); GAtResultIter iter; const char *tech; int option; @@ -1029,17 +1048,29 @@ static void nw_cnti_notify(GAtResult *result, gpointer user_data) if (g_at_result_iter_next_unquoted_string(&iter, &tech) == FALSE) return; - ofono_info("CNTI: %s", tech); + nd->tech = cnti_to_tech(tech); } -static void option_query_tech_cb(gboolean ok, - GAtResult *result, gpointer user_data) +static void cnti_query_tech_cb(gboolean ok, GAtResult *result, + gpointer user_data) { struct tech_query *tq = user_data; - int tech = -1; + struct netreg_data *nd = ofono_netreg_get_data(tq->netreg); + + ofono_netreg_status_notify(tq->netreg, + tq->status, tq->lac, tq->ci, nd->tech); +} + +static void option_query_tech_cb(gboolean ok, GAtResult *result, + gpointer user_data) +{ + struct tech_query *tq = user_data; + int tech; if (ok) tech = option_parse_tech(result); + else + tech = -1; ofono_netreg_status_notify(tq->netreg, tq->status, tq->lac, tq->ci, tech); @@ -1059,26 +1090,36 @@ static void creg_notify(GAtResult *result, gpointer user_data) if (status != 1 && status != 5) goto notify; + tq = g_try_new0(struct tech_query, 1); + if (tq == NULL) + goto notify; + + tq->status = status; + tq->lac = lac; + tq->ci = ci; + tq->netreg = netreg; + switch (nd->vendor) { + case OFONO_VENDOR_GOBI: + if (g_at_chat_send(nd->chat, "AT*CNTI=0", none_prefix, + cnti_query_tech_cb, tq, g_free) > 0) + return; + break; + case OFONO_VENDOR_NOVATEL: + if (g_at_chat_send(nd->chat, "AT$CNTI=0", none_prefix, + cnti_query_tech_cb, tq, g_free) > 0) + return; + break; case OFONO_VENDOR_OPTION_HSO: - tq = g_new0(struct tech_query, 1); - if (tq == NULL) - break; - - tq->status = status; - tq->lac = lac; - tq->ci = ci; - tq->netreg = netreg; - if (g_at_chat_send(nd->chat, "AT_OCTI?;_OUWCTI?", option_tech_prefix, option_query_tech_cb, tq, g_free) > 0) return; - - g_free(tq); break; } + g_free(tq); + if ((status == 1 || status == 5) && tech == -1) tech = nd->tech;