2012-06-22 20:20:11 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* oFono - Open Source Telephony
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011-2012 Intel Corporation. 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 <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <ofono/log.h>
|
|
|
|
#include <ofono/modem.h>
|
|
|
|
#include <ofono/sms.h>
|
|
|
|
|
|
|
|
#include "qmi.h"
|
|
|
|
#include "wms.h"
|
|
|
|
|
|
|
|
#include "qmimodem.h"
|
|
|
|
|
|
|
|
struct sms_data {
|
|
|
|
struct qmi_service *wms;
|
|
|
|
uint16_t major;
|
|
|
|
uint16_t minor;
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
struct qmi_wms_read_msg_id rd_msg_id;
|
|
|
|
struct qmi_wms_result_msg_list *msg_list;
|
|
|
|
uint32_t rd_msg_num;
|
|
|
|
uint8_t msg_mode;
|
|
|
|
bool msg_mode_all;
|
|
|
|
bool msg_list_chk;
|
2012-06-22 20:20:11 +00:00
|
|
|
};
|
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
static void get_msg_list(struct ofono_sms *sms);
|
|
|
|
static void raw_read(struct ofono_sms *sms, uint8_t type, uint32_t ndx);
|
|
|
|
|
2012-06-22 20:20:11 +00:00
|
|
|
static void get_smsc_addr_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct cb_data *cbd = user_data;
|
|
|
|
ofono_sms_sca_query_cb_t cb = cbd->cb;
|
|
|
|
struct ofono_phone_number sca;
|
|
|
|
const struct qmi_wms_result_smsc_addr *smsc;
|
|
|
|
uint16_t len;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, NULL)) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
smsc = qmi_result_get(result, QMI_WMS_RESULT_SMSC_ADDR, &len);
|
|
|
|
if (!smsc) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!smsc->addr_len) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (smsc->addr[0] == '+') {
|
|
|
|
strncpy(sca.number, smsc->addr + 1, smsc->addr_len - 1);
|
|
|
|
sca.number[smsc->addr_len - 1] = '\0';
|
|
|
|
sca.type = 145;
|
|
|
|
} else {
|
|
|
|
strncpy(sca.number, smsc->addr, smsc->addr_len);
|
|
|
|
sca.number[smsc->addr_len] = '\0';
|
|
|
|
sca.type = 129;
|
|
|
|
}
|
|
|
|
|
|
|
|
CALLBACK_WITH_SUCCESS(cb, &sca, cbd->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qmi_sca_query(struct ofono_sms *sms,
|
|
|
|
ofono_sms_sca_query_cb_t cb, void *user_data)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_GET_SMSC_ADDR, NULL,
|
|
|
|
get_smsc_addr_cb, cbd, g_free) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
|
|
|
|
|
|
|
|
g_free(cbd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_smsc_addr_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct cb_data *cbd = user_data;
|
|
|
|
ofono_sms_sca_set_cb_t cb = cbd->cb;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, NULL)) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qmi_sca_set(struct ofono_sms *sms,
|
|
|
|
const struct ofono_phone_number *sca,
|
|
|
|
ofono_sms_sca_set_cb_t cb, void *user_data)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
|
|
char type[4], number[OFONO_MAX_PHONE_NUMBER_LENGTH + 2];
|
|
|
|
struct qmi_param *param;
|
|
|
|
|
|
|
|
DBG("type %d name %s", sca->type, sca->number);
|
|
|
|
|
|
|
|
switch (sca->type) {
|
|
|
|
case 129:
|
|
|
|
snprintf(number, sizeof(number), "%s", sca->number);
|
|
|
|
break;
|
|
|
|
case 145:
|
|
|
|
snprintf(number, sizeof(number), "+%s", sca->number);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf(type, sizeof(type), "%d", sca->type);
|
|
|
|
|
|
|
|
param = qmi_param_new();
|
|
|
|
if (!param)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
qmi_param_append(param, QMI_WMS_PARAM_SMSC_ADDR,
|
|
|
|
strlen(number), number);
|
|
|
|
qmi_param_append(param, QMI_WMS_PARAM_SMSC_ADDR_TYPE,
|
|
|
|
strlen(type), type);
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_SET_SMSC_ADDR, param,
|
|
|
|
set_smsc_addr_cb, cbd, g_free) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
qmi_param_free(param);
|
|
|
|
|
|
|
|
error:
|
|
|
|
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
|
|
|
|
|
|
g_free(cbd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void raw_send_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct cb_data *cbd = user_data;
|
|
|
|
ofono_sms_submit_cb_t cb = cbd->cb;
|
|
|
|
uint16_t msgid;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, NULL)) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!qmi_result_get_uint16(result, QMI_WMS_RESULT_MESSAGE_ID, &msgid)) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CALLBACK_WITH_SUCCESS(cb, msgid, cbd->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qmi_submit(struct ofono_sms *sms,
|
|
|
|
const unsigned char *pdu, int pdu_len, int tpdu_len,
|
|
|
|
int mms, ofono_sms_submit_cb_t cb, void *user_data)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
|
|
struct qmi_wms_param_message *message;
|
|
|
|
struct qmi_param *param;
|
|
|
|
|
|
|
|
DBG("pdu_len %d tpdu_len %d mms %d", pdu_len, tpdu_len, mms);
|
|
|
|
|
|
|
|
message = alloca(3 + pdu_len);
|
|
|
|
|
|
|
|
message->msg_format = 0x06;
|
|
|
|
message->msg_length = GUINT16_TO_LE(pdu_len);
|
|
|
|
memcpy(message->msg_data, pdu, pdu_len);
|
|
|
|
|
|
|
|
param = qmi_param_new();
|
|
|
|
if (!param)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
qmi_param_append(param, QMI_WMS_PARAM_MESSAGE, 3 + pdu_len, message);
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_RAW_SEND, param,
|
|
|
|
raw_send_cb, cbd, g_free) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
qmi_param_free(param);
|
|
|
|
|
|
|
|
error:
|
|
|
|
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
|
|
|
|
|
|
g_free(cbd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int domain_to_bearer(uint8_t domain)
|
|
|
|
{
|
|
|
|
switch (domain) {
|
|
|
|
case QMI_WMS_DOMAIN_CS_PREFERRED:
|
|
|
|
return 3;
|
|
|
|
case QMI_WMS_DOMAIN_PS_PREFERRED:
|
|
|
|
return 2;
|
|
|
|
case QMI_WMS_DOMAIN_CS_ONLY:
|
|
|
|
return 1;
|
|
|
|
case QMI_WMS_DOMAIN_PS_ONLY:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t bearer_to_domain(int bearer)
|
|
|
|
{
|
|
|
|
switch (bearer) {
|
|
|
|
case 0:
|
|
|
|
return QMI_WMS_DOMAIN_PS_ONLY;
|
|
|
|
case 1:
|
|
|
|
return QMI_WMS_DOMAIN_CS_ONLY;
|
|
|
|
case 2:
|
|
|
|
return QMI_WMS_DOMAIN_PS_PREFERRED;
|
|
|
|
case 3:
|
|
|
|
return QMI_WMS_DOMAIN_CS_PREFERRED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QMI_WMS_DOMAIN_CS_PREFERRED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_domain_pref_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct cb_data *cbd = user_data;
|
|
|
|
ofono_sms_bearer_query_cb_t cb = cbd->cb;
|
|
|
|
uint8_t domain;
|
|
|
|
int bearer;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, NULL)) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!qmi_result_get_uint8(result, QMI_WMS_RESULT_DOMAIN, &domain)) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bearer = domain_to_bearer(domain);
|
|
|
|
|
|
|
|
CALLBACK_WITH_SUCCESS(cb, bearer, cbd->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qmi_bearer_query(struct ofono_sms *sms,
|
|
|
|
ofono_sms_bearer_query_cb_t cb, void *user_data)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
2017-08-22 12:25:43 +00:00
|
|
|
if (data->major < 1 || (data->major == 1 && data->minor < 2))
|
2012-06-22 20:20:11 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_GET_DOMAIN_PREF, NULL,
|
|
|
|
get_domain_pref_cb, cbd, g_free) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
|
|
|
|
|
|
|
|
g_free(cbd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_domain_pref_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct cb_data *cbd = user_data;
|
|
|
|
ofono_sms_bearer_set_cb_t cb = cbd->cb;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, NULL)) {
|
|
|
|
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qmi_bearer_set(struct ofono_sms *sms, int bearer,
|
|
|
|
ofono_sms_bearer_set_cb_t cb, void *user_data)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct cb_data *cbd = cb_data_new(cb, user_data);
|
|
|
|
struct qmi_param *param;
|
|
|
|
uint8_t domain;
|
|
|
|
|
|
|
|
DBG("bearer %d", bearer);
|
|
|
|
|
2017-08-22 12:25:43 +00:00
|
|
|
if (data->major < 1 || (data->major == 1 && data->minor < 2))
|
2012-06-22 20:20:11 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
domain = bearer_to_domain(bearer);
|
|
|
|
|
|
|
|
param = qmi_param_new_uint8(QMI_WMS_PARAM_DOMAIN, domain);
|
|
|
|
if (!param)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_SET_DOMAIN_PREF, param,
|
|
|
|
set_domain_pref_cb, cbd, g_free) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
|
|
|
|
|
|
|
g_free(cbd);
|
|
|
|
}
|
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
static void delete_msg_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
uint16_t err;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, &err))
|
|
|
|
DBG("Err: delete %d - %s", err, qmi_result_get_error(result));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Continue processing msg list. If error occurred, something
|
|
|
|
* serious happened, then don't bother.
|
|
|
|
*/
|
|
|
|
if (data->msg_list && data->msg_list_chk) {
|
|
|
|
uint32_t msg = ++data->rd_msg_num;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get another msg. If list is empty check for more. Once query
|
|
|
|
* returns empty, rely on event indication to get new msgs.
|
|
|
|
*/
|
|
|
|
if (msg < data->msg_list->cnt)
|
|
|
|
raw_read(sms, data->msg_list->msg[msg].type,
|
|
|
|
GUINT32_FROM_LE(data->msg_list->msg[msg].ndx));
|
|
|
|
else
|
|
|
|
get_msg_list(sms);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void delete_msg(struct ofono_sms *sms, uint8_t tag)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct qmi_param *param;
|
|
|
|
qmi_result_func_t func = NULL;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
param = qmi_param_new();
|
|
|
|
if (param == NULL)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_DEL_STORE,
|
|
|
|
QMI_WMS_STORAGE_TYPE_NV);
|
|
|
|
|
|
|
|
if (tag == QMI_WMS_MT_UNDEFINE) {
|
|
|
|
DBG("delete read msg type %d ndx %d", data->rd_msg_id.type,
|
|
|
|
data->rd_msg_id.ndx);
|
|
|
|
|
|
|
|
/* delete 1 msg */
|
|
|
|
qmi_param_append_uint32(param, QMI_WMS_PARAM_DEL_NDX,
|
|
|
|
data->rd_msg_id.ndx);
|
|
|
|
func = delete_msg_cb;
|
|
|
|
} else {
|
|
|
|
DBG("delete msg tag %d mode %d", tag, data->msg_mode);
|
|
|
|
|
|
|
|
/* delete all msgs from 1 tag type */
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_DEL_TYPE, tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_DEL_MODE, data->msg_mode);
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_DELETE, param,
|
|
|
|
func, sms, NULL) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
qmi_param_free(param);
|
|
|
|
|
|
|
|
done:
|
|
|
|
data->msg_list_chk = false;
|
|
|
|
}
|
|
|
|
|
2017-10-16 12:20:48 +00:00
|
|
|
static void raw_read_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
const struct qmi_wms_raw_message *msg;
|
|
|
|
uint16_t err;
|
2017-10-16 12:20:48 +00:00
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, &err)) {
|
|
|
|
DBG("Err: read %d - %s", err, qmi_result_get_error(result));
|
|
|
|
data->msg_list_chk = false;
|
2017-10-16 12:20:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Raw message data */
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
msg = qmi_result_get(result, QMI_WMS_RESULT_READ_MSG, NULL);
|
2017-10-16 12:20:48 +00:00
|
|
|
if (msg) {
|
|
|
|
uint16_t plen;
|
|
|
|
uint16_t tpdu_len;
|
|
|
|
|
|
|
|
plen = GUINT16_FROM_LE(msg->msg_length);
|
|
|
|
tpdu_len = plen - msg->msg_data[0] - 1;
|
|
|
|
|
|
|
|
ofono_sms_deliver_notify(sms, msg->msg_data, plen, tpdu_len);
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
} else
|
|
|
|
DBG("Err: no data in type %d ndx %d", data->rd_msg_id.type,
|
|
|
|
data->rd_msg_id.ndx);
|
|
|
|
|
|
|
|
/* delete read msg */
|
|
|
|
delete_msg(sms, QMI_WMS_MT_UNDEFINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void raw_read(struct ofono_sms *sms, uint8_t type, uint32_t ndx)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct qmi_param *param;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
param = qmi_param_new();
|
|
|
|
if (param == NULL)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
data->rd_msg_id.type = type;
|
|
|
|
data->rd_msg_id.ndx = ndx;
|
|
|
|
|
|
|
|
DBG("read type %d ndx %d", data->rd_msg_id.type, data->rd_msg_id.ndx);
|
|
|
|
|
|
|
|
qmi_param_append(param, QMI_WMS_PARAM_READ_MSG,
|
|
|
|
sizeof(data->rd_msg_id), &data->rd_msg_id);
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_READ_MODE, data->msg_mode);
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_RAW_READ, param,
|
|
|
|
raw_read_cb, sms, NULL) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
qmi_param_free(param);
|
|
|
|
|
|
|
|
done:
|
|
|
|
data->msg_list_chk = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_msg_list_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
const struct qmi_wms_result_msg_list *list;
|
|
|
|
uint32_t cnt = 0;
|
|
|
|
uint16_t tmp;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, &tmp)) {
|
|
|
|
DBG("Err: get msg list mode=%d %d=%s", data->msg_mode, tmp,
|
|
|
|
qmi_result_get_error(result));
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
list = qmi_result_get(result, QMI_WMS_RESULT_MSG_LIST, NULL);
|
|
|
|
if (list == NULL) {
|
|
|
|
DBG("Err: get msg list empty");
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
cnt = GUINT32_FROM_LE(list->cnt);
|
|
|
|
DBG("msgs found %d", cnt);
|
|
|
|
|
|
|
|
for (tmp = 0; tmp < cnt; tmp++) {
|
|
|
|
DBG("unread type %d ndx %d", list->msg[tmp].type,
|
|
|
|
GUINT32_FROM_LE(list->msg[tmp].ndx));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free list from last time */
|
|
|
|
if (data->msg_list) {
|
|
|
|
g_free(data->msg_list);
|
|
|
|
data->msg_list = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* save list and get 1st msg */
|
|
|
|
if (cnt) {
|
|
|
|
int msg_size = cnt * sizeof(list->msg[0]);
|
|
|
|
|
|
|
|
data->msg_list = g_try_malloc0(sizeof(list->cnt) + msg_size);
|
|
|
|
if (data->msg_list == NULL)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
data->msg_list->cnt = cnt;
|
|
|
|
memcpy(data->msg_list->msg, list->msg, msg_size);
|
|
|
|
|
|
|
|
data->rd_msg_num = 0;
|
|
|
|
raw_read(sms, data->msg_list->msg[0].type,
|
|
|
|
GUINT32_FROM_LE(data->msg_list->msg[0].ndx));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
data->msg_list_chk = false;
|
|
|
|
|
|
|
|
/* if both protocols supported, check the other */
|
|
|
|
if (data->msg_mode_all) {
|
|
|
|
data->msg_mode_all = false;
|
|
|
|
data->msg_mode = QMI_WMS_MESSAGE_MODE_GSMWCDMA;
|
|
|
|
get_msg_list(sms);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_msg_list(struct ofono_sms *sms)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct qmi_param *param;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
param = qmi_param_new();
|
|
|
|
if (param == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
data->msg_list_chk = true;
|
|
|
|
|
|
|
|
/* query NOT_READ msg list */
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_STORAGE_TYPE,
|
|
|
|
QMI_WMS_STORAGE_TYPE_NV);
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_TAG_TYPE,
|
|
|
|
QMI_WMS_MT_NOT_READ);
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_MESSAGE_MODE,
|
|
|
|
data->msg_mode);
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_GET_MSG_LIST, param,
|
|
|
|
get_msg_list_cb, sms, NULL) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
data->msg_list_chk = false;
|
|
|
|
qmi_param_free(param);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_msg_protocol_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
uint16_t err;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, &err) &&
|
|
|
|
(err != QMI_ERR_OP_DEVICE_UNSUPPORTED)) {
|
|
|
|
DBG("Err: protocol %d - %s", err, qmi_result_get_error(result));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err != QMI_ERR_OP_DEVICE_UNSUPPORTED) {
|
|
|
|
/* modem supports only 1 protocol */
|
|
|
|
qmi_result_get_uint8(result, QMI_WMS_PARAM_PROTOCOL,
|
|
|
|
&data->msg_mode);
|
2017-10-16 12:20:48 +00:00
|
|
|
} else {
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
/* check both, start with 1 then switch to other */
|
|
|
|
DBG("device supports CDMA and WCDMA msg protocol");
|
|
|
|
data->msg_mode_all = true;
|
|
|
|
data->msg_mode = QMI_WMS_MESSAGE_MODE_CDMA;
|
2017-10-16 12:20:48 +00:00
|
|
|
}
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
|
|
|
|
/* check for messages */
|
|
|
|
get_msg_list(sms);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_msg_protocol(struct ofono_sms *sms)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
qmi_service_send(data->wms, QMI_WMS_GET_MSG_PROTOCOL, NULL,
|
|
|
|
get_msg_protocol_cb, sms, NULL);
|
2017-10-16 12:20:48 +00:00
|
|
|
}
|
|
|
|
|
2012-06-22 20:20:11 +00:00
|
|
|
static void event_notify(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
2017-10-16 12:20:48 +00:00
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
2012-06-22 20:20:11 +00:00
|
|
|
const struct qmi_wms_result_new_msg_notify *notify;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
/*
|
|
|
|
* The 2 types of MT message TLVs are mutually exclusive, depending on
|
|
|
|
* how the route action is configured. If action is store and notify,
|
|
|
|
* then the MT message TLV is sent. If action is transfer only or
|
|
|
|
* transfer and ack, then the transfer route MT message TLV is sent.
|
|
|
|
*/
|
|
|
|
notify = qmi_result_get(result, QMI_WMS_RESULT_NEW_MSG_NOTIFY, NULL);
|
2012-06-22 20:20:11 +00:00
|
|
|
if (notify) {
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
/* route is store and notify */
|
|
|
|
if (!qmi_result_get_uint8(result, QMI_WMS_RESULT_MSG_MODE,
|
|
|
|
&data->msg_mode))
|
|
|
|
DBG("msg mode not found, use mode %d", data->msg_mode);
|
|
|
|
|
|
|
|
DBG("msg type %d ndx %d mode %d", notify->storage_type,
|
|
|
|
GUINT32_FROM_LE(notify->storage_index), data->msg_mode);
|
|
|
|
|
|
|
|
/* don't read if list is being processed, get this msg later */
|
|
|
|
if (!data->msg_list_chk)
|
|
|
|
raw_read(sms, notify->storage_type,
|
|
|
|
GUINT32_FROM_LE(notify->storage_index));
|
|
|
|
} else {
|
|
|
|
/* route is either transfer only or transfer and ACK */
|
|
|
|
const struct qmi_wms_result_message *message;
|
2012-06-22 20:20:11 +00:00
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
message = qmi_result_get(result, QMI_WMS_RESULT_MESSAGE, NULL);
|
|
|
|
if (message) {
|
|
|
|
uint16_t plen;
|
2012-06-22 20:20:11 +00:00
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
plen = GUINT16_FROM_LE(message->msg_length);
|
2012-06-22 20:20:11 +00:00
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
DBG("ack_required %d transaction id %u",
|
|
|
|
message->ack_required,
|
2012-06-22 20:20:11 +00:00
|
|
|
GUINT32_FROM_LE(message->transaction_id));
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
DBG("msg format %d PDU length %d",
|
|
|
|
message->msg_format, plen);
|
2012-06-22 20:20:11 +00:00
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
ofono_sms_deliver_notify(sms, message->msg_data,
|
|
|
|
plen, plen);
|
|
|
|
}
|
2012-06-22 20:20:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_routes_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
2012-06-22 20:20:11 +00:00
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
ofono_sms_register(sms);
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Modem storage is limited. As a fail safe, delete processed messages
|
|
|
|
* to free device memory to prevent blockage of new messages.
|
|
|
|
*/
|
|
|
|
data->msg_mode = QMI_WMS_MESSAGE_MODE_CDMA;
|
|
|
|
delete_msg(sms, QMI_WMS_MT_READ);
|
|
|
|
delete_msg(sms, QMI_WMS_MO_SENT);
|
|
|
|
data->msg_mode = QMI_WMS_MESSAGE_MODE_GSMWCDMA;
|
|
|
|
delete_msg(sms, QMI_WMS_MT_READ);
|
|
|
|
delete_msg(sms, QMI_WMS_MO_SENT);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Subsystem initialized, now start process to check for unread
|
|
|
|
* messages. First, query msg protocol/mode. If modem supports both
|
|
|
|
* modes, then check messages for both modes since there's no way to
|
|
|
|
* query which mode is active.
|
|
|
|
*/
|
|
|
|
get_msg_protocol(sms);
|
2012-06-22 20:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void get_routes_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
const struct qmi_wms_route_list *list;
|
|
|
|
struct qmi_wms_route_list *new_list;
|
|
|
|
struct qmi_param *param;
|
|
|
|
uint16_t len, num, i;
|
|
|
|
uint8_t value;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_result_set_error(result, NULL))
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
list = qmi_result_get(result, QMI_WMS_RESULT_ROUTE_LIST, &len);
|
|
|
|
if (!list)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
num = GUINT16_FROM_LE(list->count);
|
|
|
|
|
|
|
|
DBG("found %d routes", num);
|
|
|
|
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
DBG("type %d class %d => type %d value %d",
|
|
|
|
list->route[i].msg_type,
|
|
|
|
list->route[i].msg_class,
|
|
|
|
list->route[i].storage_type,
|
|
|
|
list->route[i].action);
|
|
|
|
|
|
|
|
if (qmi_result_get_uint8(result, QMI_WMS_RESULT_STATUS_REPORT, &value))
|
|
|
|
DBG("transfer status report %d", value);
|
|
|
|
|
|
|
|
len = 2 + (1 * 4);
|
|
|
|
new_list = alloca(len);
|
|
|
|
|
|
|
|
new_list->count = GUINT16_TO_LE(1);
|
|
|
|
new_list->route[0].msg_type = QMI_WMS_MSG_TYPE_P2P;
|
|
|
|
new_list->route[0].msg_class = QMI_WMS_MSG_CLASS_NONE;
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
new_list->route[0].storage_type = QMI_WMS_STORAGE_TYPE_NV;
|
|
|
|
new_list->route[0].action = QMI_WMS_ACTION_STORE_AND_NOTIFY;
|
2012-06-22 20:20:11 +00:00
|
|
|
|
|
|
|
param = qmi_param_new();
|
|
|
|
if (!param)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
qmi_param_append(param, QMI_WMS_PARAM_ROUTE_LIST, len, new_list);
|
|
|
|
qmi_param_append_uint8(param, QMI_WMS_PARAM_STATUS_REPORT, 0x01);
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_SET_ROUTES, param,
|
|
|
|
set_routes_cb, sms, NULL) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
qmi_param_free(param);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ofono_sms_register(sms);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_event_cb(struct qmi_result *result, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_GET_ROUTES, NULL,
|
|
|
|
get_routes_cb, sms, NULL) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ofono_sms_register(sms);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void create_wms_cb(struct qmi_service *service, void *user_data)
|
|
|
|
{
|
|
|
|
struct ofono_sms *sms = user_data;
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
struct qmi_param *param;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
if (!service) {
|
|
|
|
ofono_error("Failed to request WMS service");
|
|
|
|
ofono_sms_remove(sms);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!qmi_service_get_version(service, &data->major, &data->minor)) {
|
|
|
|
ofono_error("Failed to get WMS service version");
|
|
|
|
ofono_sms_remove(sms);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
data->wms = qmi_service_ref(service);
|
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
memset(&data->rd_msg_id, 0, sizeof(data->rd_msg_id));
|
|
|
|
data->msg_mode = QMI_WMS_MESSAGE_MODE_GSMWCDMA;
|
|
|
|
|
2012-06-22 20:20:11 +00:00
|
|
|
qmi_service_register(data->wms, QMI_WMS_EVENT,
|
|
|
|
event_notify, sms, NULL);
|
|
|
|
|
|
|
|
param = qmi_param_new_uint8(QMI_WMS_PARAM_NEW_MSG_REPORT, 0x01);
|
|
|
|
if (!param)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (qmi_service_send(data->wms, QMI_WMS_SET_EVENT, param,
|
|
|
|
set_event_cb, sms, NULL) > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
done:
|
|
|
|
ofono_sms_register(sms);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int qmi_sms_probe(struct ofono_sms *sms,
|
|
|
|
unsigned int vendor, void *user_data)
|
|
|
|
{
|
|
|
|
struct qmi_device *device = user_data;
|
|
|
|
struct sms_data *data;
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
data = g_new0(struct sms_data, 1);
|
|
|
|
|
|
|
|
ofono_sms_set_data(sms, data);
|
|
|
|
|
|
|
|
qmi_service_create(device, QMI_SERVICE_WMS, create_wms_cb, sms, NULL);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qmi_sms_remove(struct ofono_sms *sms)
|
|
|
|
{
|
|
|
|
struct sms_data *data = ofono_sms_get_data(sms);
|
|
|
|
|
|
|
|
DBG("");
|
|
|
|
|
|
|
|
ofono_sms_set_data(sms, NULL);
|
|
|
|
|
|
|
|
qmi_service_unregister_all(data->wms);
|
|
|
|
|
|
|
|
qmi_service_unref(data->wms);
|
|
|
|
|
qmimodem: change msg class none to store/notify
Change message class none configuration from directly delivering a new
message in the event indication to storing it in the modem's NV then
sending an event indication identifying the new message. Also, add
checking for stored, unread messages at boot up.
This fixes a scenario where the modem powers on, automatically
connects to the network, receives a message, and sends an indication
before oFono has fully initialized. Now, the message is saved and
retrieved after initialization.
This also helps with suspend/resume on platforms where the modem,
supports waking the host CPU upon SMS reception. And, the platform
design limitation is that the modem's interfaces (eg, cdc-wdm, wwan,
etc) disconnect on suspend and reconnect on resume. This causes oFono
to re-initialize and miss the message indication because it was sent
before oFono is ready. Now, the wake up message is saved and retrieved
after initialization.
2019-06-05 16:26:23 +00:00
|
|
|
if (data->msg_list)
|
|
|
|
g_free(data->msg_list);
|
|
|
|
|
2012-06-22 20:20:11 +00:00
|
|
|
g_free(data);
|
|
|
|
}
|
|
|
|
|
2018-10-17 13:36:10 +00:00
|
|
|
static const struct ofono_sms_driver driver = {
|
2012-06-22 20:20:11 +00:00
|
|
|
.name = "qmimodem",
|
|
|
|
.probe = qmi_sms_probe,
|
|
|
|
.remove = qmi_sms_remove,
|
|
|
|
.sca_query = qmi_sca_query,
|
|
|
|
.sca_set = qmi_sca_set,
|
|
|
|
.submit = qmi_submit,
|
|
|
|
.bearer_query = qmi_bearer_query,
|
|
|
|
.bearer_set = qmi_bearer_set,
|
|
|
|
};
|
|
|
|
|
|
|
|
void qmi_sms_init(void)
|
|
|
|
{
|
|
|
|
ofono_sms_driver_register(&driver);
|
|
|
|
}
|
|
|
|
|
|
|
|
void qmi_sms_exit(void)
|
|
|
|
{
|
|
|
|
ofono_sms_driver_unregister(&driver);
|
|
|
|
}
|