The U-Blox documentation specifies the following:
* get interface ip and dns from +CGDCONTRDP
* get gw ip and netmask from +UIPADDR

However, different firmware versions have different befaviour:

* On newer firmware, +UIPADDR returns error. But it's possible to configure
gateway ip == ipterface ip (read from CGDCONTRDP).

* On older firmware, we can actually use the commands specified in the
docs.

This patch runs +CGDCONTRDP, configures everything and then tries to run
+UIPADDR. In that works, reconfigures gw ip and netmask.
---
 drivers/ubloxmodem/gprs-context.c | 51 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/drivers/ubloxmodem/gprs-context.c 
b/drivers/ubloxmodem/gprs-context.c
index 3069e88..61b4090 100644
--- a/drivers/ubloxmodem/gprs-context.c
+++ b/drivers/ubloxmodem/gprs-context.c
@@ -43,6 +43,7 @@
 
 static const char *none_prefix[] = { NULL };
 static const char *cgcontrdp_prefix[] = { "+CGCONTRDP:", NULL };
+static const char *uipaddr_prefix[] = { "+UIPADDR:", NULL };
 
 struct gprs_context_data {
        GAtChat *chat;
@@ -51,6 +52,44 @@ struct gprs_context_data {
        void *cb_data;
 };
 
+static void uipaddr_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+       struct ofono_gprs_context *gc = user_data;
+       struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+       GAtResultIter iter;
+
+       const char *gw = NULL;
+       const char *netmask = NULL;
+
+       DBG("ok %d", ok);
+
+       if (!ok) {
+               CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
+               return;
+       }
+
+       g_at_result_iter_init(&iter, result);
+
+       while (g_at_result_iter_next(&iter, "+UIPADDR:")) {
+               g_at_result_iter_skip_next(&iter);
+               g_at_result_iter_skip_next(&iter);
+
+               if (!g_at_result_iter_next_string(&iter, &gw))
+                       break;
+
+               if (!g_at_result_iter_next_string(&iter, &netmask))
+                       break;
+       }
+
+       if (gw)
+               ofono_gprs_context_set_ipv4_gateway(gc, gw);
+
+       if (netmask)
+               ofono_gprs_context_set_ipv4_netmask(gc, netmask);
+
+       CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
+}
+
 /*
  * CGCONTRDP returns addr + netmask in the same string in the form
  * of "a.b.c.d.m.m.m.m" for IPv4. IPv6 is not supported so we ignore it.
@@ -113,6 +152,7 @@ static void cgcontrdp_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
        const char *laddrnetmask = NULL;
        const char *gw = NULL;
        const char *dns[3] = { NULL, NULL, NULL };
+       char buf[64];
 
        DBG("ok %d", ok);
 
@@ -159,7 +199,18 @@ static void cgcontrdp_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
        if (dns[0])
                ofono_gprs_context_set_ipv4_dns_servers(gc, dns);
 
+       /* Some older versions of Toby L2 need to issue AT+UIPADDR to get the
+        * the correct gateway and netmask. The newer version will return an
+        * empty ok reply.
+        */
+       snprintf(buf, sizeof(buf), "AT+UIPADDR=%u", gcd->active_context);
+       if (g_at_chat_send(gcd->chat, buf, uipaddr_prefix,
+                               uipaddr_cb, gc, NULL) > 0)
+               return;
+
+       /* Even if UIPADDR failed, we still have enough data. */
        CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
+
 }
 
 static int ublox_send_cgcontrdp(struct ofono_gprs_context *gc)
-- 
2.7.4

_______________________________________________
ofono mailing list
ofono@ofono.org
https://lists.ofono.org/mailman/listinfo/ofono

Reply via email to