summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorMartin Hundebøll <martin@geanix.com>2019-07-10 23:51:48 +0200
committerDenis Kenzior <denkenz@gmail.com>2019-07-12 11:00:52 -0500
commit57b4aa367881e2bd11e41e96f68e9e6fe1b8a403 (patch)
tree476e650251305b47b7a3ec165e51b149cdf7714e /plugins
parentded2915fd56efbb415ad3534f44c984ecfa589b3 (diff)
downloadofono-57b4aa367881e2bd11e41e96f68e9e6fe1b8a403.tar.gz
quectel: initialize call, phonebook and sms when ready
The Quectel M95 modem issues a "Call ready" notification when call and phonebook are ready, so set up a listener for that. The only way to know when sms is ready is to issue QINITSTAT queries. Since sms is always ready after call and phonebook, the queries are initiated after creating call/phonebook.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/quectel.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/plugins/quectel.c b/plugins/quectel.c
index 8cc1ecd4..11b864bc 100644
--- a/plugins/quectel.c
+++ b/plugins/quectel.c
@@ -42,6 +42,9 @@
#include <ofono/devinfo.h>
#include <ofono/netreg.h>
#include <ofono/sim.h>
+#include <ofono/sms.h>
+#include <ofono/phonebook.h>
+#include <ofono/voicecall.h>
#include <ofono/gprs.h>
#include <ofono/gprs-context.h>
#include <ofono/log.h>
@@ -51,6 +54,7 @@
static const char *cfun_prefix[] = { "+CFUN:", NULL };
static const char *cpin_prefix[] = { "+CPIN:", NULL };
+static const char *qinistat_prefix[] = { "+QINISTAT:", NULL };
static const char *cgmm_prefix[] = { "UC15", "Quectel_M95", NULL };
static const char *none_prefix[] = { NULL };
@@ -69,8 +73,10 @@ struct quectel_data {
GAtChat *modem;
GAtChat *aux;
guint cpin_ready;
+ guint call_ready;
bool have_sim;
enum ofono_vendor vendor;
+ struct l_timeout *sms_ready_timer;
/* used by quectel uart driver */
GAtChat *uart;
@@ -334,6 +340,66 @@ static void cgmm_cb(int ok, GAtResult *result, void *user_data)
NULL);
}
+static void qinistat_cb(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("%p", modem);
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+QINISTAT:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &status))
+ return;
+
+ DBG("qinistat: %d", status);
+
+ if (status != 3) {
+ l_timeout_modify_ms(data->sms_ready_timer, 500);
+ return;
+ }
+
+ ofono_sms_create(modem, data->vendor, "atmodem", data->aux);
+ l_timeout_remove(data->sms_ready_timer);
+ data->sms_ready_timer = NULL;
+}
+
+static void sms_ready_cb(struct l_timeout *timeout, void *user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct quectel_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ g_at_chat_send(data->aux, "AT+QINISTAT", qinistat_prefix, qinistat_cb,
+ modem, NULL);
+}
+
+static void call_ready_notify(GAtResult *result, void *user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct quectel_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ g_at_chat_unregister(data->aux, data->call_ready);
+ data->call_ready = 0;
+ data->sms_ready_timer = l_timeout_create_ms(500, sms_ready_cb, modem,
+ NULL);
+ if (!data->sms_ready_timer) {
+ close_serial(modem);
+ return;
+ }
+
+ ofono_phonebook_create(modem, 0, "atmodem", data->aux);
+ ofono_voicecall_create(modem, 0, "atmodem", data->aux);
+}
+
static int open_ttys(struct ofono_modem *modem)
{
struct quectel_data *data = ofono_modem_get_data(modem);
@@ -353,6 +419,14 @@ static int open_ttys(struct ofono_modem *modem)
return -EIO;
}
+ data->call_ready = g_at_chat_register(data->aux, "Call Ready",
+ call_ready_notify, false,
+ modem, NULL);
+ if (!data->call_ready) {
+ close_serial(modem);
+ return -ENOTTY;
+ }
+
g_at_chat_set_slave(data->modem, data->aux);
g_at_chat_send(data->modem, "ATE0; &C0; +CMEE=1", none_prefix, NULL,