From 45e3dc1b3ea79abce48e57b9fb4fef66d090ab0a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Aug 2011 00:39:29 +0200 Subject: [PATCH] atmodem: Add support for ZTE technology reporting --- drivers/atmodem/network-registration.c | 78 +++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/atmodem/network-registration.c b/drivers/atmodem/network-registration.c index 3bee1a25..e5e6a2c1 100644 --- a/drivers/atmodem/network-registration.c +++ b/drivers/atmodem/network-registration.c @@ -47,6 +47,7 @@ static const char *creg_prefix[] = { "+CREG:", NULL }; static const char *cops_prefix[] = { "+COPS:", NULL }; static const char *csq_prefix[] = { "+CSQ:", NULL }; static const char *cind_prefix[] = { "+CIND:", NULL }; +static const char *zpas_prefix[] = { "+ZPAS:", NULL }; static const char *option_tech_prefix[] = { "_OCTI:", "_OUWCTI:", NULL }; struct netreg_data { @@ -81,6 +82,40 @@ static void extract_mcc_mnc(const char *str, char *mcc, char *mnc) mnc[OFONO_MAX_MNC_LENGTH] = '\0'; } +static int zte_parse_tech(GAtResult *result) +{ + GAtResultIter iter; + const char *network, *domain; + int tech; + + g_at_result_iter_init(&iter, result); + + if (!g_at_result_iter_next(&iter, "+ZPAS:")) + return -1; + + if (!g_at_result_iter_next_string(&iter, &network)) + return -1; + + if (!g_at_result_iter_next_string(&iter, &domain)) + return -1; + + if (g_str_equal(network, "GSM") == TRUE || + g_str_equal(network, "GPRS") == TRUE) + tech = ACCESS_TECHNOLOGY_GSM; + else if (g_str_equal(network, "EDGE") == TRUE) + tech = ACCESS_TECHNOLOGY_GSM_EGPRS; + else if (g_str_equal(network, "UMTS") == TRUE) + tech = ACCESS_TECHNOLOGY_UTRAN; + else if (g_str_equal(network, "HSDPA") == TRUE) + tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA; + else + tech = -1; + + DBG("network %s domain %s tech %d", network, domain, tech); + + return tech; +} + static int option_parse_tech(GAtResult *result) { GAtResultIter iter; @@ -169,6 +204,18 @@ static void at_creg_cb(gboolean ok, GAtResult *result, gpointer user_data) cb(&error, status, lac, ci, tech, cbd->data); } +static void zte_tech_cb(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct cb_data *cbd = user_data; + struct ofono_netreg *netreg = cbd->data; + struct netreg_data *nd = ofono_netreg_get_data(netreg); + + if (ok) + nd->tech = zte_parse_tech(result); + else + nd->tech = -1; +} + static void option_tech_cb(gboolean ok, GAtResult *result, gpointer user_data) { struct cb_data *cbd = user_data; @@ -215,10 +262,19 @@ static void at_registration_status(struct ofono_netreg *netreg, g_at_chat_send(nd->chat, "AT$CNTI=0", none_prefix, NULL, NULL, NULL); break; + case OFONO_VENDOR_ZTE: + /* + * Send +ZPAS? to find out the current tech, zte_tech_cb + * will call, fire CREG? to do the rest. + */ + if (g_at_chat_send(nd->chat, "AT+ZPAS?", zpas_prefix, + zte_tech_cb, cbd, NULL) == 0) + nd->tech = -1; + break; case OFONO_VENDOR_OPTION_HSO: /* * Send AT_OCTI?;_OUWCTI? to find out the current tech, - * option_tech_cb will call fire CREG? to do the rest. + * option_tech_cb will call, fire CREG? to do the rest. */ if (g_at_chat_send(nd->chat, "AT_OCTI?;_OUWCTI?", option_tech_prefix, @@ -1140,6 +1196,21 @@ static void cnti_query_tech_cb(gboolean ok, GAtResult *result, tq->status, tq->lac, tq->ci, nd->tech); } +static void zte_query_tech_cb(gboolean ok, GAtResult *result, + gpointer user_data) +{ + struct tech_query *tq = user_data; + int tech; + + if (ok) + tech = zte_parse_tech(result); + else + tech = -1; + + ofono_netreg_status_notify(tq->netreg, + tq->status, tq->lac, tq->ci, tech); +} + static void option_query_tech_cb(gboolean ok, GAtResult *result, gpointer user_data) { @@ -1189,6 +1260,11 @@ static void creg_notify(GAtResult *result, gpointer user_data) cnti_query_tech_cb, tq, g_free) > 0) return; break; + case OFONO_VENDOR_ZTE: + if (g_at_chat_send(nd->chat, "AT+ZPAS?", zpas_prefix, + zte_query_tech_cb, tq, g_free) > 0) + return; + break; case OFONO_VENDOR_OPTION_HSO: if (g_at_chat_send(nd->chat, "AT_OCTI?;_OUWCTI?", option_tech_prefix,