Read messages left over in ME storage on startup.

On modems that don't support +CMT (or for class 2 SMSes) the messages are
stored in the modem and then read and deleted from there in two separate
steps with no warranty that deletion succeeds or (more likely) power is
cut before the deletion happens.  Over time the memory may become full
and if we don't want to deal with this condition we need to check on
startup if there are messages we haven't deleted.

We can't differentiate between those messages and those the user already
had on the SIM / modem before installing ofono or switching phones, so we
might want to deliver messages with REC READ status with some kind of
indication that these are potentially old so the UI doesn't emit spurious
alerts.  We don't do this now and just deliver as usual.
This commit is contained in:
Andrzej Zaborowski 2009-09-04 16:48:03 +02:00 committed by Denis Kenzior
parent b2bde46bfb
commit 36d0c8451f
1 changed files with 125 additions and 0 deletions

View File

@ -48,10 +48,12 @@ static const char *cmgf_prefix[] = { "+CMGF:", NULL };
static const char *cpms_prefix[] = { "+CPMS:", NULL };
static const char *cnmi_prefix[] = { "+CNMI:", NULL };
static const char *cmgs_prefix[] = { "+CMGS:", NULL };
static const char *cmgl_prefix[] = { "+CMGL:", NULL };
static const char *none_prefix[] = { NULL };
static gboolean set_cmgf(gpointer user_data);
static gboolean set_cpms(gpointer user_data);
static void at_cmgl_set_cpms(struct ofono_sms *sms, int store);
#define MAX_CMGF_RETRIES 10
#define MAX_CPMS_RETRIES 10
@ -499,6 +501,123 @@ err:
ofono_error("Unable to parse CMTI notification");
}
static void at_cmgl_done(struct ofono_sms *sms)
{
struct sms_data *data = ofono_sms_get_data(sms);
if (data->incoming == MT_STORE && data->store == ME_STORE)
at_cmgl_set_cpms(sms, SM_STORE);
}
static void at_cmgl_notify(GAtResult *result, gpointer user_data)
{
struct ofono_sms *sms = user_data;
struct sms_data *data = ofono_sms_get_data(sms);
GAtResultIter iter;
const char *hexpdu;
unsigned char pdu[164];
long pdu_len;
int tpdu_len;
int index;
int status;
char buf[16];
dump_response("at_cmgl_notify", TRUE, result);
g_at_result_iter_init(&iter, result);
while (g_at_result_iter_next(&iter, "+CMGL:")) {
if (!g_at_result_iter_next_number(&iter, &index))
goto err;
if (!g_at_result_iter_next_number(&iter, &status))
goto err;
if (!g_at_result_iter_skip_next(&iter))
goto err;
if (!g_at_result_iter_next_number(&iter, &tpdu_len))
goto err;
/* Only MT messages */
if (status != 0 && status != 1)
continue;
hexpdu = g_at_result_pdu(result);
ofono_debug("Found an old SMS PDU: %s, with len: %d",
hexpdu, tpdu_len);
decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu);
ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len);
/* We don't buffer SMS on the SIM/ME, send along a CMGD */
sprintf(buf, "AT+CMGD=%d", index);
g_at_chat_send(data->chat, buf, none_prefix,
at_cmgd_cb, NULL, NULL);
}
return;
err:
ofono_error("Unable to parse CMGL response");
}
static void at_cmgl_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_sms *sms = user_data;
if (!ok)
ofono_error("Initial listing SMS storage failed!");
at_cmgl_done(sms);
}
static void at_cmgl_cpms_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cpms_request *req = user_data;
struct ofono_sms *sms = req->sms;
struct sms_data *data = ofono_sms_get_data(sms);
if (!ok) {
ofono_error("Initial CPMS request failed");
at_cmgl_done(sms);
return;
}
data->store = req->store;
g_at_chat_send_pdu_listing(data->chat, "AT+CMGL=4", cmgl_prefix,
at_cmgl_notify, at_cmgl_cb, sms, NULL);
}
static void at_cmgl_set_cpms(struct ofono_sms *sms, int store)
{
struct sms_data *data = ofono_sms_get_data(sms);
if (store == data->store) {
struct cpms_request req;
req.sms = sms;
req.store = store;
at_cmgl_cpms_cb(TRUE, NULL, &req);
} else {
char buf[128];
const char *readwrite = storages[store];
const char *incoming = storages[data->incoming];
struct cpms_request *req = g_new(struct cpms_request, 1);
req->sms = sms;
req->store = store;
sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"",
readwrite, readwrite, incoming);
g_at_chat_send(data->chat, buf, cpms_prefix, at_cmgl_cpms_cb,
req, g_free);
}
}
static void at_sms_initialized(struct ofono_sms *sms)
{
struct sms_data *data = ofono_sms_get_data(sms);
@ -516,6 +635,12 @@ static void at_sms_initialized(struct ofono_sms *sms)
g_at_chat_register(data->chat, "+CMGR:", at_cmgr_notify, TRUE,
sms, NULL);
/* Inspect and free the incoming SMS storage */
if (data->incoming == MT_STORE)
at_cmgl_set_cpms(sms, ME_STORE);
else
at_cmgl_set_cpms(sms, data->incoming);
ofono_sms_register(sms);
}