For uBlox modems, a bit of custom setup is required, but after that the
generic "atmodem" (27.007-compatible) method implementations are
sufficient. This driver, therefore, just puts the custom probe method
into place and defers remaining functionality to the recently exported
atmodem implementations.
---
drivers/ubloxmodem/network-registration.c | 425 ++
drivers/ubloxmodem/ubloxmodem.c | 2 +
drivers/ubloxmodem/ubloxmodem.h | 3 +
3 files changed, 430 insertions(+)
create mode 100644 drivers/ubloxmodem/network-registration.c
diff --git a/drivers/ubloxmodem/network-registration.c
b/drivers/ubloxmodem/network-registration.c
new file mode 100644
index ..cfd194a9
--- /dev/null
+++ b/drivers/ubloxmodem/network-registration.c
@@ -0,0 +1,425 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010 ST-Ericsson AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+#include "gatchat.h"
+#include "gatresult.h"
+
+#include "common.h"
+#include "ubloxmodem.h"
+#include "drivers/atmodem/vendor.h"
+
+#include "drivers/atmodem/network-registration.h"
+
+static const char *none_prefix[] = { NULL };
+static const char *cmer_prefix[] = { "+CMER:", NULL };
+static const char *ureg_prefix[] = { "+UREG:", NULL };
+
+struct netreg_data {
+ struct at_netreg_data at_data;
+
+ const struct ublox_model *model;
+};
+
+struct tech_query {
+ int status;
+ int lac;
+ int ci;
+ struct ofono_netreg *netreg;
+};
+
+static void ciev_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct at_netreg_data *nd = ofono_netreg_get_data(netreg);
+ int strength, ind;
+ GAtResultIter iter;
+
+ g_at_result_iter_init(, result);
+
+ if (!g_at_result_iter_next(, "+CIEV:"))
+ return;
+
+ if (!g_at_result_iter_next_number(, ))
+ return;
+
+ if (ind != nd->signal_index)
+ return;
+
+ if (!g_at_result_iter_next_number(, ))
+ return;
+
+ if (strength == nd->signal_invalid)
+ strength = -1;
+ else
+ strength = (strength * 100) / (nd->signal_max - nd->signal_min);
+
+ ofono_netreg_strength_notify(netreg, strength);
+}
+
+static gboolean notify_time(gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct at_netreg_data *nd = ofono_netreg_get_data(netreg);
+
+ nd->nitz_timeout = 0;
+
+ ofono_netreg_time_notify(netreg, >time);
+
+ return FALSE;
+}
+
+static void ctzdst_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct at_netreg_data *nd = ofono_netreg_get_data(netreg);
+ int dst;
+ GAtResultIter iter;
+
+ g_at_result_iter_init(, result);
+
+ if (!g_at_result_iter_next(, "+CTZDST:"))
+ return;
+
+ if (!g_at_result_iter_next_number(, ))
+ return;
+
+ DBG("dst %d", dst);
+
+ nd->time.dst = dst;
+
+ if (nd->nitz_timeout > 0) {
+ g_source_remove(nd->nitz_timeout);
+ nd->nitz_timeout = 0;
+ }
+
+ ofono_netreg_time_notify(netreg, >time);
+}
+
+static void ctzv_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct at_netreg_data *nd = ofono_netreg_get_data(netreg);
+ int year, mon, mday, hour, min, sec;
+ const char *tz, *time;
+ GAtResultIter iter;
+
+ g_at_result_iter_init(, result);
+
+ if (!g_at_result_iter_next(, "+CTZV:"))
+ return;
+
+ if (!g_at_result_iter_next_unquoted_string(, ))
+ return;
+
+ if (!g_at_result_iter_next_string(, ))
+ return;
+
+ DBG("tz %s time %s", tz, time);
+
+ if (sscanf(time, "%u/%u/%u,%u:%u:%u", , , ,
+ , , ) != 6)
+ return;
+
+ nd->time.sec = sec;
+ nd->time.min = min;
+ nd->time.hour = hour;
+ nd->time.mday = mday;
+ nd->time.mon = mon;
+