Check the remaining pin retries after each operation that might have
changed it, i.e. locking, unlocking, reseting or changing pin.
---
src/sim.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/src/sim.c b/src/sim.c
index 335f611..a57fe84 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -62,6 +62,8 @@ struct ofono_sim {
enum ofono_sim_password_type pin_type;
gboolean locked_pins[OFONO_SIM_PASSWORD_SIM_PUK]; /* Number of PINs */
+ GSList *pin_retries;
+
enum ofono_sim_phase phase;
unsigned char mnc_length;
enum ofono_sim_cphs_phase cphs_phase;
@@ -248,6 +250,27 @@ static char **get_locked_pins(struct ofono_sim *sim)
return ret;
}
+static void **get_pin_retries(GSList *pin_retries)
+{
+ int nelem;
+ GSList *l;
+ void **ret;
+
+ nelem = g_slist_length(pin_retries) * 2;
+
+ ret = g_new0(void *, nelem + 1);
+
+ nelem = 0;
+ for (l = pin_retries; l; l = l->next) {
+ struct ofono_sim_pin_retry *retry = l->data;
+
+ ret[nelem++] = (void *)(sim_passwd_name(retry->id));
+ ret[nelem++] = &(retry->val);
+ }
+
+ return ret;
+}
+
static char **get_service_numbers(GSList *service_numbers)
{
int nelem;
@@ -287,6 +310,7 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
char **service_numbers;
char **locked_pins;
const char *pin_name;
+ void **pin_retries;
dbus_bool_t present = sim->state != OFONO_SIM_STATE_NOT_PRESENT;
dbus_bool_t fdn;
dbus_bool_t bdn;
@@ -369,12 +393,75 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
DBUS_TYPE_STRING,
(void *) &pin_name);
+ if (sim->pin_retries) {
+ pin_retries = get_pin_retries(sim->pin_retries);
+
+ ofono_dbus_dict_append_dict(&dict, "Retries", DBUS_TYPE_BYTE,
+ &pin_retries);
+
+ g_free(pin_retries);
+ }
+
done:
dbus_message_iter_close_container(&iter, &dict);
return reply;
}
+static void sim_pin_retries_query_cb(const struct ofono_error *error,
+ GSList *lretries, void *data)
+{
+ struct ofono_sim *sim = data;
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = __ofono_atom_get_path(sim->atom);
+ GSList *lnew, *lold;
+ void **pin_retries;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ ofono_error("Querying remaining pin retries failed");
+
+ return;
+ }
+
+ for (lnew = lretries, lold = sim->pin_retries;
+ lnew && lold; lnew = lnew->next, lold = lold->next) {
+ struct ofono_sim_pin_retry *rnew = lnew->data;
+ struct ofono_sim_pin_retry *rold = lold->data;
+
+ if (rnew->id != rold->id || rnew->val != rold->val)
+ break;
+ }
+
+ if (lnew == NULL && lold == NULL) {
+ g_slist_foreach(lretries, (GFunc) g_free, NULL);
+ g_slist_free(lretries);
+
+ return;
+ }
+
+ g_slist_foreach(sim->pin_retries, (GFunc) g_free, NULL);
+ g_slist_free(sim->pin_retries);
+
+ sim->pin_retries = lretries;
+
+ pin_retries = get_pin_retries(sim->pin_retries);
+
+ ofono_dbus_signal_dict_property_changed(conn, path,
+ OFONO_SIM_MANAGER_INTERFACE, "Retries",
+ DBUS_TYPE_BYTE, &pin_retries);
+
+ g_free(pin_retries);
+}
+
+static void sim_pin_retries_check(struct ofono_sim *sim)
+{
+ if (sim->driver->query_pin_retries == NULL)
+ return;
+
+ sim->driver->query_pin_retries(sim, sim_pin_retries_query_cb, sim);
+}
+
+
static void msisdn_set_done(struct msisdn_set_request *req)
{
DBusMessage *reply;
@@ -549,6 +636,8 @@ static void sim_locked_cb(struct ofono_sim *sim, gboolean locked)
"LockedPins", DBUS_TYPE_STRING,
&locked_pins);
g_strfreev(locked_pins);
+
+ sim_pin_retries_check(sim);
}
static void sim_unlock_cb(const struct ofono_error *error, void *data)
@@ -557,7 +646,10 @@ static void sim_unlock_cb(const struct ofono_error *error, void
*data)
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBusMessage *reply = __ofono_error_failed(sim->pending);
+
__ofono_dbus_pending_reply(&sim->pending, reply);
+ sim_pin_retries_check(sim);
+
return;
}
@@ -570,7 +662,10 @@ static void sim_lock_cb(const struct ofono_error *error, void *data)
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBusMessage *reply = __ofono_error_failed(sim->pending);
+
__ofono_dbus_pending_reply(&sim->pending, reply);
+ sim_pin_retries_check(sim);
+
return;
}
@@ -639,11 +734,16 @@ static void sim_change_pin_cb(const struct ofono_error *error, void
*data)
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
__ofono_dbus_pending_reply(&sim->pending,
__ofono_error_failed(sim->pending));
+
+ sim_pin_retries_check(sim);
+
return;
}
__ofono_dbus_pending_reply(&sim->pending,
dbus_message_new_method_return(sim->pending));
+
+ sim_pin_retries_check(sim);
}
static DBusMessage *sim_change_pin(DBusConnection *conn, DBusMessage *msg,
@@ -1594,6 +1694,8 @@ static void sim_pin_query_cb(const struct ofono_error *error,
&pin_name);
}
+ sim_pin_retries_check(sim);
+
checkdone:
if (pin_type == OFONO_SIM_PASSWORD_NONE)
sim_initialize_after_pin(sim);
--
1.7.3.4