From da6f3e63e020f51915c856a0fa50aa7c0378f200 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Thu, 17 Dec 2009 19:52:32 +0100 Subject: [PATCH] Handle EF-CBSMID contents. --- src/cbs.c | 29 ++++++++++++++++++++--------- src/ofono.h | 6 +++++- src/sim.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/cbs.c b/src/cbs.c index 42594c76..e088bfd6 100644 --- a/src/cbs.c +++ b/src/cbs.c @@ -184,6 +184,11 @@ void ofono_cbs_notify(struct ofono_cbs *cbs, const unsigned char *pdu, return; } + if (cbs_topic_in_range(c.message_identifier, cbs->efcbmid_contents)) { + __ofono_cbs_sim_download(cbs->sim, pdu, pdu_len); + return; + } + if (!cbs_dcs_decode(c.dcs, &udhi, &cls, &charset, &comp, NULL, NULL)) { ofono_error("Unknown / Reserved DCS. Ignoring"); return; @@ -332,6 +337,10 @@ static DBusMessage *cbs_set_topics(struct ofono_cbs *cbs, const char *value, if (topics != NULL) etws_topics = g_slist_copy(topics); + if (cbs->efcbmid_contents != NULL) + etws_topics = g_slist_concat(etws_topics, + g_slist_copy(cbs->efcbmid_contents)); + etws_topics = g_slist_append(etws_topics, &etws_range); topic_str = cbs_topic_ranges_to_string(etws_topics); g_slist_free(etws_topics); @@ -437,6 +446,13 @@ static void cbs_unregister(struct ofono_atom *atom) cbs->new_topics = NULL; } + if (cbs->efcbmid_length) { + cbs->efcbmid_length = 0; + g_slist_foreach(cbs->efcbmid_contents, (GFunc)g_free, NULL); + g_slist_free(cbs->efcbmid_contents); + cbs->efcbmid_contents = NULL; + } + cbs->sim = NULL; if (cbs->reset_source) { @@ -627,6 +643,7 @@ static void sim_cbmid_read_cb(int ok, int length, int record, unsigned short mi; int i; char *str; + GSList *contents = NULL; if (!ok) return; @@ -648,23 +665,17 @@ static void sim_cbmid_read_cb(int ok, int length, int record, range->min = mi; range->max = mi; - cbs->efcbmid_contents = g_slist_prepend(cbs->efcbmid_contents, - range); + contents = g_slist_prepend(contents, range); } - if (cbs->efcbmid_contents == NULL) + if (contents == NULL) return; - cbs->efcbmid_contents = g_slist_reverse(cbs->efcbmid_contents); + cbs->efcbmid_contents = g_slist_reverse(contents); str = cbs_topic_ranges_to_string(cbs->efcbmid_contents); ofono_debug("Got cbmid: %s", str); g_free(str); - - cbs->efcbmid_length = 0; - g_slist_foreach(cbs->efcbmid_contents, (GFunc)g_free, NULL); - g_slist_free(cbs->efcbmid_contents); - cbs->efcbmid_contents = NULL; } static void cbs_got_imsi(struct ofono_cbs *cbs) diff --git a/src/ofono.h b/src/ofono.h index 31524b50..05d035ea 100644 --- a/src/ofono.h +++ b/src/ofono.h @@ -167,11 +167,15 @@ void __ofono_atom_free(struct ofono_atom *atom); #include #include #include -#include #include #include #include +#include + +void __ofono_cbs_sim_download(struct ofono_sim *sim, + const guint8 *pdu, int pdu_len); + #include typedef void (*ofono_ssn_mo_notify_cb)(int index, void *user); diff --git a/src/sim.c b/src/sim.c index 907e4ced..a8543169 100644 --- a/src/sim.c +++ b/src/sim.c @@ -1720,6 +1720,40 @@ void ofono_sim_set_ready(struct ofono_sim *sim) } } +static void sim_cb_download_cb(const struct ofono_error *error, + const unsigned char *data, int len, void *user) +{ + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { + ofono_error("CellBroadcast download to UICC failed"); + return; + } + + ofono_debug("CellBroadcast download to UICC reported no error"); +} + +void __ofono_cbs_sim_download(struct ofono_sim *sim, + const guint8 *pdu, int pdu_len) +{ + guint8 tlv[pdu_len + 8]; + + if (sim->ready != TRUE) + return; + if (!sim->driver->envelope) + return; + + tlv[0] = 0xd2; /* Cell Broadcast Download */ + tlv[1] = 6 + pdu_len; + tlv[2] = 0x82; /* Device Identities */ + tlv[3] = 0x02; /* Device Identities length */ + tlv[4] = 0x83; /* Network */ + tlv[5] = 0x81; /* UICC */ + tlv[6] = 0x8c; /* Cell Broadcast page */ + tlv[7] = pdu_len; + memcpy(tlv + 8, pdu, pdu_len); + + sim->driver->envelope(sim, pdu_len + 8, tlv, sim_cb_download_cb, sim); +} + int ofono_sim_driver_register(const struct ofono_sim_driver *d) { DBG("driver: %p, name: %s", d, d->name);