Compare commits

...

2 Commits

Author SHA1 Message Date
Slava Monich
adca340f4b [simfs] Prevent a crash in sim_fs_notify_file_watches. Fixes JB#38656
If no file watchers have ever been added, context->file_watches
is NULL and sim_fs_notify_file_watches() should take that into
account.
2017-05-12 23:39:37 +03:00
Slava Monich
709bb7e596 [ril] Always refresh SIM status from query_passwd_state. Fixes JB#38257
After we have entered an invalid pin too many times, RIL signals
the SIM status change, we request the new status but ofono core
asks us for the new passwd state before our SIM status query has
completed. We need to wait for the query to complete before we can
report the new status to the core.

It also won't hurt if we request a fresh SIM status every time
when query_passwd_state callback is called, just in case if RIL
fails to notify us about the SIM status change.
2017-04-27 11:18:46 +03:00
4 changed files with 54 additions and 19 deletions

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2016 Jolla Ltd.
* Copyright (C) 2015-2017 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -85,6 +85,7 @@ struct ril_sim {
ofono_sim_passwd_cb_t query_passwd_state_cb;
void *query_passwd_state_cb_data;
guint query_passwd_state_timeout_id;
gulong query_passwd_state_sim_status_refresh_id;
};
struct ril_sim_io_response {
@@ -691,6 +692,12 @@ static void ril_sim_finish_passwd_state_query(struct ril_sim *sd,
sd->query_passwd_state_timeout_id = 0;
}
if (sd->query_passwd_state_sim_status_refresh_id) {
ril_sim_card_remove_handler(sd->card,
sd->query_passwd_state_sim_status_refresh_id);
sd->query_passwd_state_sim_status_refresh_id = 0;
}
if (sd->query_passwd_state_cb) {
ofono_sim_passwd_cb_t cb = sd->query_passwd_state_cb;
void *data = sd->query_passwd_state_cb_data;
@@ -884,6 +891,15 @@ static void ril_sim_query_pin_retries(struct ofono_sim *sim,
cb(ril_error_ok(&error), sd->retries, data);
}
static void ril_sim_query_passwd_state_complete_cb(struct ril_sim_card *sc,
void *user_data)
{
struct ril_sim *sd = user_data;
GASSERT(sd->query_passwd_state_sim_status_refresh_id);
ril_sim_finish_passwd_state_query(sd, ril_sim_passwd_state(sd));
}
static gboolean ril_sim_query_passwd_state_timeout_cb(gpointer user_data)
{
struct ril_sim *sd = user_data;
@@ -899,29 +915,41 @@ static void ril_sim_query_passwd_state(struct ofono_sim *sim,
ofono_sim_passwd_cb_t cb, void *data)
{
struct ril_sim *sd = ril_sim_get_data(sim);
enum ofono_sim_password_type passwd_state = ril_sim_passwd_state(sd);
struct ofono_error error;
if (sd->query_passwd_state_timeout_id) {
g_source_remove(sd->query_passwd_state_timeout_id);
sd->query_passwd_state_timeout_id = 0;
}
if (passwd_state != OFONO_SIM_PASSWORD_INVALID) {
DBG_(sd, "%d", passwd_state);
sd->query_passwd_state_cb = NULL;
sd->query_passwd_state_cb_data = NULL;
sd->ofono_passwd_state = passwd_state;
cb(ril_error_ok(&error), passwd_state, data);
if (!sd->query_passwd_state_sim_status_refresh_id) {
ril_sim_card_remove_handler(sd->card,
sd->query_passwd_state_sim_status_refresh_id);
sd->query_passwd_state_sim_status_refresh_id = 0;
}
/* Always request fresh status, just in case. */
ril_sim_card_request_status(sd->card);
sd->query_passwd_state_cb = cb;
sd->query_passwd_state_cb_data = data;
if (ril_sim_passwd_state(sd) != OFONO_SIM_PASSWORD_INVALID) {
/* Just wait for GET_SIM_STATUS completion */
DBG_(sd, "waiting for SIM status query to complete");
sd->query_passwd_state_sim_status_refresh_id =
ril_sim_card_add_status_received_handler(sd->card,
ril_sim_query_passwd_state_complete_cb, sd);
} else {
/* Wait for the state to change */
DBG_(sd, "waiting for the SIM state to change");
sd->query_passwd_state_cb = cb;
sd->query_passwd_state_cb_data = data;
sd->query_passwd_state_timeout_id =
g_timeout_add_seconds(SIM_STATE_CHANGE_TIMEOUT_SECS,
ril_sim_query_passwd_state_timeout_cb, sd);
}
/*
* We still need to complete the request somehow, even if
* GET_STATUS never completes or SIM status never changes.
*/
sd->query_passwd_state_timeout_id =
g_timeout_add_seconds(SIM_STATE_CHANGE_TIMEOUT_SECS,
ril_sim_query_passwd_state_timeout_cb, sd);
}
static gboolean ril_sim_pin_change_state_timeout_cb(gpointer user_data)
@@ -1280,6 +1308,11 @@ static void ril_sim_remove(struct ofono_sim *sim)
g_source_remove(sd->query_passwd_state_timeout_id);
}
if (sd->query_passwd_state_sim_status_refresh_id) {
ril_sim_card_remove_handler(sd->card,
sd->query_passwd_state_sim_status_refresh_id);
}
ril_sim_card_remove_handler(sd->card, sd->card_status_id);
ril_sim_card_unref(sd->card);

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2016 Jolla Ltd.
* Copyright (C) 2015-2017 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -64,8 +64,6 @@ G_DEFINE_TYPE(RilSimCard, ril_sim_card, G_TYPE_OBJECT)
#define RIL_SIMCARD_STATE_CHANGED (0x01)
#define RIL_SIMCARD_STATUS_CHANGED (0x02)
static void ril_sim_card_request_status(struct ril_sim_card *self);
static gboolean ril_sim_card_app_equal(const struct ril_sim_card_app *a1,
const struct ril_sim_card_app *a2)
{
@@ -365,7 +363,7 @@ static void ril_sim_card_status_cb(GRilIoChannel *io, int ril_status,
}
}
static void ril_sim_card_request_status(struct ril_sim_card *self)
void ril_sim_card_request_status(struct ril_sim_card *self)
{
struct ril_sim_card_priv *priv = self->priv;

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2016 Jolla Ltd.
* Copyright (C) 2015-2017 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -55,6 +55,7 @@ typedef void (*ril_sim_card_cb_t)(struct ril_sim_card *sc, void *arg);
struct ril_sim_card *ril_sim_card_new(GRilIoChannel *io, guint slot, int flags);
struct ril_sim_card *ril_sim_card_ref(struct ril_sim_card *sc);
void ril_sim_card_unref(struct ril_sim_card *sc);
void ril_sim_card_request_status(struct ril_sim_card *self);
gboolean ril_sim_card_ready(struct ril_sim_card *sc);
gulong ril_sim_card_add_status_received_handler(struct ril_sim_card *sc,
ril_sim_card_cb_t cb, void *arg);

View File

@@ -226,6 +226,9 @@ void sim_fs_notify_file_watches(struct sim_fs *fs, int id)
struct ofono_sim_context *context = l->data;
GSList *k;
if (context->file_watches == NULL)
continue;
for (k = context->file_watches->items; k; k = k->next) {
struct file_watch *w = k->data;
ofono_sim_file_changed_cb_t notify = w->item.notify;