--- src/network.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 84 insertions(+), 1 deletions(-)
diff --git a/src/network.c b/src/network.c index ae0f334..927f7ce 100644 --- a/src/network.c +++ b/src/network.c @@ -66,6 +66,7 @@ struct ofono_netreg { int cellid; int technology; int mode; + gboolean forced_auto; char *base_station; struct network_operator_data *current_operator; GSList *operator_list; @@ -174,6 +175,36 @@ static void set_registration_mode(struct ofono_netreg *netreg, int mode) "Mode", DBUS_TYPE_STRING, &strmode); } +static void set_registration_forced_auto(struct ofono_netreg *netreg, gboolean value) +{ + DBusConnection *conn; + const char *strmode; + const char *path; + + if (netreg->forced_auto == value) + return; + + netreg->forced_auto = value; + + if (netreg->settings) { + g_key_file_set_boolean(netreg->settings, SETTINGS_GROUP, + "ForcedAuto", netreg->forced_auto); + storage_sync(netreg->imsi, SETTINGS_STORE, netreg->settings); + } + + if (value) + strmode = "forced-auto"; + else + strmode = registration_mode_to_string(netreg->mode); + + conn = ofono_dbus_get_connection(); + path = __ofono_atom_get_path(netreg->atom); + + ofono_dbus_signal_property_changed(conn, path, + OFONO_NETWORK_REGISTRATION_INTERFACE, + "Mode", DBUS_TYPE_STRING, &strmode); +} + static void registration_status_callback(const struct ofono_error *error, int status, int lac, int ci, int tech, void *data) @@ -588,6 +619,9 @@ static DBusMessage *network_operator_register(DBusConnection *conn, struct network_operator_data *opd = data; struct ofono_netreg *netreg = opd->netreg; + if (netreg->forced_auto) + return __ofono_error_access_denied(msg); + if (netreg->pending) return __ofono_error_busy(msg); @@ -757,7 +791,12 @@ static DBusMessage *network_get_properties(DBusConnection *conn, const char *status = registration_status_to_string(netreg->status); const char *operator; - const char *mode = registration_mode_to_string(netreg->mode); + const char *mode; + + if (netreg->forced_auto) + mode = "forced-auto"; + else + mode = registration_mode_to_string(netreg->mode); reply = dbus_message_new_method_return(msg); if (reply == NULL) @@ -1598,6 +1637,43 @@ static void sim_spn_read_cb(int ok, int length, int record, } } +static void sim_csp_read_cb(int ok, int length, int record, + const unsigned char *data, + int record_length, void *user_data) +{ + struct ofono_netreg *netreg = user_data; + int i; + + if (!ok) + return; + + if (length < 18 || record_length < 18 || length < record_length) + return; + + /* + * Acording to CPHS 4.2, EFcsp is an array of two-byte service + * entries, each consisting of a one byte service group + * identifier followed by 8 bits; each bit is indicating + * availability of a specific service or feature. + * + * The PLMN mode bit, if present, indicates whether manual + * operator selection should be disabled or enabled. When + * unset, the device is forced to automatic mode; when set, + * manual selection is to be enabled. The latter is also the + * default. + */ + for (i = 0; i < record_length / 2; i++) { + gboolean forced_auto; + + if (data[i * 2] != SIM_CSP_ENTRY_VALUE_ADDED_SERVICES) + continue; + + forced_auto = (data[i * 2 + 1] & 0x80) == 0; + + set_registration_forced_auto(netreg, forced_auto); + } +} + int ofono_netreg_get_location(struct ofono_netreg *netreg) { if (netreg == NULL) @@ -1803,6 +1879,10 @@ static void netreg_load_settings(struct ofono_netreg *netreg) g_key_file_set_integer(netreg->settings, SETTINGS_GROUP, "Mode", netreg->mode); + + netreg->forced_auto = g_key_file_get_boolean(netreg->settings, + SETTINGS_GROUP, + "ForcedAuto", NULL); } void ofono_netreg_register(struct ofono_netreg *netreg) @@ -1845,6 +1925,9 @@ void ofono_netreg_register(struct ofono_netreg *netreg) ofono_sim_read(netreg->sim, SIM_EFSPN_FILEID, OFONO_SIM_FILE_STRUCTURE_TRANSPARENT, sim_spn_read_cb, netreg); + ofono_sim_read(netreg->sim, SIM_EF_CPHS_CSP_FILEID, + OFONO_SIM_FILE_STRUCTURE_TRANSPARENT, + sim_csp_read_cb, netreg); } __ofono_atom_register(netreg->atom, netreg_unregister); -- 1.7.1 _______________________________________________ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono