[PATCH 4/4] Save CellBroadcast Topics list, handle EF-CBMI, EF-CBMIR.
by Andrzej Zaborowski
The two SIM files are only used to bootstrap the topics list value
if there's no previous value. I think there's no point in updating
their contents because if the user adds new ranges, most likely the
list will not fit the file sizes and writing will fail so we will need
to use the copy from IMSI based storage. And if we use our copy then
we won't detect changes made to these files when ofono wasn't running.
(Basically we have a choice between storing new values in the SIM or
our own storage, but doing both things doesn't make sense)
---
src/cbs.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 65 insertions(+), 19 deletions(-)
diff --git a/src/cbs.c b/src/cbs.c
index 5d326fc..0ab2890 100644
--- a/src/cbs.c
+++ b/src/cbs.c
@@ -347,6 +347,12 @@ static void cbs_set_topics_cb(const struct ofono_error *error, void *data)
CBS_MANAGER_INTERFACE,
"Topics",
DBUS_TYPE_STRING, &topics);
+
+ if (cbs->settings) {
+ g_key_file_set_string(cbs->settings, SETTINGS_GROUP,
+ "Topics", topics);
+ storage_sync(cbs->imsi, SETTINGS_STORE, cbs->settings);
+ }
g_free(topics);
}
@@ -672,6 +678,63 @@ struct ofono_cbs *ofono_cbs_create(struct ofono_modem *modem,
return cbs;
}
+static void cbs_got_file_contents(struct ofono_cbs *cbs)
+{
+ gboolean powered;
+ GSList *topics = NULL;
+ GSList *initial_topics = NULL;
+ char *topics_str;
+ GError *error = NULL;
+
+ topics_str = g_key_file_get_string(cbs->settings, SETTINGS_GROUP,
+ "Topics", NULL);
+ if (topics_str) {
+ topics = cbs_extract_topic_ranges(topics_str);
+ g_free(topics_str);
+ }
+
+ /* If stored value is invalid or no stored value, bootstrap
+ * topics list from SIM contents */
+ if (topics == NULL && (topics_str == NULL || topics_str[0] != '\0')) {
+ if (cbs->efcbmi_contents != NULL)
+ initial_topics = g_slist_concat(initial_topics,
+ g_slist_copy(cbs->efcbmi_contents));
+
+ if (cbs->efcbmir_contents != NULL)
+ initial_topics = g_slist_concat(initial_topics,
+ g_slist_copy(cbs->efcbmir_contents));
+
+ topics = cbs_optimize_ranges(initial_topics);
+ g_slist_free(initial_topics);
+
+ topics_str = cbs_topic_ranges_to_string(topics);
+ g_key_file_set_string(cbs->settings, SETTINGS_GROUP,
+ "Topics", topics_str);
+ g_free(topics_str);
+ storage_sync(cbs->imsi, SETTINGS_STORE, cbs->settings);
+ }
+
+ cbs->topics = topics;
+
+ if (cbs->efcbmi_length) {
+ cbs->efcbmi_length = 0;
+ g_slist_foreach(cbs->efcbmi_contents, (GFunc) g_free, NULL);
+ g_slist_free(cbs->efcbmi_contents);
+ cbs->efcbmi_contents = NULL;
+ }
+
+ if (cbs->efcbmir_length) {
+ cbs->efcbmir_length = 0;
+ g_slist_foreach(cbs->efcbmir_contents, (GFunc) g_free, NULL);
+ g_slist_free(cbs->efcbmir_contents);
+ cbs->efcbmir_contents = NULL;
+ }
+
+ powered = g_key_file_get_boolean(cbs->settings, SETTINGS_GROUP,
+ "Powered", &error);
+ cbs_set_powered(cbs, powered, NULL);
+}
+
static void sim_cbmi_read_cb(int ok, int length, int record,
const unsigned char *data,
int record_length, void *userdata)
@@ -711,16 +774,9 @@ static void sim_cbmi_read_cb(int ok, int length, int record,
if (cbs->efcbmi_contents == NULL)
return;
- cbs->efcbmi_contents = g_slist_reverse(cbs->efcbmi_contents);
-
str = cbs_topic_ranges_to_string(cbs->efcbmi_contents);
ofono_debug("Got cbmi: %s", str);
g_free(str);
-
- cbs->efcbmi_length = 0;
- g_slist_foreach(cbs->efcbmi_contents, (GFunc)g_free, NULL);
- g_slist_free(cbs->efcbmi_contents);
- cbs->efcbmi_contents = NULL;
}
static void sim_cbmir_read_cb(int ok, int length, int record,
@@ -765,16 +821,9 @@ static void sim_cbmir_read_cb(int ok, int length, int record,
if (cbs->efcbmir_contents == NULL)
return;
- cbs->efcbmir_contents = g_slist_reverse(cbs->efcbmir_contents);
-
str = cbs_topic_ranges_to_string(cbs->efcbmir_contents);
ofono_debug("Got cbmir: %s", str);
g_free(str);
-
- cbs->efcbmir_length = 0;
- g_slist_foreach(cbs->efcbmir_contents, (GFunc)g_free, NULL);
- g_slist_free(cbs->efcbmir_contents);
- cbs->efcbmir_contents = NULL;
}
static void sim_cbmid_read_cb(int ok, int length, int record,
@@ -820,12 +869,13 @@ static void sim_cbmid_read_cb(int ok, int length, int record,
str = cbs_topic_ranges_to_string(cbs->efcbmid_contents);
ofono_debug("Got cbmid: %s", str);
g_free(str);
+
+ cbs_got_file_contents(cbs);
}
static void cbs_got_imsi(struct ofono_cbs *cbs)
{
const char *imsi = ofono_sim_get_imsi(cbs->sim);
- gboolean powered;
ofono_debug("Got IMSI: %s", imsi);
@@ -835,10 +885,6 @@ static void cbs_got_imsi(struct ofono_cbs *cbs)
cbs->imsi = g_strdup(imsi);
- powered = g_key_file_get_boolean(cbs->settings, SETTINGS_GROUP,
- "Powered", NULL);
- cbs_set_powered(cbs, powered, NULL);
-
ofono_sim_read(cbs->sim, SIM_EFCBMI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cbmi_read_cb, cbs);
--
1.6.1
12 years, 5 months
[PATCH] Support 51.011 EFecc format.
by Andrzej Zaborowski
EFecc has different formats in G2 and G3 UICC specs.
---
src/voicecall.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/src/voicecall.c b/src/voicecall.c
index e52ca66..52383e7 100644
--- a/src/voicecall.c
+++ b/src/voicecall.c
@@ -1663,8 +1663,42 @@ static void set_new_ecc(struct ofono_voicecall *vc)
emit_en_list_changed(vc);
}
-static void ecc_read_cb(int ok, int total_length, int record, const unsigned char *data,
- int record_length, void *userdata)
+static void ecc_g2_read_cb(int ok, int total_length, int record,
+ const unsigned char *data,
+ int record_length, void *userdata)
+{
+ struct ofono_voicecall *vc = userdata;
+ char en[7];
+
+ DBG("%d", ok);
+
+ if (!ok)
+ return;
+
+ if (total_length < 3) {
+ ofono_error("Unable to read emergency numbers from SIM");
+ return;
+ }
+
+ total_length /= 3;
+ while (total_length--) {
+ extract_bcd_number(data, 3, en);
+ data += 3;
+
+ if (en[0] != '\0')
+ vc->new_en_list = g_slist_prepend(vc->new_en_list,
+ g_strdup(en));
+ }
+
+ if (vc->new_en_list == NULL)
+ return;
+
+ set_new_ecc(vc);
+}
+
+static void ecc_g3_read_cb(int ok, int total_length, int record,
+ const unsigned char *data,
+ int record_length, void *userdata)
{
struct ofono_voicecall *vc = userdata;
int total;
@@ -1821,8 +1855,13 @@ static void sim_watch(struct ofono_atom *atom,
return;
}
- ofono_sim_read(sim, SIM_EFECC_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED,
- ecc_read_cb, vc);
+ /* Try both formats, only one or none will work */
+ ofono_sim_read(sim, SIM_EFECC_FILEID,
+ OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+ ecc_g2_read_cb, vc);
+ ofono_sim_read(sim, SIM_EFECC_FILEID,
+ OFONO_SIM_FILE_STRUCTURE_FIXED,
+ ecc_g3_read_cb, vc);
}
void ofono_voicecall_register(struct ofono_voicecall *vc)
--
1.6.1
12 years, 5 months
[PATCH 1/1] add netmask to hso gprs-context driver
by Xu, Martin
>From 0a2f79bf4282562db1230e511b24214345689e18 Mon Sep 17 00:00:00 2001
From: Martin Xu <martin.xu(a)intel.com>
Date: Thu, 24 Dec 2009 12:29:56 -0500
Subject: [PATCH 1/1] add netmask to hso gprs-context driver
---
drivers/hsomodem/gprs-context.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/hsomodem/gprs-context.c b/drivers/hsomodem/gprs-context.c
index 0526fcc..721a017 100644
--- a/drivers/hsomodem/gprs-context.c
+++ b/drivers/hsomodem/gprs-context.c
@@ -47,6 +47,8 @@
#define AUTH_BUF_LENGTH OFONO_GPRS_MAX_USERNAME_LENGTH + \
OFONO_GPRS_MAX_PASSWORD_LENGTH + 128
+#define STATIC_IP_NETMASK "255.255.255.255"
+
static const char *none_prefix[] = { NULL };
static const char *owandata_prefix[] = { "_OWANDATA:", NULL };
@@ -274,7 +276,7 @@ static void owandata_cb(gboolean ok, GAtResult *result, gpointer user_data)
ofono_info("IP: %s, Gateway: %s", ip, gateway);
ofono_info("DNS: %s, %s", dns1, dns2);
- CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, TRUE, ip, NULL,
+ CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, TRUE, ip, STATIC_IP_NETMASK,
gateway, dns, gcd->cb_data);
gcd->hso_state = HSO_NONE;
--
1.6.1.3
12 years, 6 months
Merry Christmas to everyone
by Marcel Holtmann
Hello everyone,
and Santa is coming to town and bringing the 0.15 release with him. Many
thanks to all contributors during this year.
We had 28 different contributors with all together 1464 commits in the
public repository which goes back as far as April. The line count
summary for a project that is fairly new is actually quite impressive:
Language Files Code Comment Comment % Blank Total
---------------- ----- --------- --------- --------- --------- ---------
c 163 44816 4958 10.0% 13396 63170
python 29 989 35 3.4% 436 1460
automake 1 251 0 0.0% 80 331
autoconf 1 132 1 0.8% 34 167
shell 3 29 3 9.4% 8 40
---------------- ----- --------- --------- --------- --------- ---------
Total 197 46217 4997 9.8% 13954 65168
So enjoy your vacation and a Happy New Year :)
Regards
Marcel
12 years, 6 months
[PATCH 3/4] Add Powered property to CbsManager.
by Andrzej Zaborowski
---
src/cbs.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 165 insertions(+), 8 deletions(-)
diff --git a/src/cbs.c b/src/cbs.c
index c378f2a..5d326fc 100644
--- a/src/cbs.c
+++ b/src/cbs.c
@@ -36,9 +36,13 @@
#include "util.h"
#include "smsutil.h"
#include "simutil.h"
+#include "storage.h"
#define CBS_MANAGER_INTERFACE "org.ofono.CbsManager"
+#define SETTINGS_STORE "cbs"
+#define SETTINGS_GROUP "Settings"
+
static GSList *g_drivers = NULL;
enum etws_topic_type {
@@ -69,6 +73,9 @@ struct ofono_cbs {
int ci;
char mnc[OFONO_MAX_MNC_LENGTH + 1];
char mcc[OFONO_MAX_MCC_LENGTH + 1];
+ ofono_bool_t powered;
+ GKeyFile *settings;
+ char *imsi;
const struct ofono_cbs_driver *driver;
void *driver_data;
struct ofono_atom *atom;
@@ -178,6 +185,8 @@ void ofono_cbs_notify(struct ofono_cbs *cbs, const unsigned char *pdu,
if (cbs->assembly == NULL)
return;
+ if (!cbs->powered)
+ return;
if (!cbs_decode(pdu, pdu_len, &c)) {
ofono_error("Unable to decode CBS PDU");
@@ -272,6 +281,9 @@ static DBusMessage *cbs_get_properties(DBusConnection *conn,
OFONO_PROPERTIES_ARRAY_SIGNATURE,
&dict);
+ ofono_dbus_dict_append(&dict, "Powered", DBUS_TYPE_BOOLEAN,
+ &cbs->powered);
+
topics = cbs_topic_ranges_to_string(cbs->topics);
ofono_dbus_dict_append(&dict, "Topics", DBUS_TYPE_STRING, &topics);
g_free(topics);
@@ -281,6 +293,28 @@ static DBusMessage *cbs_get_properties(DBusConnection *conn,
return reply;
}
+static char *cbs_topics_to_str(struct ofono_cbs *cbs, GSList *user_topics)
+{
+ GSList *topics = NULL;
+ char *topic_str;
+ struct cbs_topic_range etws_range = { 4352, 4356 };
+
+ topics = g_slist_append(topics, &etws_range);
+
+ if (user_topics != NULL)
+ topics = g_slist_concat(topics,
+ g_slist_copy(user_topics));
+
+ if (cbs->efcbmid_contents != NULL)
+ topics = g_slist_concat(topics,
+ g_slist_copy(cbs->efcbmid_contents));
+
+ topic_str = cbs_topic_ranges_to_string(topics);
+ g_slist_free(topics);
+
+ return topic_str;
+}
+
static void cbs_set_topics_cb(const struct ofono_error *error, void *data)
{
struct ofono_cbs *cbs = data;
@@ -320,9 +354,8 @@ static DBusMessage *cbs_set_topics(struct ofono_cbs *cbs, const char *value,
DBusMessage *msg)
{
GSList *topics;
- GSList *etws_topics = NULL;
char *topic_str;
- struct cbs_topic_range etws_range = { 4352, 4356 };
+ struct ofono_error error;
topics = cbs_extract_topic_ranges(value);
@@ -334,20 +367,112 @@ static DBusMessage *cbs_set_topics(struct ofono_cbs *cbs, const char *value,
cbs->new_topics = topics;
- if (topics != NULL)
- etws_topics = g_slist_copy(topics);
+ cbs->pending = dbus_message_ref(msg);
- etws_topics = g_slist_append(etws_topics, &etws_range);
- topic_str = cbs_topic_ranges_to_string(etws_topics);
- g_slist_free(etws_topics);
+ if (!cbs->powered) {
+ error.type = OFONO_ERROR_TYPE_NO_ERROR;
+ cbs_set_topics_cb(&error, cbs);
+ return NULL;
+ }
- cbs->pending = dbus_message_ref(msg);
+ topic_str = cbs_topics_to_str(cbs, topics);
cbs->driver->set_topics(cbs, topic_str, cbs_set_topics_cb, cbs);
g_free(topic_str);
return NULL;
}
+static void cbs_power_off_cb(const struct ofono_error *error, void *data)
+{
+}
+
+static void cbs_power_on_cb(const struct ofono_error *error, void *data)
+{
+ struct ofono_cbs *cbs = data;
+ const char *path = __ofono_atom_get_path(cbs->atom);
+ DBusConnection *conn = ofono_dbus_get_connection();
+ DBusMessage *reply;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ ofono_debug("Setting Cell Broadcast topics failed");
+ if (!cbs->pending)
+ return;
+
+ __ofono_dbus_pending_reply(&cbs->pending,
+ __ofono_error_failed(cbs->pending));
+ return;
+ }
+
+ cbs->powered = TRUE;
+
+ if (cbs->settings) {
+ g_key_file_set_boolean(cbs->settings, SETTINGS_GROUP,
+ "Powered", cbs->powered);
+ storage_sync(cbs->imsi, SETTINGS_STORE, cbs->settings);
+ }
+
+ ofono_dbus_signal_property_changed(conn, path,
+ CBS_MANAGER_INTERFACE,
+ "Powered",
+ DBUS_TYPE_BOOLEAN,
+ &cbs->powered);
+
+ if (!cbs->pending)
+ return;
+
+ reply = dbus_message_new_method_return(cbs->pending);
+ __ofono_dbus_pending_reply(&cbs->pending, reply);
+}
+
+static DBusMessage *cbs_set_powered(struct ofono_cbs *cbs, gboolean value,
+ DBusMessage *msg)
+{
+ const char *path = __ofono_atom_get_path(cbs->atom);
+ DBusConnection *conn = ofono_dbus_get_connection();
+ char *topic_str;
+
+ if (cbs->powered == value)
+ goto reply;
+
+ if (!cbs->driver->set_topics)
+ goto done;
+
+ if (!value) {
+ cbs->driver->clear_topics(cbs, cbs_power_off_cb, cbs);
+
+ goto done;
+ }
+
+ topic_str = cbs_topics_to_str(cbs, cbs->topics);
+
+ if (msg)
+ cbs->pending = dbus_message_ref(msg);
+ cbs->driver->set_topics(cbs, topic_str, cbs_power_on_cb, cbs);
+ g_free(topic_str);
+
+ return NULL;
+done:
+ cbs->powered = value;
+
+ if (cbs->settings) {
+ g_key_file_set_boolean(cbs->settings, SETTINGS_GROUP,
+ "Powered", cbs->powered);
+ storage_sync(cbs->imsi, SETTINGS_STORE, cbs->settings);
+ }
+
+ ofono_dbus_signal_property_changed(conn, path,
+ CBS_MANAGER_INTERFACE,
+ "Powered",
+ DBUS_TYPE_BOOLEAN,
+ &cbs->powered);
+
+reply:
+ if (msg)
+ return dbus_message_new_method_return(msg);
+
+ return NULL;
+}
+
static DBusMessage *cbs_set_property(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -373,6 +498,17 @@ static DBusMessage *cbs_set_property(DBusConnection *conn, DBusMessage *msg,
dbus_message_iter_recurse(&iter, &var);
+ if (!strcmp(property, "Powered")) {
+ dbus_bool_t value;
+
+ if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
+ return __ofono_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&var, &value);
+
+ return cbs_set_powered(cbs, value, msg);
+ }
+
if (!strcmp(property, "Topics")) {
const char *value;
@@ -459,6 +595,16 @@ static void cbs_unregister(struct ofono_atom *atom)
__ofono_netreg_set_base_station_name(cbs->netreg, NULL);
}
+ cbs->powered = FALSE;
+
+ if (cbs->settings) {
+ storage_close(cbs->imsi, SETTINGS_STORE, cbs->settings, TRUE);
+
+ g_free(cbs->imsi);
+ cbs->imsi = NULL;
+ cbs->settings = NULL;
+ }
+
if (cbs->netreg_watch) {
if (cbs->location_watch) {
__ofono_netreg_remove_status_watch(cbs->netreg,
@@ -679,9 +825,20 @@ static void sim_cbmid_read_cb(int ok, int length, int record,
static void cbs_got_imsi(struct ofono_cbs *cbs)
{
const char *imsi = ofono_sim_get_imsi(cbs->sim);
+ gboolean powered;
ofono_debug("Got IMSI: %s", imsi);
+ cbs->settings = storage_open(imsi, SETTINGS_STORE);
+ if (cbs->settings == NULL)
+ return;
+
+ cbs->imsi = g_strdup(imsi);
+
+ powered = g_key_file_get_boolean(cbs->settings, SETTINGS_GROUP,
+ "Powered", NULL);
+ cbs_set_powered(cbs, powered, NULL);
+
ofono_sim_read(cbs->sim, SIM_EFCBMI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cbmi_read_cb, cbs);
--
1.6.1
12 years, 6 months
[PATCH 2/4] Handle EF-CBSMID contents.
by Andrzej Zaborowski
This lets operators download contents to the sim over the air.
---
drivers/atmodem/sim.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++
include/sim.h | 6 ++++
src/cbs.c | 27 +++++++++++-----
src/sim.c | 33 ++++++++++++++++++++
4 files changed, 138 insertions(+), 9 deletions(-)
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 92ae575..fca6f0f 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -704,6 +704,86 @@ error:
CALLBACK_WITH_FAILURE(cb, -1, data);
}
+static void at_csim_envelope_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ GAtResultIter iter;
+ ofono_sim_read_cb_t cb = cbd->cb;
+ struct ofono_error error;
+ const guint8 *response;
+ gint rlen, len;
+
+ dump_response("at_csim_envelope_cb", ok, result);
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CSIM:")) {
+ CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+ return;
+ }
+
+ if (!g_at_result_iter_next_number(&iter, &rlen)) {
+ CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+ return;
+ }
+
+ if (!g_at_result_iter_next_hexstring(&iter, &response, &len)) {
+ CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+ return;
+ }
+
+ if (rlen != len * 2 || len < 2 ||
+ response[len - 2] != 0x90 || response[len - 1] != 0) {
+ CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+ return;
+ }
+
+ ofono_debug("csim_envelope_cb: %i", len);
+
+ cb(&error, response, len - 2, cbd->data);
+}
+
+static void at_sim_envelope(struct ofono_sim *sim, int length,
+ const guint8 *command,
+ ofono_sim_read_cb_t cb, void *data)
+{
+ struct sim_data *sd = ofono_sim_get_data(sim);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ char *buf = g_try_new(char, 64 + length * 2);
+ int len, ret;
+
+ if (!cbd || !buf)
+ goto error;
+
+ len = sprintf(buf, "AT+CSIM=%i,a0c20000%02hhx",
+ 12 + length * 2, length);
+
+ for (; length; length--)
+ len += sprintf(buf + len, "%02hhx", *command++);
+ sprintf(buf + len, "00");
+
+ ret = g_at_chat_send(sd->chat, buf, crsm_prefix,
+ at_csim_envelope_cb, cbd, g_free);
+
+ g_free(buf);
+
+ if (ret > 0)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
+}
+
static gboolean at_sim_register(gpointer user)
{
struct ofono_sim *sim = user;
@@ -756,6 +836,7 @@ static struct ofono_sim_driver driver = {
.lock = at_pin_enable,
.change_passwd = at_change_passwd,
.query_locked = at_pin_query_enabled,
+ .envelope = at_sim_envelope,
};
void at_sim_init()
diff --git a/include/sim.h b/include/sim.h
index f76f9d1..8df7ec3 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -135,6 +135,9 @@ struct ofono_sim_driver {
void (*query_locked)(struct ofono_sim *sim,
enum ofono_sim_password_type type,
ofono_sim_locked_cb_t cb, void *data);
+ void (*envelope)(struct ofono_sim *sim, int length,
+ const guint8 *command,
+ ofono_sim_read_cb_t cb, void *data);
};
int ofono_sim_driver_register(const struct ofono_sim_driver *d);
@@ -176,6 +179,9 @@ int ofono_sim_write(struct ofono_sim *sim, int id,
ofono_sim_file_write_cb_t cb,
enum ofono_sim_file_structure structure, int record,
const unsigned char *data, int length, void *userdata);
+
+void ofono_cbs_download(struct ofono_sim *sim, const guint8 *pdu, int pdu_len);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/cbs.c b/src/cbs.c
index 42594c7..c378f2a 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_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;
@@ -437,6 +442,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 +639,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 +661,19 @@ 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 = cbs_optimize_ranges(contents);
+ g_slist_foreach(contents, (GFunc) g_free, NULL);
+ g_slist_free(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/sim.c b/src/sim.c
index 907e4ce..4689886 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -1720,6 +1720,39 @@ 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_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);
--
1.6.1
12 years, 6 months
[PATCH] Add full features to Huawei modem
by Gu, Yang
Hi,
This patch is to enable Huawei modem (EM770W) as a full feature modem, which supports call forwarding, call setting, phonebook, etc.
Regards,
-Yang
12 years, 6 months
[PATCH] Fix: Documentation fixes
by Anders Gustafsson
---
doc/dataconnectionmanager-api.txt | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/doc/dataconnectionmanager-api.txt
b/doc/dataconnectionmanager-api.txt
index bfc14d9..f4d70cb 100644
--- a/doc/dataconnectionmanager-api.txt
+++ b/doc/dataconnectionmanager-api.txt
@@ -132,7 +132,7 @@ Signals PropertyChanged(string property, variant value)
This signal indicates a changed value of the given
property.
-Properties boolean Activated [readwrite]
+Properties boolean Active [readwrite]
Holds whether the context is activated. This value
can be set to activate / deactivate the context.
@@ -163,6 +163,12 @@ Properties boolean Activated [readwrite]
purposes. This value cannot be changed when the
context is active.
+ string Name [readwrite]
+
+ The name is a free form string that describes this
+ context. The name should not be empty and limited
+ to a short string for display purposes.
+
dict Settings [readonly, optional]
Holds all the IP network settings
--
1.6.3.3
12 years, 6 months
[PATCH 1/1] set netmask for static ip on mbm
by Martin Xu
---
drivers/mbmmodem/gprs-context.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/mbmmodem/gprs-context.c b/drivers/mbmmodem/gprs-context.c
index 5dae7b5..407a2d3 100644
--- a/drivers/mbmmodem/gprs-context.c
+++ b/drivers/mbmmodem/gprs-context.c
@@ -48,6 +48,8 @@
#define MAX_DNS 5
+#define STATIC_IP_NETMASK "255.255.255.248"
+
static const char *none_prefix[] = { NULL };
static const char *e2ipcfg_prefix[] = { "*E2IPCFG:", NULL };
static const char *enap_prefix[] = { "*ENAP:", NULL };
@@ -133,8 +135,9 @@ out:
modem = ofono_gprs_context_get_modem(gc);
interface = ofono_modem_get_string(modem, "NetworkInterface");
- CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, success, ip, NULL,
- gateway, success ? dns : NULL, gcd->cb_data);
+ CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, success, ip,
+ STATIC_IP_NETMASK, gateway,
+ success ? dns : NULL, gcd->cb_data);
gcd->mbm_state = MBM_NONE;
gcd->up_cb = NULL;
gcd->cb_data = NULL;
--
1.6.1.3
12 years, 6 months
[PATCH 1/4] Enhance topic range list utilities
by Andrzej Zaborowski
The functions need to handle full 16-bit range to be useful for EFcbmid
handling.
---
src/smsutil.c | 28 ++++++++++++++++++++++++----
src/smsutil.h | 2 ++
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/src/smsutil.c b/src/smsutil.c
index c27e937..d5169f0 100644
--- a/src/smsutil.c
+++ b/src/smsutil.c
@@ -3509,12 +3509,12 @@ out:
return TRUE;
}
-static GSList *cbs_optimize_ranges(GSList *ranges)
+GSList *cbs_optimize_ranges(GSList *ranges)
{
struct cbs_topic_range *range;
- unsigned char bitmap[125];
+ unsigned char bitmap[8192];
GSList *l;
- unsigned short i;
+ unsigned int i;
GSList *ret = NULL;
memset(bitmap, 0, sizeof(bitmap));
@@ -3532,7 +3532,7 @@ static GSList *cbs_optimize_ranges(GSList *ranges)
range = NULL;
- for (i = 0; i <= 999; i++) {
+ for (i = 0; i <= 65535; i++) {
int byte_offset = i / 8;
int bit = i % 8;
@@ -3666,3 +3666,23 @@ char *cbs_topic_ranges_to_string(GSList *ranges)
return ret;
}
+
+static gint cbs_topic_compare(gconstpointer a, gconstpointer b)
+{
+ const struct cbs_topic_range *range = a;
+ unsigned short topic = GPOINTER_TO_UINT(b);
+
+ if (topic >= range->min && topic <= range->max)
+ return 0;
+
+ return 1;
+}
+
+gboolean cbs_topic_in_range(unsigned int topic, GSList *ranges)
+{
+ if (!ranges)
+ return FALSE;
+
+ return g_slist_find_custom(ranges, GUINT_TO_POINTER(topic),
+ cbs_topic_compare) != NULL;
+}
diff --git a/src/smsutil.h b/src/smsutil.h
index 858fc84..10774dc 100644
--- a/src/smsutil.h
+++ b/src/smsutil.h
@@ -494,3 +494,5 @@ void cbs_assembly_location_changed(struct cbs_assembly *assembly, gboolean plmn,
char *cbs_topic_ranges_to_string(GSList *ranges);
GSList *cbs_extract_topic_ranges(const char *ranges);
+GSList *cbs_optimize_ranges(GSList *ranges);
+gboolean cbs_topic_in_range(unsigned int topic, GSList *ranges);
--
1.6.1
12 years, 6 months