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.
This commit is contained in:
Martin Hundebøll 2019-07-10 23:51:48 +02:00 committed by Denis Kenzior
parent ded2915fd5
commit 57b4aa3678
1 changed files with 74 additions and 0 deletions

View File

@ -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,