* [PATCH 0/6] Add a driver for u-blox modems
@ 2014-06-24 17:10 Philip Paeps
2014-06-24 17:10 ` [PATCH 1/6] atmodem: add vendor u-blox Philip Paeps
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Philip Paeps @ 2014-06-24 17:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 996 bytes --]
This set of patches adds basic support for u-blox modems. It has only
been tested with a u-blox SARA U270 modem but judging from the datasheet
it should be fairly trivial to adapt to other variants of the SARA, LISA
and LEON chips.
Philip Paeps (6):
atmodem: add vendor u-blox
udevng: add detection logic for u-blox modems
plugins: new driver for u-blox SARA-U270 modems
sim: query u-blox PIN retries with AT+UPINCNT
gprs: add support for u-blox +UREG URCs
atmodem: set the auth method for u-blox modems
Makefile.am | 3 +
drivers/atmodem/gprs-context.c | 29 +++-
drivers/atmodem/gprs.c | 44 ++++++
drivers/atmodem/sim.c | 45 +++++++
drivers/atmodem/vendor.h | 3 +-
plugins/ublox.c | 289 ++++++++++++++++++++++++++++++++++++++++
plugins/udevng.c | 42 ++++++
7 files changed, 452 insertions(+), 3 deletions(-)
create mode 100644 plugins/ublox.c
--
1.7.10.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/6] atmodem: add vendor u-blox
2014-06-24 17:10 [PATCH 0/6] Add a driver for u-blox modems Philip Paeps
@ 2014-06-24 17:10 ` Philip Paeps
2014-06-24 17:10 ` [PATCH 2/6] udevng: add detection logic for u-blox modems Philip Paeps
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Philip Paeps @ 2014-06-24 17:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 472 bytes --]
---
drivers/atmodem/vendor.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/atmodem/vendor.h b/drivers/atmodem/vendor.h
index bf2b38a..de3c455 100644
--- a/drivers/atmodem/vendor.h
+++ b/drivers/atmodem/vendor.h
@@ -42,5 +42,6 @@ enum ofono_vendor {
OFONO_VENDOR_SIMCOM_SIM900,
OFONO_VENDOR_ICERA,
OFONO_VENDOR_WAVECOM_Q2XXX,
- OFONO_VENDOR_ALCATEL
+ OFONO_VENDOR_ALCATEL,
+ OFONO_VENDOR_UBLOX
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/6] udevng: add detection logic for u-blox modems
2014-06-24 17:10 [PATCH 0/6] Add a driver for u-blox modems Philip Paeps
2014-06-24 17:10 ` [PATCH 1/6] atmodem: add vendor u-blox Philip Paeps
@ 2014-06-24 17:10 ` Philip Paeps
2014-06-24 17:10 ` [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems Philip Paeps
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Philip Paeps @ 2014-06-24 17:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1851 bytes --]
---
plugins/udevng.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/plugins/udevng.c b/plugins/udevng.c
index d41c6a8..42ee989 100644
--- a/plugins/udevng.c
+++ b/plugins/udevng.c
@@ -791,6 +791,46 @@ static gboolean setup_samsung(struct modem_info *modem)
return TRUE;
}
+static gboolean setup_ublox(struct modem_info *modem)
+{
+ const char *aux = NULL, *mdm = NULL;
+ GSList *list;
+
+ DBG("%s", modem->syspath);
+
+ for (list = modem->devices; list; list = list->next) {
+ struct device_info *info = list->data;
+
+ DBG("%s %s %s %s", info->devnode, info->interface,
+ info->number, info->label);
+
+ if (g_strcmp0(info->label, "aux") == 0) {
+ aux = info->devnode;
+ if (mdm != NULL)
+ break;
+ } else if (g_strcmp0(info->label, "modem") == 0) {
+ mdm = info->devnode;
+ if (aux != NULL)
+ break;
+ } else if (g_strcmp0(info->interface, "2/2/1") == 0) {
+ if (g_strcmp0(info->number, "02") == 0)
+ aux = info->devnode;
+ else if (g_strcmp0(info->number, "00") == 0)
+ mdm = info->devnode;
+ }
+ }
+
+ if (aux == NULL || mdm == NULL)
+ return FALSE;
+
+ DBG("aux=%s modem=%s", aux, mdm);
+
+ ofono_modem_set_string(modem->modem, "Aux", aux);
+ ofono_modem_set_string(modem->modem, "Modem", mdm);
+
+ return TRUE;
+}
+
static struct {
const char *name;
gboolean (*setup)(struct modem_info *modem);
@@ -815,6 +855,7 @@ static struct {
{ "zte", setup_zte },
{ "icera", setup_icera },
{ "samsung", setup_samsung },
+ { "ublox", setup_ublox },
{ }
};
@@ -1026,6 +1067,7 @@ static struct {
{ "nokia", "option", "0421", "0623" },
{ "samsung", "option", "04e8", "6889" },
{ "samsung", "kalmia" },
+ { "ublox", "cdc_acm", "1546", "1102" },
{ }
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems
2014-06-24 17:10 [PATCH 0/6] Add a driver for u-blox modems Philip Paeps
2014-06-24 17:10 ` [PATCH 1/6] atmodem: add vendor u-blox Philip Paeps
2014-06-24 17:10 ` [PATCH 2/6] udevng: add detection logic for u-blox modems Philip Paeps
@ 2014-06-24 17:10 ` Philip Paeps
2014-06-26 14:29 ` Denis Kenzior
2014-06-24 17:10 ` [PATCH 4/6] sim: query u-blox PIN retries with AT+UPINCNT Philip Paeps
` (2 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Philip Paeps @ 2014-06-24 17:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 8081 bytes --]
This driver may also work (perhaps with more or less trivial changes)
with other u-blox modems (SARA, LISA, LEON) but this hasn't been tested.
---
Makefile.am | 3 +
plugins/ublox.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 292 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index cd83ef4..5f98f8e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -420,6 +420,9 @@ builtin_sources += plugins/connman.c
builtin_modules += he910
builtin_sources += plugins/he910.c
+builtin_modules += ublox
+builtin_sources += plugins/ublox.c
+
if BLUETOOTH
if BLUEZ4
builtin_modules += bluez4
diff --git a/plugins/ublox.c b/plugins/ublox.c
new file mode 100644
index 0000000..4cdc966
--- /dev/null
+++ b/plugins/ublox.c
@@ -0,0 +1,289 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2014 Philip Paeps. All rights reserved.
+ *
+ * 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 <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <gatchat.h>
+#include <gattty.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/modem.h>
+#include <ofono/devinfo.h>
+#include <ofono/netreg.h>
+#include <ofono/sim.h>
+#include <ofono/gprs.h>
+#include <ofono/gprs-context.h>
+
+#include <drivers/atmodem/atutil.h>
+#include <drivers/atmodem/vendor.h>
+
+struct ublox_data {
+ GAtChat *modem;
+ GAtChat *aux;
+};
+
+static void ublox_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ ofono_info("%s%s", prefix, str);
+}
+
+static int ublox_probe(struct ofono_modem *modem)
+{
+ struct ublox_data *data;
+
+ DBG("%p", modem);
+
+ data = g_try_new0(struct ublox_data, 1);
+ if (data == NULL)
+ return -ENOMEM;
+
+ ofono_modem_set_data(modem, data);
+
+ return 0;
+}
+
+static void ublox_remove(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ ofono_modem_set_data(modem, NULL);
+ g_at_chat_unref(data->aux);
+ g_free(data);
+}
+
+static GAtChat *open_device(struct ofono_modem *modem,
+ const char *key, char *debug)
+{
+ const char *device;
+ GAtSyntax *syntax;
+ GIOChannel *channel;
+ GAtChat *chat;
+
+ device = ofono_modem_get_string(modem, key);
+ if (device == NULL)
+ return NULL;
+
+ DBG("%s %s", key, device);
+
+ channel = g_at_tty_open(device, NULL);
+ if (channel == NULL)
+ return NULL;
+
+ syntax = g_at_syntax_new_gsm_permissive();
+ chat = g_at_chat_new(channel, syntax);
+ g_at_syntax_unref(syntax);
+
+ g_io_channel_unref(channel);
+
+ if (chat == NULL)
+ return NULL;
+
+ if (getenv("OFONO_AT_DEBUG"))
+ g_at_chat_set_debug(chat, ublox_debug, debug);
+
+ return chat;
+}
+
+
+static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct ublox_data * data = ofono_modem_get_data(modem);
+
+ DBG("ok %d", (int)ok);
+
+ if (!ok) {
+ g_at_chat_unref(data->aux);
+ data->aux = NULL;
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+ }
+
+ ofono_modem_set_powered(modem, TRUE);
+
+ g_at_chat_send(data->modem, "AT&C0", NULL, NULL, NULL, NULL);
+ g_at_chat_send(data->aux, "AT&C0", NULL, NULL, NULL, NULL);
+}
+
+static int ublox_enable(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ data->modem = open_device(modem, "Modem", "Modem: ");
+ if (data->modem == NULL)
+ return -EINVAL;
+
+ data->aux = open_device(modem, "Aux", "Aux: ");
+ if (data->aux == NULL) {
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+ return -EIO;
+ }
+ g_at_chat_set_slave(data->modem, data->aux);
+
+ g_at_chat_send(data->modem, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
+ g_at_chat_send(data->aux, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
+
+ g_at_chat_send(data->aux, "AT+CFUN=1", NULL, cfun_enable,
+ modem, NULL);
+
+ return -EINPROGRESS;
+}
+
+static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("");
+
+ g_at_chat_unref(data->aux);
+ data->aux = NULL;
+
+ if (ok)
+ ofono_modem_set_powered(modem, FALSE);
+}
+
+static int ublox_disable(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ g_at_chat_cancel_all(data->modem);
+ g_at_chat_unregister_all(data->modem);
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+
+ g_at_chat_cancel_all(data->aux);
+ g_at_chat_unregister_all(data->aux);
+
+ g_at_chat_send(data->aux, "AT+CFUN=0", NULL,
+ cfun_disable, modem, NULL);
+
+ return -EINPROGRESS;
+}
+
+static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_modem_online_cb_t cb = cbd->cb;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+ cb(&error, cbd->data);
+}
+
+static void ublox_set_online(struct ofono_modem *modem, ofono_bool_t online,
+ ofono_modem_online_cb_t cb, void *user_data)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+ struct cb_data *cbd = cb_data_new(cb, user_data);
+ char const *command = online ? "AT+CFUN=1" : "AT+CFUN=4";
+
+ DBG("modem %p %s", modem, online ? "online" : "offline");
+
+ if (g_at_chat_send(data->aux, command, NULL, set_online_cb,
+ cbd, g_free) > 0)
+ return;
+
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+
+ g_free(cbd);
+}
+
+static void ublox_pre_sim(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
+
+ DBG("%p", modem);
+
+ ofono_devinfo_create(modem, 0, "atmodem", data->aux);
+ sim = ofono_sim_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->aux);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
+}
+
+static void ublox_post_sim(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+ struct ofono_gprs *gprs;
+ struct ofono_gprs_context *gc;
+
+ DBG("%p", modem);
+
+ gprs = ofono_gprs_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->aux);
+ gc = ofono_gprs_context_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->modem);
+
+ if (gprs && gc)
+ ofono_gprs_add_context(gprs, gc);
+}
+
+static void ublox_post_online(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ ofono_netreg_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->aux);
+}
+
+static struct ofono_modem_driver ublox_driver = {
+ .name = "ublox",
+ .probe = ublox_probe,
+ .remove = ublox_remove,
+ .enable = ublox_enable,
+ .disable = ublox_disable,
+ .set_online = ublox_set_online,
+ .pre_sim = ublox_pre_sim,
+ .post_sim = ublox_post_sim,
+ .post_online = ublox_post_online,
+};
+
+static int ublox_init(void)
+{
+ return ofono_modem_driver_register(&ublox_driver);
+}
+
+static void ublox_exit(void)
+{
+ ofono_modem_driver_unregister(&ublox_driver);
+}
+
+OFONO_PLUGIN_DEFINE(ublox, "u-blox modem driver", VERSION,
+ OFONO_PLUGIN_PRIORITY_DEFAULT, ublox_init, ublox_exit)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/6] sim: query u-blox PIN retries with AT+UPINCNT
2014-06-24 17:10 [PATCH 0/6] Add a driver for u-blox modems Philip Paeps
` (2 preceding siblings ...)
2014-06-24 17:10 ` [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems Philip Paeps
@ 2014-06-24 17:10 ` Philip Paeps
2014-06-24 17:10 ` [PATCH 5/6] gprs: add support for u-blox +UREG URCs Philip Paeps
2014-06-24 17:10 ` [PATCH 6/6] atmodem: set the auth method for u-blox modems Philip Paeps
5 siblings, 0 replies; 11+ messages in thread
From: Philip Paeps @ 2014-06-24 17:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2277 bytes --]
---
drivers/atmodem/sim.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index f8e0472..9b8d176 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -67,6 +67,7 @@ static const char *epin_prefix[] = { "*EPIN:", NULL };
static const char *spic_prefix[] = { "+SPIC:", NULL };
static const char *pct_prefix[] = { "#PCT:", NULL };
static const char *pnnm_prefix[] = { "+PNNM:", NULL };
+static const char *upincnt_prefix[] = { "+UPINCNT:", NULL };
static const char *none_prefix[] = { NULL };
static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -967,6 +968,45 @@ error:
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
}
+static void upincnt_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_sim_pin_retries_cb_t cb = cbd->cb;
+ const char *final = g_at_result_final_response(result);
+ GAtResultIter iter;
+ struct ofono_error error;
+ int retries[OFONO_SIM_PASSWORD_INVALID];
+ size_t i;
+ static enum ofono_sim_password_type password_types[] = {
+ OFONO_SIM_PASSWORD_SIM_PIN,
+ OFONO_SIM_PASSWORD_SIM_PIN2,
+ OFONO_SIM_PASSWORD_SIM_PUK,
+ OFONO_SIM_PASSWORD_SIM_PUK2,
+ };
+
+ decode_at_error(&error, final);
+
+ if (!ok) {
+ cb(&error, NULL, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+UPINCNT:"))
+ goto error;
+
+ BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
+ retries);
+
+ cb(&error, retries, cbd->data);
+
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
+}
+
static void at_pin_retries_query(struct ofono_sim *sim,
ofono_sim_pin_retries_cb_t cb,
void *data)
@@ -1028,6 +1068,11 @@ static void at_pin_retries_query(struct ofono_sim *sim,
at_pnnm_cb, cbd, g_free) > 0)
return;
break;
+ case OFONO_VENDOR_UBLOX:
+ if (g_at_chat_send(sd->chat, "AT+UPINCNT", upincnt_prefix,
+ upincnt_cb, cbd, g_free) > 0)
+ return;
+ break;
default:
if (g_at_chat_send(sd->chat, "AT+CPINR", cpinr_prefixes,
at_cpinr_cb, cbd, g_free) > 0)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/6] gprs: add support for u-blox +UREG URCs
2014-06-24 17:10 [PATCH 0/6] Add a driver for u-blox modems Philip Paeps
` (3 preceding siblings ...)
2014-06-24 17:10 ` [PATCH 4/6] sim: query u-blox PIN retries with AT+UPINCNT Philip Paeps
@ 2014-06-24 17:10 ` Philip Paeps
2014-06-24 17:10 ` [PATCH 6/6] atmodem: set the auth method for u-blox modems Philip Paeps
5 siblings, 0 replies; 11+ messages in thread
From: Philip Paeps @ 2014-06-24 17:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1751 bytes --]
---
drivers/atmodem/gprs.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c
index 3005867..5551316 100644
--- a/drivers/atmodem/gprs.c
+++ b/drivers/atmodem/gprs.c
@@ -282,6 +282,44 @@ static void telit_mode_notify(GAtResult *result, gpointer user_data)
ofono_gprs_bearer_notify(gprs, bearer);
}
+static void ublox_ureg_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_gprs *gprs = user_data;
+ GAtResultIter iter;
+ gint state, bearer;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+UREG:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &state))
+ return;
+
+ switch (state) {
+ case 4:
+ bearer = 5;
+ break;
+ case 5:
+ bearer = 4;
+ break;
+ case 7:
+ /* XXX: reserved - assume none. */
+ bearer = 0;
+ break;
+ case 8:
+ bearer = 1;
+ break;
+ case 9:
+ bearer = 2;
+ break;
+ default:
+ bearer = state;
+ }
+
+ ofono_gprs_bearer_notify(gprs, bearer);
+}
+
static void cpsb_notify(GAtResult *result, gpointer user_data)
{
struct ofono_gprs *gprs = user_data;
@@ -316,6 +354,12 @@ static void gprs_initialized(gboolean ok, GAtResult *result, gpointer user_data)
g_at_chat_register(gd->chat, "^MODE:", huawei_mode_notify,
FALSE, gprs, NULL);
break;
+ case OFONO_VENDOR_UBLOX:
+ g_at_chat_register(gd->chat, "+UREG:", ublox_ureg_notify,
+ FALSE, gprs, NULL);
+ g_at_chat_send(gd->chat, "AT+UREG=1", none_prefix,
+ NULL, NULL, NULL);
+ break;
case OFONO_VENDOR_TELIT:
g_at_chat_register(gd->chat, "#PSNT:", telit_mode_notify,
FALSE, gprs, NULL);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/6] atmodem: set the auth method for u-blox modems
2014-06-24 17:10 [PATCH 0/6] Add a driver for u-blox modems Philip Paeps
` (4 preceding siblings ...)
2014-06-24 17:10 ` [PATCH 5/6] gprs: add support for u-blox +UREG URCs Philip Paeps
@ 2014-06-24 17:10 ` Philip Paeps
5 siblings, 0 replies; 11+ messages in thread
From: Philip Paeps @ 2014-06-24 17:10 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1478 bytes --]
---
drivers/atmodem/gprs-context.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/atmodem/gprs-context.c b/drivers/atmodem/gprs-context.c
index be44443..ebb4960 100644
--- a/drivers/atmodem/gprs-context.c
+++ b/drivers/atmodem/gprs-context.c
@@ -282,9 +282,34 @@ static void at_gprs_activate_primary(struct ofono_gprs_context *gc,
len = snprintf(buf, sizeof(buf), "AT+CGDCONT=%u,\"IP\"", ctx->cid);
- if (ctx->apn)
- snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"",
+ if (ctx->apn) {
+ switch (gcd->vendor) {
+ case OFONO_VENDOR_UBLOX:
+ /*
+ * U-blox modems require a magic prefix to the APN to
+ * specify the authentication method to use in the
+ * network. See UBX-13002752 - R21.
+ *
+ * As the response of the read command omits this magic
+ * prefix, this is the least invasive place to set it.
+ */
+ switch (ctx->auth_method) {
+ case OFONO_GPRS_AUTH_METHOD_CHAP:
+ snprintf(buf + len, sizeof(buf) - len - 3,
+ ",\"CHAP:%s\"", ctx->apn);
+ break;
+ case OFONO_GPRS_AUTH_METHOD_PAP:
+ snprintf(buf + len, sizeof(buf) - len - 3,
+ ",\"PAP:%s\"", ctx->apn);
+ break;
+ }
+ break;
+ default:
+ snprintf(buf + len, sizeof(buf) - len - 3, ",\"%s\"",
ctx->apn);
+ break;
+ }
+ }
if (g_at_chat_send(gcd->chat, buf, none_prefix,
at_cgdcont_cb, gc, NULL) > 0)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems
2014-06-24 17:10 ` [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems Philip Paeps
@ 2014-06-26 14:29 ` Denis Kenzior
2014-06-26 14:49 ` Philip Paeps
0 siblings, 1 reply; 11+ messages in thread
From: Denis Kenzior @ 2014-06-26 14:29 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3770 bytes --]
Hi Philip,
> +static void ublox_remove(struct ofono_modem *modem)
> +{
> + struct ublox_data *data = ofono_modem_get_data(modem);
> +
> + DBG("%p", modem);
> +
> + ofono_modem_set_data(modem, NULL);
> + g_at_chat_unref(data->aux);
Any reason data->modem is not being unrefed? e.g in the case of hot-unplug?
> + g_free(data);
> +}
> +
> +static GAtChat *open_device(struct ofono_modem *modem,
> + const char *key, char *debug)
> +{
> + const char *device;
> + GAtSyntax *syntax;
> + GIOChannel *channel;
> + GAtChat *chat;
> +
> + device = ofono_modem_get_string(modem, key);
> + if (device == NULL)
> + return NULL;
> +
> + DBG("%s %s", key, device);
> +
> + channel = g_at_tty_open(device, NULL);
> + if (channel == NULL)
> + return NULL;
> +
> + syntax = g_at_syntax_new_gsm_permissive();
> + chat = g_at_chat_new(channel, syntax);
> + g_at_syntax_unref(syntax);
> +
> + g_io_channel_unref(channel);
> +
> + if (chat == NULL)
> + return NULL;
> +
> + if (getenv("OFONO_AT_DEBUG"))
> + g_at_chat_set_debug(chat, ublox_debug, debug);
> +
> + return chat;
> +}
> +
> +
Please remove one whitespace. Our coding style likes to use a single
empty line to separate functions.
> +static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
> +{
> + struct ofono_modem *modem = user_data;
> + struct ublox_data * data = ofono_modem_get_data(modem);
> +
> + DBG("ok %d", (int)ok);
No need to cast
> +
> + if (!ok) {
> + g_at_chat_unref(data->aux);
> + data->aux = NULL;
> + g_at_chat_unref(data->modem);
> + data->modem = NULL;
> + }
> +
> + ofono_modem_set_powered(modem, TRUE);
> +
> + g_at_chat_send(data->modem, "AT&C0", NULL, NULL, NULL, NULL);
> + g_at_chat_send(data->aux, "AT&C0", NULL, NULL, NULL, NULL);
Might want to use prefixes here
> +}
> +
> +static int ublox_enable(struct ofono_modem *modem)
> +{
> + struct ublox_data *data = ofono_modem_get_data(modem);
> +
> + DBG("%p", modem);
> +
> + data->modem = open_device(modem, "Modem", "Modem: ");
> + if (data->modem == NULL)
> + return -EINVAL;
> +
> + data->aux = open_device(modem, "Aux", "Aux: ");
> + if (data->aux == NULL) {
> + g_at_chat_unref(data->modem);
> + data->modem = NULL;
> + return -EIO;
> + }
> + g_at_chat_set_slave(data->modem, data->aux);
> +
> + g_at_chat_send(data->modem, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
> + g_at_chat_send(data->aux, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
> +
> + g_at_chat_send(data->aux, "AT+CFUN=1", NULL, cfun_enable,
> + modem, NULL);
Prefix should probably be used. Also, should this be CFUN=4 and not 1?
enable() callback should be putting the modem in the SIM powered, RX/TX
off mode (e.g. Offline).
> +
> + return -EINPROGRESS;
> +}
> +
> +static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
> +{
> + struct ofono_modem *modem = user_data;
> + struct ublox_data *data = ofono_modem_get_data(modem);
> +
> + DBG("");
> +
> + g_at_chat_unref(data->aux);
> + data->aux = NULL;
> +
> + if (ok)
> + ofono_modem_set_powered(modem, FALSE);
> +}
> +
> +static int ublox_disable(struct ofono_modem *modem)
> +{
> + struct ublox_data *data = ofono_modem_get_data(modem);
> +
> + DBG("%p", modem);
> +
> + g_at_chat_cancel_all(data->modem);
> + g_at_chat_unregister_all(data->modem);
> + g_at_chat_unref(data->modem);
> + data->modem = NULL;
> +
> + g_at_chat_cancel_all(data->aux);
> + g_at_chat_unregister_all(data->aux);
> +
> + g_at_chat_send(data->aux, "AT+CFUN=0", NULL,
> + cfun_disable, modem, NULL);
This modem doesn't jump off the bus on CFUN=0, right?
> +
> + return -EINPROGRESS;
> +}
> +
<snip>
Regards,
-Denis
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems
2014-06-26 14:29 ` Denis Kenzior
@ 2014-06-26 14:49 ` Philip Paeps
2014-06-26 15:35 ` Denis Kenzior
0 siblings, 1 reply; 11+ messages in thread
From: Philip Paeps @ 2014-06-26 14:49 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1752 bytes --]
On 2014-06-26 09:29:51 (-0500), Denis Kenzior <denkenz@gmail.com> wrote:
> > +static void ublox_remove(struct ofono_modem *modem)
> > +{
> > + struct ublox_data *data = ofono_modem_get_data(modem);
> > +
> > + DBG("%p", modem);
> > +
> > + ofono_modem_set_data(modem, NULL);
> > + g_at_chat_unref(data->aux);
>
> Any reason data->modem is not being unrefed? e.g in the case of hot-unplug?
As far as I can tell, disable is always called before remove. In the
hot-unplug case, ofonod -d output goes:
ofonod[680]: src/gprs.c:gprs_remove() atom: 0x1443220
ofonod[680]: src/sim.c:sim_remove() atom: 0x1442fb0
ofonod[680]: src/modem.c:devinfo_remove() atom: 0x14425a0
ofonod[680]: plugins/ublox.c:ublox_disable() 0x143ba00
ofonod[680]: plugins/ublox.c:ublox_remove() 0x143ba00
ofonod[680]: src/modem.c:unregister_property() property 0x143bb00
ofonod[680]: src/modem.c:unregister_property() property 0x14448e0
Am I missing something?
> > +static int ublox_enable(struct ofono_modem *modem)
> > + [...]
> > + g_at_chat_send(data->aux, "AT+CFUN=1", NULL, cfun_enable,
> > + modem, NULL);
>
> Prefix should probably be used. Also, should this be CFUN=4 and not 1?
> enable() callback should be putting the modem in the SIM powered, RX/TX
> off mode (e.g. Offline).
Good point. I'll fix that in the quectel driver too.
> > +static int ublox_disable(struct ofono_modem *modem)
> > +{
> > + [...]
> > + g_at_chat_send(data->aux, "AT+CFUN=0", NULL,
> > + cfun_disable, modem, NULL);
>
> This modem doesn't jump off the bus on CFUN=0, right?
Nope. It stays on the bus with the radio off.
Thanks for the review!
Philip
--
Philip Paeps
Senior Reality Engineer
Ministry of Information
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems
2014-06-26 14:49 ` Philip Paeps
@ 2014-06-26 15:35 ` Denis Kenzior
0 siblings, 0 replies; 11+ messages in thread
From: Denis Kenzior @ 2014-06-26 15:35 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1215 bytes --]
Hi Philip,
On 06/26/2014 09:49 AM, Philip Paeps wrote:
> On 2014-06-26 09:29:51 (-0500), Denis Kenzior <denkenz@gmail.com> wrote:
>>> +static void ublox_remove(struct ofono_modem *modem)
>>> +{
>>> + struct ublox_data *data = ofono_modem_get_data(modem);
>>> +
>>> + DBG("%p", modem);
>>> +
>>> + ofono_modem_set_data(modem, NULL);
>>> + g_at_chat_unref(data->aux);
>>
>> Any reason data->modem is not being unrefed? e.g in the case of hot-unplug?
>
> As far as I can tell, disable is always called before remove. In the
> hot-unplug case, ofonod -d output goes:
>
> ofonod[680]: src/gprs.c:gprs_remove() atom: 0x1443220
> ofonod[680]: src/sim.c:sim_remove() atom: 0x1442fb0
> ofonod[680]: src/modem.c:devinfo_remove() atom: 0x14425a0
> ofonod[680]: plugins/ublox.c:ublox_disable() 0x143ba00
> ofonod[680]: plugins/ublox.c:ublox_remove() 0x143ba00
> ofonod[680]: src/modem.c:unregister_property() property 0x143bb00
> ofonod[680]: src/modem.c:unregister_property() property 0x14448e0
>
> Am I missing something?
>
ofono_modem_remove calls disable() only if the modem is powered. So in
cases of e.g. modem still being powered up, disable() won't be called.
Regards,
-Denis
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems
2014-06-26 18:28 [PATCH v2 0/6] Add a driver " Philip Paeps
@ 2014-06-26 18:28 ` Philip Paeps
0 siblings, 0 replies; 11+ messages in thread
From: Philip Paeps @ 2014-06-26 18:28 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 8125 bytes --]
This driver may also work (perhaps with more or less trivial changes)
with other u-blox modems (SARA, LISA, LEON) but this hasn't been tested.
---
Makefile.am | 3 +
plugins/ublox.c | 291 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 294 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index cd83ef4..5f98f8e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -420,6 +420,9 @@ builtin_sources += plugins/connman.c
builtin_modules += he910
builtin_sources += plugins/he910.c
+builtin_modules += ublox
+builtin_sources += plugins/ublox.c
+
if BLUETOOTH
if BLUEZ4
builtin_modules += bluez4
diff --git a/plugins/ublox.c b/plugins/ublox.c
new file mode 100644
index 0000000..99ddc81
--- /dev/null
+++ b/plugins/ublox.c
@@ -0,0 +1,291 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2014 Philip Paeps. All rights reserved.
+ *
+ * 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 <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <gatchat.h>
+#include <gattty.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/modem.h>
+#include <ofono/devinfo.h>
+#include <ofono/netreg.h>
+#include <ofono/sim.h>
+#include <ofono/gprs.h>
+#include <ofono/gprs-context.h>
+
+#include <drivers/atmodem/atutil.h>
+#include <drivers/atmodem/vendor.h>
+
+static const char *none_prefix[] = { NULL };
+
+struct ublox_data {
+ GAtChat *modem;
+ GAtChat *aux;
+};
+
+static void ublox_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ ofono_info("%s%s", prefix, str);
+}
+
+static int ublox_probe(struct ofono_modem *modem)
+{
+ struct ublox_data *data;
+
+ DBG("%p", modem);
+
+ data = g_try_new0(struct ublox_data, 1);
+ if (data == NULL)
+ return -ENOMEM;
+
+ ofono_modem_set_data(modem, data);
+
+ return 0;
+}
+
+static void ublox_remove(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ ofono_modem_set_data(modem, NULL);
+ g_at_chat_unref(data->aux);
+ g_at_chat_unref(data->modem);
+ g_free(data);
+}
+
+static GAtChat *open_device(struct ofono_modem *modem,
+ const char *key, char *debug)
+{
+ const char *device;
+ GAtSyntax *syntax;
+ GIOChannel *channel;
+ GAtChat *chat;
+
+ device = ofono_modem_get_string(modem, key);
+ if (device == NULL)
+ return NULL;
+
+ DBG("%s %s", key, device);
+
+ channel = g_at_tty_open(device, NULL);
+ if (channel == NULL)
+ return NULL;
+
+ syntax = g_at_syntax_new_gsm_permissive();
+ chat = g_at_chat_new(channel, syntax);
+ g_at_syntax_unref(syntax);
+
+ g_io_channel_unref(channel);
+
+ if (chat == NULL)
+ return NULL;
+
+ if (getenv("OFONO_AT_DEBUG"))
+ g_at_chat_set_debug(chat, ublox_debug, debug);
+
+ return chat;
+}
+
+static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct ublox_data * data = ofono_modem_get_data(modem);
+
+ DBG("ok %d", ok);
+
+ if (!ok) {
+ g_at_chat_unref(data->aux);
+ data->aux = NULL;
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+ ofono_modem_set_powered(modem, FALSE);
+ return;
+ }
+
+ ofono_modem_set_powered(modem, TRUE);
+}
+
+static int ublox_enable(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ data->modem = open_device(modem, "Modem", "Modem: ");
+ if (data->modem == NULL)
+ return -EINVAL;
+
+ data->aux = open_device(modem, "Aux", "Aux: ");
+ if (data->aux == NULL) {
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+ return -EIO;
+ }
+ g_at_chat_set_slave(data->modem, data->aux);
+
+ g_at_chat_send(data->modem, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
+ g_at_chat_send(data->aux, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
+
+ g_at_chat_send(data->aux, "AT+CFUN=4", none_prefix,
+ cfun_enable, modem, NULL);
+
+ return -EINPROGRESS;
+}
+
+static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("");
+
+ g_at_chat_unref(data->aux);
+ data->aux = NULL;
+
+ if (ok)
+ ofono_modem_set_powered(modem, FALSE);
+}
+
+static int ublox_disable(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ g_at_chat_cancel_all(data->modem);
+ g_at_chat_unregister_all(data->modem);
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+
+ g_at_chat_cancel_all(data->aux);
+ g_at_chat_unregister_all(data->aux);
+
+ g_at_chat_send(data->aux, "AT+CFUN=0", none_prefix,
+ cfun_disable, modem, NULL);
+
+ return -EINPROGRESS;
+}
+
+static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_modem_online_cb_t cb = cbd->cb;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+ cb(&error, cbd->data);
+}
+
+static void ublox_set_online(struct ofono_modem *modem, ofono_bool_t online,
+ ofono_modem_online_cb_t cb, void *user_data)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+ struct cb_data *cbd = cb_data_new(cb, user_data);
+ char const *command = online ? "AT+CFUN=1" : "AT+CFUN=4";
+
+ DBG("modem %p %s", modem, online ? "online" : "offline");
+
+ if (g_at_chat_send(data->aux, command, none_prefix, set_online_cb,
+ cbd, g_free) > 0)
+ return;
+
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+
+ g_free(cbd);
+}
+
+static void ublox_pre_sim(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
+
+ DBG("%p", modem);
+
+ ofono_devinfo_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->aux);
+ sim = ofono_sim_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->aux);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, TRUE);
+}
+
+static void ublox_post_sim(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+ struct ofono_gprs *gprs;
+ struct ofono_gprs_context *gc;
+
+ DBG("%p", modem);
+
+ gprs = ofono_gprs_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->aux);
+ gc = ofono_gprs_context_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->modem);
+
+ if (gprs && gc)
+ ofono_gprs_add_context(gprs, gc);
+}
+
+static void ublox_post_online(struct ofono_modem *modem)
+{
+ struct ublox_data *data = ofono_modem_get_data(modem);
+
+ ofono_netreg_create(modem, OFONO_VENDOR_UBLOX, "atmodem",
+ data->aux);
+}
+
+static struct ofono_modem_driver ublox_driver = {
+ .name = "ublox",
+ .probe = ublox_probe,
+ .remove = ublox_remove,
+ .enable = ublox_enable,
+ .disable = ublox_disable,
+ .set_online = ublox_set_online,
+ .pre_sim = ublox_pre_sim,
+ .post_sim = ublox_post_sim,
+ .post_online = ublox_post_online,
+};
+
+static int ublox_init(void)
+{
+ return ofono_modem_driver_register(&ublox_driver);
+}
+
+static void ublox_exit(void)
+{
+ ofono_modem_driver_unregister(&ublox_driver);
+}
+
+OFONO_PLUGIN_DEFINE(ublox, "u-blox modem driver", VERSION,
+ OFONO_PLUGIN_PRIORITY_DEFAULT, ublox_init, ublox_exit)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-06-26 18:28 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-24 17:10 [PATCH 0/6] Add a driver for u-blox modems Philip Paeps
2014-06-24 17:10 ` [PATCH 1/6] atmodem: add vendor u-blox Philip Paeps
2014-06-24 17:10 ` [PATCH 2/6] udevng: add detection logic for u-blox modems Philip Paeps
2014-06-24 17:10 ` [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems Philip Paeps
2014-06-26 14:29 ` Denis Kenzior
2014-06-26 14:49 ` Philip Paeps
2014-06-26 15:35 ` Denis Kenzior
2014-06-24 17:10 ` [PATCH 4/6] sim: query u-blox PIN retries with AT+UPINCNT Philip Paeps
2014-06-24 17:10 ` [PATCH 5/6] gprs: add support for u-blox +UREG URCs Philip Paeps
2014-06-24 17:10 ` [PATCH 6/6] atmodem: set the auth method for u-blox modems Philip Paeps
-- strict thread matches above, loose matches on Subject: below --
2014-06-26 18:28 [PATCH v2 0/6] Add a driver " Philip Paeps
2014-06-26 18:28 ` [PATCH 3/6] plugins: new driver for u-blox SARA-U270 modems Philip Paeps
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.