* [PATCH 1/4] atmodem: add vendor Quectel
2014-06-24 10:08 [PATCH 0/4] Add a driver for Quectel UC15 modules Philip Paeps
@ 2014-06-24 10:08 ` Philip Paeps
0 siblings, 0 replies; 10+ messages in thread
From: Philip Paeps @ 2014-06-24 10:08 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 474 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..05ec872 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_QUECTEL
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 0/4] Add a driver for Quectel UC15 modems
@ 2014-06-26 17:08 Philip Paeps
2014-06-26 17:08 ` [PATCH 1/4] atmodem: add vendor Quectel Philip Paeps
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Philip Paeps @ 2014-06-26 17:08 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 981 bytes --]
Changes since v1:
o Ammended udevng probing to also catch the modem when no
labels have been configured in udev rules.
o Reworked the enable/retry mechanism to be a little bit less
hackish. Commented the rationale in quectel_enable().
o Use prefixes to help the AT parser match queries to replies.
o Fixed style issues and unnecessary casts.
o Make enable() end up in CFUN=4 (powered but radio off).
Philip Paeps (4):
atmodem: add vendor Quectel
udevng: add detection logic for Quectel modems
plugins: add a new driver for Quectel UC15 modems
sim: query Quectel UC15 PIN retries with AT+QPINC?
Makefile.am | 3 +
drivers/atmodem/sim.c | 49 ++++++
drivers/atmodem/vendor.h | 3 +-
plugins/quectel.c | 371 ++++++++++++++++++++++++++++++++++++++++++++++
plugins/udevng.c | 42 ++++++
5 files changed, 467 insertions(+), 1 deletion(-)
create mode 100644 plugins/quectel.c
--
1.7.10.4
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/4] atmodem: add vendor Quectel
2014-06-26 17:08 [PATCH v2 0/4] Add a driver for Quectel UC15 modems Philip Paeps
@ 2014-06-26 17:08 ` Philip Paeps
2014-06-30 18:45 ` Denis Kenzior
2014-06-26 17:08 ` [PATCH 2/4] udevng: add detection logic for Quectel modems Philip Paeps
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Philip Paeps @ 2014-06-26 17:08 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 474 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..05ec872 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_QUECTEL
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/4] udevng: add detection logic for Quectel modems
2014-06-26 17:08 [PATCH v2 0/4] Add a driver for Quectel UC15 modems Philip Paeps
2014-06-26 17:08 ` [PATCH 1/4] atmodem: add vendor Quectel Philip Paeps
@ 2014-06-26 17:08 ` Philip Paeps
2014-06-30 18:46 ` Denis Kenzior
2014-06-26 17:08 ` [PATCH 3/4] plugins: add a new driver for Quectel UC15 modems Philip Paeps
2014-06-26 17:08 ` [PATCH 4/4] sim: query Quectel UC15 PIN retries with AT+QPINC? Philip Paeps
3 siblings, 1 reply; 10+ messages in thread
From: Philip Paeps @ 2014-06-26 17:08 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1865 bytes --]
---
plugins/udevng.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/plugins/udevng.c b/plugins/udevng.c
index d41c6a8..2ee5a24 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_quectel(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, "255/255/255") == 0) {
+ if (g_strcmp0(info->number, "02") == 0)
+ aux = info->devnode;
+ else if (g_strcmp0(info->number, "03") == 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 },
+ { "quectel", setup_quectel },
{ }
};
@@ -1026,6 +1067,7 @@ static struct {
{ "nokia", "option", "0421", "0623" },
{ "samsung", "option", "04e8", "6889" },
{ "samsung", "kalmia" },
+ { "quectel", "option", "05c6", "9090" },
{ }
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] plugins: add a new driver for Quectel UC15 modems
2014-06-26 17:08 [PATCH v2 0/4] Add a driver for Quectel UC15 modems Philip Paeps
2014-06-26 17:08 ` [PATCH 1/4] atmodem: add vendor Quectel Philip Paeps
2014-06-26 17:08 ` [PATCH 2/4] udevng: add detection logic for Quectel modems Philip Paeps
@ 2014-06-26 17:08 ` Philip Paeps
2014-06-30 18:57 ` Denis Kenzior
2014-06-26 17:08 ` [PATCH 4/4] sim: query Quectel UC15 PIN retries with AT+QPINC? Philip Paeps
3 siblings, 1 reply; 10+ messages in thread
From: Philip Paeps @ 2014-06-26 17:08 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 10663 bytes --]
---
Makefile.am | 3 +
plugins/quectel.c | 371 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 374 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index cd83ef4..aee28de 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 += quectel
+builtin_sources += plugins/quectel.c
+
if BLUETOOTH
if BLUEZ4
builtin_modules += bluez4
diff --git a/plugins/quectel.c b/plugins/quectel.c
new file mode 100644
index 0000000..c5f8f41
--- /dev/null
+++ b/plugins/quectel.c
@@ -0,0 +1,371 @@
+/*
+ *
+ * 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 <ofono/log.h>
+
+#include <drivers/atmodem/atutil.h>
+#include <drivers/atmodem/vendor.h>
+
+static const char *cfun_prefix[] = { "+CFUN:", NULL };
+static const char *none_prefix[] = { NULL };
+
+struct quectel_data {
+ GAtChat *modem;
+ GAtChat *aux;
+ struct at_util_sim_state_query *sim_state_query;
+ gboolean have_sim;
+};
+
+static void quectel_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ ofono_info("%s%s", prefix, str);
+}
+
+static int quectel_probe(struct ofono_modem *modem)
+{
+ struct quectel_data *data;
+
+ DBG("%p", modem);
+
+ data = g_try_new0(struct quectel_data, 1);
+ if (data == NULL)
+ return -ENOMEM;
+
+ ofono_modem_set_data(modem, data);
+
+ return 0;
+}
+
+static void quectel_remove(struct ofono_modem *modem)
+{
+ struct quectel_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ at_util_sim_state_query_free(data->sim_state_query);
+ 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, quectel_debug, debug);
+
+ return chat;
+}
+
+static void sim_state_cb(gboolean present, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct quectel_data *data = ofono_modem_get_data(modem);
+
+ DBG("present %d", present);
+
+ at_util_sim_state_query_free(data->sim_state_query);
+ data->sim_state_query = NULL;
+
+ data->have_sim = present;
+
+ ofono_modem_set_powered(modem, TRUE);
+
+ /* Enable +CME error reporting and turn off the radio. */
+ g_at_chat_send(data->aux, "AT+CMEE=1", NULL, NULL, NULL, NULL);
+ g_at_chat_send(data->aux, "AT+CFUN=4", NULL, NULL, NULL, NULL);
+}
+
+static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct quectel_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;
+ }
+
+ data->sim_state_query = at_util_sim_state_query_new(data->aux,
+ 3, 5, sim_state_cb, modem, NULL);
+}
+
+static void cfun_query(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct quectel_data *data = ofono_modem_get_data(modem);
+ GAtResultIter iter;
+ int status;
+
+ DBG("ok %d", ok);
+
+ if (!ok)
+ return;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (g_at_result_iter_next(&iter, "+CFUN:") == FALSE)
+ return;
+
+ g_at_result_iter_next_number(&iter, &status);
+
+ /*
+ * When coming out of reset or transitioning out of CFUN=0, the modem
+ * firmware will respond to most commands with ERROR until some amount
+ * of time (which varies with temperature) passes. Empirical evidence
+ * suggests that the firmware will report an unsolicited +CPIN:
+ * indication when it is ready to be useful.
+ *
+ * Specific issues:
+ *
+ * o The modem firmware powers up in CFUN=1 but responds to
+ * AT+CFUN=4 with ERROR until it has sent an unsolicited
+ * +CPIN: indication.
+ *
+ * o In CFUN=0 or after toggling the modem's reset line, the
+ * modem firmware will respond to AT+CPIN? queries with
+ * +CME ERROR: 10 ("SIM not inserted", regardless of whether
+ * a SIM is actually inserted), again until it has sent an
+ * unsolicited +CPIN: indication.
+ *
+ * Work around these features by temporarily disabling +CME error
+ * reporting and transitioning to CFUN=4 only after polling the
+ * AT+CPIN? status.
+ */
+
+ if (status != 1) {
+ g_at_chat_send(data->aux, "AT+CMEE=0", NULL, NULL,
+ NULL, NULL);
+ g_at_chat_send(data->aux, "AT+CFUN=1", none_prefix,
+ cfun_enable, modem, NULL);
+ return;
+ }
+
+ cfun_enable(TRUE, NULL, modem);
+}
+
+static int quectel_enable(struct ofono_modem *modem)
+{
+ struct quectel_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 &C0", NULL, NULL, NULL, NULL);
+ g_at_chat_send(data->aux, "ATE0 &C0", NULL, NULL, NULL, NULL);
+
+ g_at_chat_send(data->aux, "AT+CFUN?", cfun_prefix,
+ cfun_query, modem, NULL);
+
+ return -EINPROGRESS;
+}
+
+static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct quectel_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 quectel_disable(struct ofono_modem *modem)
+{
+ struct quectel_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", cfun_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 quectel_set_online(struct ofono_modem *modem, ofono_bool_t online,
+ ofono_modem_online_cb_t cb, void *user_data)
+{
+ struct quectel_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, cfun_prefix, set_online_cb,
+ cbd, g_free) > 0)
+ return;
+
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+
+ g_free(cbd);
+}
+
+static void quectel_pre_sim(struct ofono_modem *modem)
+{
+ struct quectel_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
+
+ DBG("%p", modem);
+
+ ofono_devinfo_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
+ data->aux);
+ sim = ofono_sim_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
+ data->aux);
+
+ if (sim && data->have_sim == TRUE)
+ ofono_sim_inserted_notify(sim, TRUE);
+}
+
+static void quectel_post_sim(struct ofono_modem *modem)
+{
+ struct quectel_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_QUECTEL, "atmodem",
+ data->aux);
+ gc = ofono_gprs_context_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
+ data->modem);
+
+ if (gprs && gc)
+ ofono_gprs_add_context(gprs, gc);
+}
+
+static void quectel_post_online(struct ofono_modem *modem)
+{
+ struct quectel_data *data = ofono_modem_get_data(modem);
+
+ ofono_netreg_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
+ data->aux);
+}
+
+static struct ofono_modem_driver quectel_driver = {
+ .name = "quectel",
+ .probe = quectel_probe,
+ .remove = quectel_remove,
+ .enable = quectel_enable,
+ .disable = quectel_disable,
+ .set_online = quectel_set_online,
+ .pre_sim = quectel_pre_sim,
+ .post_sim = quectel_post_sim,
+ .post_online = quectel_post_online,
+};
+
+static int quectel_init(void)
+{
+ return ofono_modem_driver_register(&quectel_driver);
+}
+
+static void quectel_exit(void)
+{
+ ofono_modem_driver_unregister(&quectel_driver);
+}
+
+OFONO_PLUGIN_DEFINE(quectel, "Quectel driver", VERSION,
+ OFONO_PLUGIN_PRIORITY_DEFAULT, quectel_init, quectel_exit)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] sim: query Quectel UC15 PIN retries with AT+QPINC?
2014-06-26 17:08 [PATCH v2 0/4] Add a driver for Quectel UC15 modems Philip Paeps
` (2 preceding siblings ...)
2014-06-26 17:08 ` [PATCH 3/4] plugins: add a new driver for Quectel UC15 modems Philip Paeps
@ 2014-06-26 17:08 ` Philip Paeps
2014-06-30 18:46 ` Denis Kenzior
3 siblings, 1 reply; 10+ messages in thread
From: Philip Paeps @ 2014-06-26 17:08 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2497 bytes --]
---
drivers/atmodem/sim.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index f8e0472..4a91798 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 *qpinc_prefix[] = { "+QPINC:", NULL };
static const char *none_prefix[] = { NULL };
static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -967,6 +968,49 @@ error:
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
}
+static void at_qpinc_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;
+
+ decode_at_error(&error, final);
+
+ if (!ok) {
+ cb(&error, NULL, cbd->data);
+ return;
+ }
+
+ for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
+ retries[i] = -1;
+
+ g_at_result_iter_init(&iter, result);
+ while (g_at_result_iter_next(&iter, "+QPINC:")) {
+ const char *name;
+ int pin, puk;
+
+ if (!g_at_result_iter_next_string(&iter, &name))
+ continue;
+ if (!g_at_result_iter_next_number(&iter, &pin))
+ continue;
+ if (!g_at_result_iter_next_number(&iter, &puk))
+ continue;
+
+ if (!strcmp(name, "SC")) {
+ retries[OFONO_SIM_PASSWORD_SIM_PIN] = pin;
+ retries[OFONO_SIM_PASSWORD_SIM_PUK] = puk;
+ } else if (!strcmp(name, "P2")) {
+ retries[OFONO_SIM_PASSWORD_SIM_PIN2] = pin;
+ retries[OFONO_SIM_PASSWORD_SIM_PUK2] = puk;
+ }
+ }
+ cb(&error, retries, cbd->data);
+}
+
static void at_pin_retries_query(struct ofono_sim *sim,
ofono_sim_pin_retries_cb_t cb,
void *data)
@@ -1028,6 +1072,11 @@ static void at_pin_retries_query(struct ofono_sim *sim,
at_pnnm_cb, cbd, g_free) > 0)
return;
break;
+ case OFONO_VENDOR_QUECTEL:
+ if (g_at_chat_send(sd->chat, "AT+QPINC?", qpinc_prefix,
+ at_qpinc_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] 10+ messages in thread
* Re: [PATCH 1/4] atmodem: add vendor Quectel
2014-06-26 17:08 ` [PATCH 1/4] atmodem: add vendor Quectel Philip Paeps
@ 2014-06-30 18:45 ` Denis Kenzior
0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2014-06-30 18:45 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 218 bytes --]
Hi Philip,
On 06/26/2014 12:08 PM, Philip Paeps wrote:
> ---
> drivers/atmodem/vendor.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
Patch has been applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] udevng: add detection logic for Quectel modems
2014-06-26 17:08 ` [PATCH 2/4] udevng: add detection logic for Quectel modems Philip Paeps
@ 2014-06-30 18:46 ` Denis Kenzior
0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2014-06-30 18:46 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 235 bytes --]
Hi Philip,
On 06/26/2014 12:08 PM, Philip Paeps wrote:
> ---
> plugins/udevng.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
Patch has been applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 4/4] sim: query Quectel UC15 PIN retries with AT+QPINC?
2014-06-26 17:08 ` [PATCH 4/4] sim: query Quectel UC15 PIN retries with AT+QPINC? Philip Paeps
@ 2014-06-30 18:46 ` Denis Kenzior
0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2014-06-30 18:46 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 247 bytes --]
Hi Philip,
On 06/26/2014 12:08 PM, Philip Paeps wrote:
> ---
> drivers/atmodem/sim.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 49 insertions(+)
>
Patch has been applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/4] plugins: add a new driver for Quectel UC15 modems
2014-06-26 17:08 ` [PATCH 3/4] plugins: add a new driver for Quectel UC15 modems Philip Paeps
@ 2014-06-30 18:57 ` Denis Kenzior
0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2014-06-30 18:57 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 6868 bytes --]
Hi Philip,
<snip>
> +static void sim_state_cb(gboolean present, gpointer user_data)
> +{
> + struct ofono_modem *modem = user_data;
> + struct quectel_data *data = ofono_modem_get_data(modem);
> +
> + DBG("present %d", present);
> +
> + at_util_sim_state_query_free(data->sim_state_query);
> + data->sim_state_query = NULL;
> +
> + data->have_sim = present;
> +
> + ofono_modem_set_powered(modem, TRUE);
> +
> + /* Enable +CME error reporting and turn off the radio. */
> + g_at_chat_send(data->aux, "AT+CMEE=1", NULL, NULL, NULL, NULL);
> + g_at_chat_send(data->aux, "AT+CFUN=4", NULL, NULL, NULL, NULL);
Please use none_prefix here since it is already defined.
> +}
> +
<snip>
> +static void cfun_query(gboolean ok, GAtResult *result, gpointer user_data)
> +{
> + struct ofono_modem *modem = user_data;
> + struct quectel_data *data = ofono_modem_get_data(modem);
> + GAtResultIter iter;
> + int status;
> +
> + DBG("ok %d", ok);
> +
> + if (!ok)
> + return;
> +
> + g_at_result_iter_init(&iter, result);
> +
> + if (g_at_result_iter_next(&iter, "+CFUN:") == FALSE)
> + return;
> +
> + g_at_result_iter_next_number(&iter, &status);
> +
> + /*
> + * When coming out of reset or transitioning out of CFUN=0, the modem
> + * firmware will respond to most commands with ERROR until some amount
> + * of time (which varies with temperature) passes. Empirical evidence
> + * suggests that the firmware will report an unsolicited +CPIN:
> + * indication when it is ready to be useful.
> + *
> + * Specific issues:
> + *
> + * o The modem firmware powers up in CFUN=1 but responds to
> + * AT+CFUN=4 with ERROR until it has sent an unsolicited
> + * +CPIN: indication.
> + *
> + * o In CFUN=0 or after toggling the modem's reset line, the
> + * modem firmware will respond to AT+CPIN? queries with
> + * +CME ERROR: 10 ("SIM not inserted", regardless of whether
> + * a SIM is actually inserted), again until it has sent an
> + * unsolicited +CPIN: indication.
> + *
> + * Work around these features by temporarily disabling +CME error
> + * reporting and transitioning to CFUN=4 only after polling the
> + * AT+CPIN? status.
> + */
So why not query CFUN, register to unsolicited CPIN notifications and
query CPIN. If that fails, then in theory CPIN will come in
unsolicited. Beats polling.
> +
> + if (status != 1) {
> + g_at_chat_send(data->aux, "AT+CMEE=0", NULL, NULL,
> + NULL, NULL);
Might want to use a prefix here as well
> + g_at_chat_send(data->aux, "AT+CFUN=1", none_prefix,
> + cfun_enable, modem, NULL);
Should you be using CFUN=4 here?
> + return;
> + }
> +
> + cfun_enable(TRUE, NULL, modem);
> +}
> +
> +static int quectel_enable(struct ofono_modem *modem)
> +{
> + struct quectel_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 &C0", NULL, NULL, NULL, NULL);
> + g_at_chat_send(data->aux, "ATE0 &C0", NULL, NULL, NULL, NULL);
> +
prefixes here
> + g_at_chat_send(data->aux, "AT+CFUN?", cfun_prefix,
> + cfun_query, modem, NULL);
> +
> + return -EINPROGRESS;
> +}
> +
> +static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
> +{
> + struct ofono_modem *modem = user_data;
> + struct quectel_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 quectel_disable(struct ofono_modem *modem)
> +{
> + struct quectel_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", cfun_prefix,
That should probably be none_prefix if the modem follows standards.
> + 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 quectel_set_online(struct ofono_modem *modem, ofono_bool_t online,
> + ofono_modem_online_cb_t cb, void *user_data)
> +{
> + struct quectel_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, cfun_prefix, set_online_cb,
> + cbd, g_free) > 0)
> + return;
> +
> + CALLBACK_WITH_FAILURE(cb, cbd->data);
> +
> + g_free(cbd);
> +}
> +
> +static void quectel_pre_sim(struct ofono_modem *modem)
> +{
> + struct quectel_data *data = ofono_modem_get_data(modem);
> + struct ofono_sim *sim;
> +
> + DBG("%p", modem);
> +
> + ofono_devinfo_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
> + data->aux);
We don't specify VENDOR flags if the atom driver uses default behavior.
That way it is easy to tell where non-standard behavior occurs for a
particular modem. So just use 0 here.
> + sim = ofono_sim_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
> + data->aux);
> +
> + if (sim && data->have_sim == TRUE)
> + ofono_sim_inserted_notify(sim, TRUE);
> +}
> +
> +static void quectel_post_sim(struct ofono_modem *modem)
> +{
> + struct quectel_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_QUECTEL, "atmodem",
> + data->aux);
> + gc = ofono_gprs_context_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
> + data->modem);
Same as above
> +
> + if (gprs && gc)
> + ofono_gprs_add_context(gprs, gc);
> +}
> +
> +static void quectel_post_online(struct ofono_modem *modem)
> +{
> + struct quectel_data *data = ofono_modem_get_data(modem);
> +
> + ofono_netreg_create(modem, OFONO_VENDOR_QUECTEL, "atmodem",
> + data->aux);
And here
> +}
> +
<snip>
Regards,
-Denis
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-06-30 18:57 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-26 17:08 [PATCH v2 0/4] Add a driver for Quectel UC15 modems Philip Paeps
2014-06-26 17:08 ` [PATCH 1/4] atmodem: add vendor Quectel Philip Paeps
2014-06-30 18:45 ` Denis Kenzior
2014-06-26 17:08 ` [PATCH 2/4] udevng: add detection logic for Quectel modems Philip Paeps
2014-06-30 18:46 ` Denis Kenzior
2014-06-26 17:08 ` [PATCH 3/4] plugins: add a new driver for Quectel UC15 modems Philip Paeps
2014-06-30 18:57 ` Denis Kenzior
2014-06-26 17:08 ` [PATCH 4/4] sim: query Quectel UC15 PIN retries with AT+QPINC? Philip Paeps
2014-06-30 18:46 ` Denis Kenzior
-- strict thread matches above, loose matches on Subject: below --
2014-06-24 10:08 [PATCH 0/4] Add a driver for Quectel UC15 modules Philip Paeps
2014-06-24 10:08 ` [PATCH 1/4] atmodem: add vendor Quectel 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.