Port SMS AT modem driver to the new API

This commit is contained in:
Denis Kenzior 2009-08-17 22:42:17 -05:00
parent c4a349fdf9
commit 1c61fa3db4
3 changed files with 178 additions and 179 deletions

View File

@ -27,7 +27,6 @@ struct at_data {
struct netreg_data *netreg; struct netreg_data *netreg;
struct voicecall_data *voicecall; struct voicecall_data *voicecall;
struct sms_data *sms;
}; };
void decode_at_error(struct ofono_error *error, const char *final); void decode_at_error(struct ofono_error *error, const char *final);
@ -88,8 +87,8 @@ extern void at_call_barring_exit();
extern void at_sim_init(struct ofono_modem *modem); extern void at_sim_init(struct ofono_modem *modem);
extern void at_sim_exit(struct ofono_modem *modem); extern void at_sim_exit(struct ofono_modem *modem);
extern void at_sms_init(struct ofono_modem *modem); extern void at_sms_init();
extern void at_sms_exit(struct ofono_modem *modem); extern void at_sms_exit();
extern void at_phonebook_init(); extern void at_phonebook_init();
extern void at_phonebook_exit(); extern void at_phonebook_exit();

View File

@ -100,7 +100,6 @@ static void at_destroy(struct at_data *at)
static void interface_exit(struct at_data *at) static void interface_exit(struct at_data *at)
{ {
at_phonebook_exit(at->modem); at_phonebook_exit(at->modem);
at_sms_exit(at->modem);
at_network_registration_exit(at->modem); at_network_registration_exit(at->modem);
at_voicecall_exit(at->modem); at_voicecall_exit(at->modem);
at_sim_exit(at->modem); at_sim_exit(at->modem);
@ -368,7 +367,7 @@ static void create_cb(GIOChannel *io, gboolean success, gpointer user)
ofono_call_meter_create(at->modem, "generic_at", at->parser); ofono_call_meter_create(at->modem, "generic_at", at->parser);
ofono_call_barring_create(at->modem, "generic_at", at->parser); ofono_call_barring_create(at->modem, "generic_at", at->parser);
ofono_ssn_create(at->modem, "generic_at", at->parser); ofono_ssn_create(at->modem, "generic_at", at->parser);
at_sms_init(at->modem); ofono_sms_create(at->modem, "generic_at", at->parser);
ofono_phonebook_create(at->modem, "generic_at", at->parser); ofono_phonebook_create(at->modem, "generic_at", at->parser);
at->io = io; at->io = io;
@ -533,6 +532,7 @@ static int atmodem_init(void)
at_phonebook_init(); at_phonebook_init();
at_ssn_init(); at_ssn_init();
at_ussd_init(); at_ussd_init();
at_sms_init();
manager_init(conn); manager_init(conn);
@ -545,6 +545,7 @@ static void atmodem_exit(void)
manager_exit(conn); manager_exit(conn);
at_sms_exit();
at_ussd_exit(); at_ussd_exit();
at_ssn_exit(); at_ssn_exit();
at_phonebook_exit(); at_phonebook_exit();

View File

@ -32,7 +32,7 @@
#include <ofono/log.h> #include <ofono/log.h>
#include <ofono/modem.h> #include <ofono/modem.h>
#include "driver.h" #include <ofono/sms.h>
#include "smsutil.h" #include "smsutil.h"
#include "util.h" #include "util.h"
@ -72,31 +72,19 @@ struct sms_data {
gboolean cnma_enabled; gboolean cnma_enabled;
char *cnma_ack_pdu; char *cnma_ack_pdu;
int cnma_ack_pdu_len; int cnma_ack_pdu_len;
GAtChat *chat;
}; };
struct cpms_request { struct cpms_request {
struct ofono_modem *modem; struct ofono_sms *sms;
int store; int store;
int index; int index;
}; };
static struct sms_data *sms_create()
{
return g_try_new0(struct sms_data, 1);
}
static void sms_destroy(struct sms_data *data)
{
if (data->cnma_ack_pdu)
g_free(data->cnma_ack_pdu);
g_free(data);
}
static void at_csca_set_cb(gboolean ok, GAtResult *result, gpointer user_data) static void at_csca_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
struct cb_data *cbd = user_data; struct cb_data *cbd = user_data;
ofono_generic_cb_t cb = cbd->cb; ofono_sms_sca_set_cb_t cb = cbd->cb;
struct ofono_error error; struct ofono_error error;
dump_response("csca_set_cb", ok, result); dump_response("csca_set_cb", ok, result);
@ -105,12 +93,12 @@ static void at_csca_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
cb(&error, cbd->data); cb(&error, cbd->data);
} }
static void at_csca_set(struct ofono_modem *modem, static void at_csca_set(struct ofono_sms *sms,
const struct ofono_phone_number *sca, const struct ofono_phone_number *sca,
ofono_generic_cb_t cb, void *data) ofono_sms_sca_set_cb_t cb, void *user_data)
{ {
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
struct cb_data *cbd = cb_data_new(modem, cb, data); struct cb_data *cbd = cb_data_new(NULL, cb, user_data);
char buf[64]; char buf[64];
if (!cbd) if (!cbd)
@ -118,7 +106,7 @@ static void at_csca_set(struct ofono_modem *modem,
sprintf(buf, "AT+CSCA=\"%s\",%d", sca->number, sca->type); sprintf(buf, "AT+CSCA=\"%s\",%d", sca->number, sca->type);
if (g_at_chat_send(at->parser, buf, csca_prefix, if (g_at_chat_send(data->chat, buf, csca_prefix,
at_csca_set_cb, cbd, g_free) > 0) at_csca_set_cb, cbd, g_free) > 0)
return; return;
@ -128,7 +116,7 @@ error:
{ {
DECLARE_FAILURE(error); DECLARE_FAILURE(error);
cb(&error, data); cb(&error, user_data);
} }
} }
@ -136,7 +124,7 @@ static void at_csca_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
struct cb_data *cbd = user_data; struct cb_data *cbd = user_data;
GAtResultIter iter; GAtResultIter iter;
ofono_sca_query_cb_t cb = cbd->cb; ofono_sms_sca_query_cb_t cb = cbd->cb;
struct ofono_error error; struct ofono_error error;
struct ofono_phone_number sca; struct ofono_phone_number sca;
const char *number; const char *number;
@ -181,16 +169,16 @@ err:
} }
} }
static void at_csca_query(struct ofono_modem *modem, ofono_sca_query_cb_t cb, static void at_csca_query(struct ofono_sms *sms, ofono_sms_sca_query_cb_t cb,
void *data) void *user_data)
{ {
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
struct cb_data *cbd = cb_data_new(modem, cb, data); struct cb_data *cbd = cb_data_new(NULL, cb, user_data);
if (!cbd) if (!cbd)
goto error; goto error;
if (g_at_chat_send(at->parser, "AT+CSCA?", csca_prefix, if (g_at_chat_send(data->chat, "AT+CSCA?", csca_prefix,
at_csca_query_cb, cbd, g_free) > 0) at_csca_query_cb, cbd, g_free) > 0)
return; return;
@ -200,7 +188,7 @@ error:
{ {
DECLARE_FAILURE(error); DECLARE_FAILURE(error);
cb(&error, NULL, data); cb(&error, NULL, user_data);
} }
} }
@ -240,12 +228,12 @@ err:
} }
} }
static void at_cmgs(struct ofono_modem *modem, unsigned char *pdu, int pdu_len, static void at_cmgs(struct ofono_sms *sms, unsigned char *pdu, int pdu_len,
int tpdu_len, int mms, ofono_sms_submit_cb_t cb, int tpdu_len, int mms, ofono_sms_submit_cb_t cb,
void *data) void *user_data)
{ {
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
struct cb_data *cbd = cb_data_new(modem, cb, data); struct cb_data *cbd = cb_data_new(NULL, cb, user_data);
char buf[512]; char buf[512];
int len; int len;
@ -254,14 +242,14 @@ static void at_cmgs(struct ofono_modem *modem, unsigned char *pdu, int pdu_len,
if (mms) { if (mms) {
sprintf(buf, "AT+CMMS=%d", mms); sprintf(buf, "AT+CMMS=%d", mms);
g_at_chat_send(at->parser, buf, none_prefix, g_at_chat_send(data->chat, buf, none_prefix,
NULL, NULL, NULL); NULL, NULL, NULL);
} }
len = sprintf(buf, "AT+CMGS=%d\r", tpdu_len); len = sprintf(buf, "AT+CMGS=%d\r", tpdu_len);
encode_hex_own_buf(pdu, pdu_len, 0, buf+len); encode_hex_own_buf(pdu, pdu_len, 0, buf+len);
if (g_at_chat_send(at->parser, buf, cmgs_prefix, if (g_at_chat_send(data->chat, buf, cmgs_prefix,
at_cmgs_cb, cbd, g_free) > 0) at_cmgs_cb, cbd, g_free) > 0)
return; return;
@ -271,16 +259,10 @@ error:
{ {
DECLARE_FAILURE(error); DECLARE_FAILURE(error);
cb(&error, -1, data); cb(&error, -1, user_data);
} }
} }
static struct ofono_sms_ops ops = {
.sca_query = at_csca_query,
.sca_set = at_csca_set,
.submit = at_cmgs,
};
static void at_cnma_cb(gboolean ok, GAtResult *result, gpointer user_data) static void at_cnma_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
if (!ok) if (!ok)
@ -326,8 +308,8 @@ static void at_cbm_notify(GAtResult *result, gpointer user_data)
static void at_cds_notify(GAtResult *result, gpointer user_data) static void at_cds_notify(GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
int pdulen; int pdulen;
const char *pdu; const char *pdu;
char buf[256]; char buf[256];
@ -342,19 +324,19 @@ static void at_cds_notify(GAtResult *result, gpointer user_data)
ofono_debug("Got new Status-Report PDU via CDS: %s, %d", pdu, pdulen); ofono_debug("Got new Status-Report PDU via CDS: %s, %d", pdu, pdulen);
/* We must acknowledge the PDU using CNMA */ /* We must acknowledge the PDU using CNMA */
if (at->sms->cnma_ack_pdu) if (data->cnma_ack_pdu)
sprintf(buf, "AT+CNMA=1,%d\r%s", at->sms->cnma_ack_pdu_len, sprintf(buf, "AT+CNMA=1,%d\r%s", data->cnma_ack_pdu_len,
at->sms->cnma_ack_pdu); data->cnma_ack_pdu);
else else
sprintf(buf, "AT+CNMA=0"); /* Should be a safe fallback */ sprintf(buf, "AT+CNMA=0"); /* Should be a safe fallback */
g_at_chat_send(at->parser, buf, none_prefix, at_cnma_cb, NULL, NULL); g_at_chat_send(data->chat, buf, none_prefix, at_cnma_cb, NULL, NULL);
} }
static void at_cmt_notify(GAtResult *result, gpointer user_data) static void at_cmt_notify(GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
const char *hexpdu; const char *hexpdu;
long pdu_len; long pdu_len;
int tpdu_len; int tpdu_len;
@ -371,21 +353,21 @@ static void at_cmt_notify(GAtResult *result, gpointer user_data)
ofono_debug("Got new SMS Deliver PDU via CMT: %s, %d", hexpdu, tpdu_len); ofono_debug("Got new SMS Deliver PDU via CMT: %s, %d", hexpdu, tpdu_len);
decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu); decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu);
ofono_sms_deliver_notify(modem, pdu, pdu_len, tpdu_len); ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len);
/* We must acknowledge the PDU using CNMA */ /* We must acknowledge the PDU using CNMA */
if (at->sms->cnma_ack_pdu) if (data->cnma_ack_pdu)
sprintf(buf, "AT+CNMA=1,%d\r%s", at->sms->cnma_ack_pdu_len, sprintf(buf, "AT+CNMA=1,%d\r%s", data->cnma_ack_pdu_len,
at->sms->cnma_ack_pdu); data->cnma_ack_pdu);
else else
sprintf(buf, "AT+CNMA=0"); /* Should be a safe fallback */ sprintf(buf, "AT+CNMA=0"); /* Should be a safe fallback */
g_at_chat_send(at->parser, buf, none_prefix, at_cnma_cb, NULL, NULL); g_at_chat_send(data->chat, buf, none_prefix, at_cnma_cb, NULL, NULL);
} }
static void at_cmgr_notify(GAtResult *result, gpointer user_data) static void at_cmgr_notify(GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
GAtResultIter iter; GAtResultIter iter;
const char *hexpdu; const char *hexpdu;
unsigned char pdu[164]; unsigned char pdu[164];
@ -413,7 +395,7 @@ static void at_cmgr_notify(GAtResult *result, gpointer user_data)
ofono_debug("Got PDU: %s, with len: %d", hexpdu, tpdu_len); ofono_debug("Got PDU: %s, with len: %d", hexpdu, tpdu_len);
decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu); decode_hex_own_buf(hexpdu, -1, &pdu_len, 0, pdu);
ofono_sms_deliver_notify(modem, pdu, pdu_len, tpdu_len); ofono_sms_deliver_notify(sms, pdu, pdu_len, tpdu_len);
return; return;
err: err:
@ -435,8 +417,8 @@ static void at_cmgd_cb(gboolean ok, GAtResult *result, gpointer user_data)
static void at_cmti_cpms_cb(gboolean ok, GAtResult *result, gpointer user_data) static void at_cmti_cpms_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
struct cpms_request *req = user_data; struct cpms_request *req = user_data;
struct ofono_modem *modem = req->modem; struct ofono_sms *sms = req->sms;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
char buf[128]; char buf[128];
if (!ok) { if (!ok) {
@ -444,20 +426,20 @@ static void at_cmti_cpms_cb(gboolean ok, GAtResult *result, gpointer user_data)
return; return;
} }
at->sms->store = req->store; data->store = req->store;
sprintf(buf, "AT+CMGR=%d", req->index); sprintf(buf, "AT+CMGR=%d", req->index);
g_at_chat_send(at->parser, buf, none_prefix, at_cmgr_cb, modem, NULL); g_at_chat_send(data->chat, buf, none_prefix, at_cmgr_cb, NULL, NULL);
/* We don't buffer SMS on the SIM/ME, send along a CMGD as well */ /* We don't buffer SMS on the SIM/ME, send along a CMGD as well */
sprintf(buf, "AT+CMGD=%d", req->index); sprintf(buf, "AT+CMGD=%d", req->index);
g_at_chat_send(at->parser, buf, none_prefix, at_cmgd_cb, NULL, NULL); g_at_chat_send(data->chat, buf, none_prefix, at_cmgd_cb, NULL, NULL);
} }
static void at_cmti_notify(GAtResult *result, gpointer user_data) static void at_cmti_notify(GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
const char *strstore; const char *strstore;
int store; int store;
GAtResultIter iter; GAtResultIter iter;
@ -485,27 +467,27 @@ static void at_cmti_notify(GAtResult *result, gpointer user_data)
ofono_debug("Got a CMTI indication at %s, index: %d", strstore, index); ofono_debug("Got a CMTI indication at %s, index: %d", strstore, index);
if (store == at->sms->store) { if (store == data->store) {
struct cpms_request req; struct cpms_request req;
req.modem = modem; req.sms = sms;
req.store = store; req.store = store;
req.index = index; req.index = index;
at_cmti_cpms_cb(TRUE, NULL, &req); at_cmti_cpms_cb(TRUE, NULL, &req);
} else { } else {
char buf[128]; char buf[128];
const char *incoming = storages[at->sms->incoming]; const char *incoming = storages[data->incoming];
struct cpms_request *req = g_new(struct cpms_request, 1); struct cpms_request *req = g_new(struct cpms_request, 1);
req->modem = modem; req->sms = sms;
req->store = store; req->store = store;
req->index = index; req->index = index;
sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"", sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"",
strstore, strstore, incoming); strstore, strstore, incoming);
g_at_chat_send(at->parser, buf, cpms_prefix, at_cmti_cpms_cb, g_at_chat_send(data->chat, buf, cpms_prefix, at_cmti_cpms_cb,
req, g_free); req, g_free);
} }
@ -515,46 +497,42 @@ err:
ofono_error("Unable to parse CMTI notification"); ofono_error("Unable to parse CMTI notification");
} }
static void at_sms_initialized(struct ofono_modem *modem) static void at_sms_initialized(struct ofono_sms *sms)
{ {
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
g_at_chat_register(at->parser, "+CMTI:", at_cmti_notify, FALSE, g_at_chat_register(data->chat, "+CMTI:", at_cmti_notify, FALSE,
modem, NULL); sms, NULL);
g_at_chat_register(at->parser, "+CMT:", at_cmt_notify, TRUE, g_at_chat_register(data->chat, "+CMT:", at_cmt_notify, TRUE,
modem, NULL); sms, NULL);
g_at_chat_register(at->parser, "+CDS:", at_cds_notify, TRUE, g_at_chat_register(data->chat, "+CDS:", at_cds_notify, TRUE,
modem, NULL); sms, NULL);
g_at_chat_register(at->parser, "+CBM:", at_cbm_notify, TRUE, g_at_chat_register(data->chat, "+CBM:", at_cbm_notify, TRUE,
modem, NULL); sms, NULL);
/* We treat CMGR just like a notification */ /* We treat CMGR just like a notification */
g_at_chat_register(at->parser, "+CMGR:", at_cmgr_notify, TRUE, g_at_chat_register(data->chat, "+CMGR:", at_cmgr_notify, TRUE,
modem, NULL); sms, NULL);
ofono_sms_manager_register(modem, &ops); ofono_sms_register(sms);
} }
static void at_sms_not_supported(struct ofono_modem *modem) static void at_sms_not_supported(struct ofono_sms *sms)
{ {
struct at_data *at = ofono_modem_get_userdata(modem);
ofono_error("SMS not supported by this modem. If this is in error" ofono_error("SMS not supported by this modem. If this is in error"
" please submit patches to support this hardware"); " please submit patches to support this hardware");
if (at->sms) {
sms_destroy(at->sms); ofono_sms_remove(sms);
at->sms = NULL;
}
} }
static void at_cnmi_set_cb(gboolean ok, GAtResult *result, gpointer user_data) static void at_cnmi_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
if (!ok) if (!ok)
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
at_sms_initialized(modem); at_sms_initialized(sms);
} }
static inline char wanted_cnmi(int supported, const char *pref) static inline char wanted_cnmi(int supported, const char *pref)
@ -651,8 +629,8 @@ err:
static void at_cnmi_query_cb(gboolean ok, GAtResult *result, gpointer user_data) static void at_cnmi_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
GAtResultIter iter; GAtResultIter iter;
int cnmi_opts[5]; /* See 27.005 Section 3.4.1 */ int cnmi_opts[5]; /* See 27.005 Section 3.4.1 */
int opt; int opt;
@ -687,101 +665,101 @@ static void at_cnmi_query_cb(gboolean ok, GAtResult *result, gpointer user_data)
goto out; goto out;
} }
if (build_cnmi_string(buf, cnmi_opts, at->sms->cnma_enabled)) if (build_cnmi_string(buf, cnmi_opts, data->cnma_enabled))
supported = TRUE; supported = TRUE;
if (at->sms->cnma_enabled) if (data->cnma_enabled)
construct_ack_pdu(at->sms); construct_ack_pdu(data);
out: out:
if (!supported) if (!supported)
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
g_at_chat_send(at->parser, buf, cnmi_prefix, g_at_chat_send(data->chat, buf, cnmi_prefix,
at_cnmi_set_cb, modem, NULL); at_cnmi_set_cb, sms, NULL);
} }
static void at_query_cnmi(struct ofono_modem *modem) static void at_query_cnmi(struct ofono_sms *sms)
{ {
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
g_at_chat_send(at->parser, "AT+CNMI=?", cnmi_prefix, g_at_chat_send(data->chat, "AT+CNMI=?", cnmi_prefix,
at_cnmi_query_cb, modem, NULL); at_cnmi_query_cb, sms, NULL);
} }
static void at_cpms_set_cb(gboolean ok, GAtResult *result, gpointer user_data) static void at_cpms_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
dump_response("at_cpms_set_cb", ok, result); dump_response("at_cpms_set_cb", ok, result);
if (ok) if (ok)
return at_query_cnmi(modem); return at_query_cnmi(sms);
at->sms->retries += 1; data->retries += 1;
if (at->sms->retries == MAX_CPMS_RETRIES) { if (data->retries == MAX_CPMS_RETRIES) {
ofono_error("Unable to set preferred storage"); ofono_error("Unable to set preferred storage");
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
} }
g_timeout_add_seconds(1, set_cpms, modem); g_timeout_add_seconds(1, set_cpms, sms);
} }
static gboolean set_cpms(gpointer user_data) static gboolean set_cpms(gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
const char *store = storages[at->sms->store]; const char *store = storages[data->store];
const char *incoming = storages[at->sms->incoming]; const char *incoming = storages[data->incoming];
char buf[128]; char buf[128];
sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"", store, store, incoming); sprintf(buf, "AT+CPMS=\"%s\",\"%s\",\"%s\"", store, store, incoming);
g_at_chat_send(at->parser, buf, cpms_prefix, g_at_chat_send(data->chat, buf, cpms_prefix,
at_cpms_set_cb, modem, NULL); at_cpms_set_cb, sms, NULL);
return FALSE; return FALSE;
} }
static void at_cmgf_set_cb(gboolean ok, GAtResult *result, gpointer user_data) static void at_cmgf_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
dump_response("at_cmgf_set_cb", ok, result); dump_response("at_cmgf_set_cb", ok, result);
if (ok) { if (ok) {
at->sms->retries = 0; data->retries = 0;
set_cpms(modem); set_cpms(sms);
return; return;
} }
at->sms->retries += 1; data->retries += 1;
if (at->sms->retries == MAX_CMGF_RETRIES) { if (data->retries == MAX_CMGF_RETRIES) {
ofono_debug("Unable to enter PDU mode"); ofono_debug("Unable to enter PDU mode");
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
} }
g_timeout_add_seconds(1, set_cmgf, modem); g_timeout_add_seconds(1, set_cmgf, sms);
} }
static gboolean set_cmgf(gpointer user_data) static gboolean set_cmgf(gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
g_at_chat_send(at->parser, "AT+CMGF=0", cmgf_prefix, g_at_chat_send(data->chat, "AT+CMGF=0", cmgf_prefix,
at_cmgf_set_cb, modem, NULL); at_cmgf_set_cb, sms, NULL);
return FALSE; return FALSE;
} }
static void at_cpms_query_cb(gboolean ok, GAtResult *result, static void at_cpms_query_cb(gboolean ok, GAtResult *result,
gpointer user_data) gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
gboolean supported = FALSE; gboolean supported = FALSE;
dump_response("cpms_query_cb", ok, result); dump_response("cpms_query_cb", ok, result);
@ -825,12 +803,12 @@ static void at_cpms_query_cb(gboolean ok, GAtResult *result,
if (sm_supported[0] && sm_supported[1]) { if (sm_supported[0] && sm_supported[1]) {
supported = TRUE; supported = TRUE;
at->sms->store = SM_STORE; data->store = SM_STORE;
} }
if (me_supported[0] && me_supported[1]) { if (me_supported[0] && me_supported[1]) {
supported = TRUE; supported = TRUE;
at->sms->store = ME_STORE; data->store = ME_STORE;
} }
/* This seems to be a special case, where the modem will /* This seems to be a special case, where the modem will
@ -838,26 +816,26 @@ static void at_cpms_query_cb(gboolean ok, GAtResult *result,
* mem1 * mem1
*/ */
if (mt_supported[2] && (sm_supported[0] || me_supported[0])) if (mt_supported[2] && (sm_supported[0] || me_supported[0]))
at->sms->incoming = MT_STORE; data->incoming = MT_STORE;
if (sm_supported[2]) if (sm_supported[2])
at->sms->incoming = SM_STORE; data->incoming = SM_STORE;
if (me_supported[2]) if (me_supported[2])
at->sms->incoming = ME_STORE; data->incoming = ME_STORE;
} }
out: out:
if (!supported) if (!supported)
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
set_cmgf(modem); set_cmgf(sms);
} }
static void at_cmgf_query_cb(gboolean ok, GAtResult *result, static void at_cmgf_query_cb(gboolean ok, GAtResult *result,
gpointer user_data) gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
gboolean supported = FALSE; gboolean supported = FALSE;
dump_response("cmgf_query_cb", ok, result); dump_response("cmgf_query_cb", ok, result);
@ -882,17 +860,17 @@ static void at_cmgf_query_cb(gboolean ok, GAtResult *result,
out: out:
if (!supported) if (!supported)
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
g_at_chat_send(at->parser, "AT+CPMS=?", cpms_prefix, g_at_chat_send(data->chat, "AT+CPMS=?", cpms_prefix,
at_cpms_query_cb, modem, NULL); at_cpms_query_cb, sms, NULL);
} }
static void at_csms_status_cb(gboolean ok, GAtResult *result, static void at_csms_status_cb(gboolean ok, GAtResult *result,
gpointer user_data) gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
gboolean supported = FALSE; gboolean supported = FALSE;
dump_response("csms_status_cb", ok, result); dump_response("csms_status_cb", ok, result);
@ -918,7 +896,7 @@ static void at_csms_status_cb(gboolean ok, GAtResult *result,
goto out; goto out;
if (service == 1) if (service == 1)
at->sms->cnma_enabled = TRUE; data->cnma_enabled = TRUE;
if (mt == 1 && mo == 1) if (mt == 1 && mo == 1)
supported = TRUE; supported = TRUE;
@ -926,28 +904,28 @@ static void at_csms_status_cb(gboolean ok, GAtResult *result,
out: out:
if (!supported) if (!supported)
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
/* Now query supported text format */ /* Now query supported text format */
g_at_chat_send(at->parser, "AT+CMGF=?", cmgf_prefix, g_at_chat_send(data->chat, "AT+CMGF=?", cmgf_prefix,
at_cmgf_query_cb, modem, NULL); at_cmgf_query_cb, sms, NULL);
} }
static void at_csms_set_cb(gboolean ok, GAtResult *result, static void at_csms_set_cb(gboolean ok, GAtResult *result,
gpointer user_data) gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
g_at_chat_send(at->parser, "AT+CSMS?", csms_prefix, g_at_chat_send(data->chat, "AT+CSMS?", csms_prefix,
at_csms_status_cb, modem, NULL); at_csms_status_cb, sms, NULL);
} }
static void at_csms_query_cb(gboolean ok, GAtResult *result, static void at_csms_query_cb(gboolean ok, GAtResult *result,
gpointer user_data) gpointer user_data)
{ {
struct ofono_modem *modem = user_data; struct ofono_sms *sms = user_data;
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
gboolean cnma_supported = FALSE; gboolean cnma_supported = FALSE;
GAtResultIter iter; GAtResultIter iter;
int status; int status;
@ -956,12 +934,7 @@ static void at_csms_query_cb(gboolean ok, GAtResult *result,
dump_response("csms_query_cb", ok, result); dump_response("csms_query_cb", ok, result);
if (!ok) if (!ok)
return at_sms_not_supported(modem); return at_sms_not_supported(sms);
at->sms = sms_create();
if (!at->sms)
return;
g_at_result_iter_init(&iter, result); g_at_result_iter_init(&iter, result);
@ -979,27 +952,53 @@ static void at_csms_query_cb(gboolean ok, GAtResult *result,
out: out:
sprintf(buf, "AT+CSMS=%d", cnma_supported ? 1 : 0); sprintf(buf, "AT+CSMS=%d", cnma_supported ? 1 : 0);
g_at_chat_send(at->parser, buf, csms_prefix, g_at_chat_send(data->chat, buf, csms_prefix,
at_csms_set_cb, modem, NULL); at_csms_set_cb, sms, NULL);
} }
void at_sms_init(struct ofono_modem *modem) static int at_sms_probe(struct ofono_sms *sms)
{ {
struct at_data *at = ofono_modem_get_userdata(modem); GAtChat *chat = ofono_sms_get_data(sms);
struct sms_data *data;
g_at_chat_send(at->parser, "AT+CSMS=?", csms_prefix, data = g_new0(struct sms_data, 1);
at_csms_query_cb, modem, NULL); data->chat = chat;
ofono_sms_set_data(sms, data);
g_at_chat_send(chat, "AT+CSMS=?", csms_prefix,
at_csms_query_cb, sms, NULL);
return 0;
} }
void at_sms_exit(struct ofono_modem *modem) static int at_sms_remove(struct ofono_sms *sms)
{ {
struct at_data *at = ofono_modem_get_userdata(modem); struct sms_data *data = ofono_sms_get_data(sms);
if (!at->sms) if (data->cnma_ack_pdu)
return; g_free(data->cnma_ack_pdu);
sms_destroy(at->sms); g_free(data);
at->sms = NULL;
ofono_sms_manager_unregister(modem); return 0;
}
static struct ofono_sms_driver driver = {
.name = "generic_at",
.probe = at_sms_probe,
.remove = at_sms_remove,
.sca_query = at_csca_query,
.sca_set = at_csca_set,
.submit = at_cmgs,
};
void at_sms_init()
{
ofono_sms_driver_register(&driver);
}
void at_sms_exit()
{
ofono_sms_driver_unregister(&driver);
} }