diff options
author | Andrzej Zaborowski <andrew.zaborowski@intel.com> | 2009-12-17 19:52:32 +0100 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2009-12-17 21:45:39 -0600 |
commit | da6f3e63e020f51915c856a0fa50aa7c0378f200 (patch) | |
tree | 0691e384788f4987ec291f65e84a0edcf154db42 /src | |
parent | 79c0d4c779c6aaef1bfe337a160e74c03187717f (diff) | |
download | ofono-da6f3e63e020f51915c856a0fa50aa7c0378f200.tar.bz2 |
Handle EF-CBSMID contents.
Diffstat (limited to 'src')
-rw-r--r-- | src/cbs.c | 29 | ||||
-rw-r--r-- | src/ofono.h | 6 | ||||
-rw-r--r-- | src/sim.c | 34 |
3 files changed, 59 insertions, 10 deletions
@@ -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 <ofono/devinfo.h> #include <ofono/phonebook.h> #include <ofono/sms.h> -#include <ofono/sim.h> #include <ofono/voicecall.h> #include <ofono/gprs.h> #include <ofono/gprs-context.h> +#include <ofono/sim.h> + +void __ofono_cbs_sim_download(struct ofono_sim *sim, + const guint8 *pdu, int pdu_len); + #include <ofono/ssn.h> typedef void (*ofono_ssn_mo_notify_cb)(int index, void *user); @@ -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); |