All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] sim: Watch for changes to relevant SIM files.
@ 2011-02-19  3:54 Andrzej Zaborowski
  2011-02-19  3:54 ` [PATCH 2/3] message-waiting: " Andrzej Zaborowski
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Andrzej Zaborowski @ 2011-02-19  3:54 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 9843 bytes --]

---
 src/sim.c |  170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 157 insertions(+), 13 deletions(-)

diff --git a/src/sim.c b/src/sim.c
index c39269d..c33fcd5 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -58,6 +58,7 @@ struct ofono_sim {
 	char **language_prefs;
 	unsigned char *efli;
 	unsigned char efli_length;
+	gboolean language_prefs_update;
 
 	enum ofono_sim_password_type pin_type;
 	gboolean locked_pins[OFONO_SIM_PASSWORD_SIM_PUK]; /* Number of PINs */
@@ -97,8 +98,10 @@ struct ofono_sim {
 
 	struct sim_fs *simfs;
 	struct ofono_sim_context *context;
+	struct ofono_sim_context *early_context;
 
 	unsigned char *iidf_image;
+	unsigned int *iidf_watch_ids;
 
 	DBusMessage *pending;
 	const struct ofono_sim_driver *driver;
@@ -928,6 +931,11 @@ static void sim_iidf_read_cb(int ok, int length, int record,
 					sim_iidf_read_clut_cb, sim);
 }
 
+static void sim_image_data_changed(int id, void *userdata)
+{
+	/* TODO: notify D-bus clients */
+}
+
 static void sim_get_image(struct ofono_sim *sim, unsigned char id,
 				gpointer user_data)
 {
@@ -941,7 +949,7 @@ static void sim_get_image(struct ofono_sim *sim, unsigned char id,
 
 	if (image != NULL) {
 		sim_get_image_cb(sim, id, image, FALSE);
-		return;
+		goto watch;
 	}
 
 	if (sim->efimg_length <= (id * 9)) {
@@ -958,6 +966,17 @@ static void sim_get_image(struct ofono_sim *sim, unsigned char id,
 	/* read the image data */
 	ofono_sim_read_bytes(sim->context, iidf_id, iidf_offset, iidf_len,
 				sim_iidf_read_cb, sim);
+
+watch:
+	if (sim->efimg_length <= id * 9)
+		return;
+
+	if (sim->iidf_watch_ids[id] > 0)
+		return;
+
+	sim->iidf_watch_ids[id] = ofono_sim_add_file_watch(sim->context,
+					iidf_id, sim_image_data_changed,
+					sim, NULL);
 }
 
 static DBusMessage *sim_get_icon(DBusConnection *conn,
@@ -1197,10 +1216,12 @@ out:
 check:
 	/* All records retrieved */
 	if (sim->service_numbers) {
-		char **service_numbers;
-
 		sim->service_numbers = g_slist_reverse(sim->service_numbers);
 		sim->sdn_ready = TRUE;
+	}
+
+	if (sim->sdn_ready) {
+		char **service_numbers;
 
 		service_numbers = get_service_numbers(sim->service_numbers);
 
@@ -1213,6 +1234,21 @@ check:
 	}
 }
 
+static void sim_service_numbers_changed(int id, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+
+	if (sim->service_numbers) {
+		g_slist_foreach(sim->service_numbers,
+				(GFunc)service_number_free, NULL);
+		g_slist_free(sim->service_numbers);
+		sim->service_numbers = NULL;
+	}
+
+	ofono_sim_read(sim->context, SIM_EFSDN_FILEID,
+			OFONO_SIM_FILE_STRUCTURE_FIXED, sim_sdn_read_cb, sim);
+}
+
 static void sim_own_numbers_update(struct ofono_sim *sim)
 {
 	ofono_sim_read(sim->context, SIM_EFMSISDN_FILEID,
@@ -1220,6 +1256,13 @@ static void sim_own_numbers_update(struct ofono_sim *sim)
 			sim);
 }
 
+static void sim_own_numbers_changed(int id, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+
+	sim_own_numbers_update(sim);
+}
+
 static void sim_efimg_read_cb(int ok, int length, int record,
 				const unsigned char *data,
 				int record_length, void *userdata)
@@ -1247,6 +1290,11 @@ static void sim_efimg_read_cb(int ok, int length, int record,
 		if (sim->efimg == NULL)
 			return;
 
+		sim->iidf_watch_ids = g_try_new0(unsigned int, num_records);
+
+		if (sim->iidf_watch_ids == NULL)
+			return;
+
 		sim->efimg_length = num_records * 9;
 	}
 
@@ -1261,6 +1309,33 @@ static void sim_efimg_read_cb(int ok, int length, int record,
 	memcpy(efimg, &data[1], 9);
 }
 
+static void sim_efimg_changed(int id, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+	int i, watch;
+
+	if (sim->efimg != NULL) {
+		for (i = sim->efimg_length / 9 - 1; i >= 0; i--) {
+			watch = sim->iidf_watch_ids[i];
+			if (watch == 0)
+				continue;
+
+			ofono_sim_remove_file_watch(sim->context, watch);
+		}
+
+		g_free(sim->efimg);
+		sim->efimg = NULL;
+		sim->efimg_length = 0;
+		g_free(sim->iidf_watch_ids);
+		sim->iidf_watch_ids = NULL;
+	}
+
+	ofono_sim_read(sim->context, SIM_EFIMG_FILEID,
+			OFONO_SIM_FILE_STRUCTURE_FIXED, sim_efimg_read_cb, sim);
+
+	/* TODO: notify D-bus clients */
+}
+
 static void sim_ready(enum ofono_sim_state new_state, void *user)
 {
 	struct ofono_sim *sim = user;
@@ -1269,11 +1344,18 @@ static void sim_ready(enum ofono_sim_state new_state, void *user)
 		return;
 
 	sim_own_numbers_update(sim);
+	ofono_sim_add_file_watch(sim->context, SIM_EFMSISDN_FILEID,
+					sim_own_numbers_changed, sim, NULL);
 
 	ofono_sim_read(sim->context, SIM_EFSDN_FILEID,
 			OFONO_SIM_FILE_STRUCTURE_FIXED, sim_sdn_read_cb, sim);
+	ofono_sim_add_file_watch(sim->context, SIM_EFSDN_FILEID,
+					sim_service_numbers_changed, sim, NULL);
+
 	ofono_sim_read(sim->context, SIM_EFIMG_FILEID,
 			OFONO_SIM_FILE_STRUCTURE_FIXED, sim_efimg_read_cb, sim);
+	ofono_sim_add_file_watch(sim->context, SIM_EFIMG_FILEID,
+					sim_efimg_changed, sim, NULL);
 }
 
 static void sim_set_ready(struct ofono_sim *sim)
@@ -1846,7 +1928,15 @@ skip_efpl:
 						DBUS_TYPE_STRING,
 						&sim->language_prefs);
 
-	sim_pin_check(sim);
+	/* Proceed with sim initialization if we're not merely updating */
+	if (!sim->language_prefs_update) {
+		if (sim->context == NULL)
+			sim->context = ofono_sim_context_create(sim);
+
+		sim_pin_check(sim);
+	}
+
+	sim->language_prefs_update = FALSE;
 }
 
 static void sim_iccid_read_cb(int ok, int length, int record,
@@ -1872,6 +1962,43 @@ static void sim_iccid_read_cb(int ok, int length, int record,
 						&sim->iccid);
 }
 
+static void sim_iccid_changed(int id, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+
+	if (sim->iccid) {
+		g_free(sim->iccid);
+		sim->iccid = NULL;
+	}
+
+	ofono_sim_read(sim->early_context, SIM_EF_ICCID_FILEID,
+			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+			sim_iccid_read_cb, sim);
+}
+
+static void sim_efli_efpl_changed(int id, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+
+	if (sim->efli != NULL) /* This shouldn't happen */
+		return;
+
+	if (sim->language_prefs) {
+		g_strfreev(sim->language_prefs);
+		sim->language_prefs = NULL;
+	}
+
+	sim->language_prefs_update = TRUE;
+
+	ofono_sim_read(sim->early_context, SIM_EFLI_FILEID,
+			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+			sim_efli_read_cb, sim);
+
+	ofono_sim_read(sim->early_context, SIM_EFPL_FILEID,
+			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+			sim_efpl_read_cb, sim);
+}
+
 static void sim_initialize(struct ofono_sim *sim)
 {
 	/*
@@ -1900,10 +2027,15 @@ static void sim_initialize(struct ofono_sim *sim)
 	 * in the EFust
 	 */
 
+	if (sim->early_context == NULL)
+		sim->early_context = ofono_sim_context_create(sim);
+
 	/* Grab the EFiccid which is always available */
-	ofono_sim_read(sim->context, SIM_EF_ICCID_FILEID,
+	ofono_sim_read(sim->early_context, SIM_EF_ICCID_FILEID,
 			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 			sim_iccid_read_cb, sim);
+	ofono_sim_add_file_watch(sim->early_context, SIM_EF_ICCID_FILEID,
+					sim_iccid_changed, sim, NULL);
 
 	/* EFecc is read by the voicecall atom */
 
@@ -1915,12 +2047,17 @@ static void sim_initialize(struct ofono_sim *sim)
 	 * However we don't depend on the user interface and so
 	 * need to read both files now.
 	 */
-	ofono_sim_read(sim->context, SIM_EFLI_FILEID,
+	ofono_sim_read(sim->early_context, SIM_EFLI_FILEID,
 			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 			sim_efli_read_cb, sim);
-	ofono_sim_read(sim->context, SIM_EFPL_FILEID,
+	ofono_sim_add_file_watch(sim->early_context, SIM_EFLI_FILEID,
+					sim_efli_efpl_changed, sim, NULL);
+
+	ofono_sim_read(sim->early_context, SIM_EFPL_FILEID,
 			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 			sim_efpl_read_cb, sim);
+	ofono_sim_add_file_watch(sim->early_context, SIM_EFPL_FILEID,
+					sim_efli_efpl_changed, sim, NULL);
 }
 
 struct ofono_sim_context *ofono_sim_context_create(struct ofono_sim *sim)
@@ -2069,6 +2206,11 @@ static void sim_free_early_state(struct ofono_sim *sim)
 		g_strfreev(sim->language_prefs);
 		sim->language_prefs = NULL;
 	}
+
+	if (sim->early_context) {
+		ofono_sim_context_free(sim->early_context);
+		sim->early_context = NULL;
+	}
 }
 
 static void sim_free_main_state(struct ofono_sim *sim)
@@ -2092,6 +2234,7 @@ static void sim_free_main_state(struct ofono_sim *sim)
 				(GFunc)service_number_free, NULL);
 		g_slist_free(sim->service_numbers);
 		sim->service_numbers = NULL;
+		sim->sdn_ready = FALSE;
 	}
 
 	if (sim->efust) {
@@ -2118,6 +2261,8 @@ static void sim_free_main_state(struct ofono_sim *sim)
 		g_free(sim->efimg);
 		sim->efimg = NULL;
 		sim->efimg_length = 0;
+		g_free(sim->iidf_watch_ids);
+		sim->iidf_watch_ids = NULL;
 	}
 
 	g_free(sim->iidf_image);
@@ -2125,6 +2270,11 @@ static void sim_free_main_state(struct ofono_sim *sim)
 
 	sim->fixed_dialing = FALSE;
 	sim->barred_dialing = FALSE;
+
+	if (sim->context) {
+		ofono_sim_context_free(sim->context);
+		sim->context = NULL;
+	}
 }
 
 static void sim_free_state(struct ofono_sim *sim)
@@ -2304,11 +2454,6 @@ static void sim_remove(struct ofono_atom *atom)
 
 	sim_free_state(sim);
 
-	if (sim->context) {
-		ofono_sim_context_free(sim->context);
-		sim->context = NULL;
-	}
-
 	sim_fs_free(sim->simfs);
 	sim->simfs = NULL;
 
@@ -2374,7 +2519,6 @@ void ofono_sim_register(struct ofono_sim *sim)
 	ofono_modem_add_interface(modem, OFONO_SIM_MANAGER_INTERFACE);
 	sim->state_watches = __ofono_watchlist_new(g_free);
 	sim->simfs = sim_fs_new(sim, sim->driver);
-	sim->context = ofono_sim_context_create(sim);
 
 	__ofono_atom_register(sim->atom, sim_unregister);
 
-- 
1.7.1.86.g0e460.dirty


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-03-16  2:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-19  3:54 [PATCH 1/3] sim: Watch for changes to relevant SIM files Andrzej Zaborowski
2011-02-19  3:54 ` [PATCH 2/3] message-waiting: " Andrzej Zaborowski
2011-03-16  2:24   ` Denis Kenzior
2011-02-19  3:54 ` [PATCH 3/3] call-forwarding: " Andrzej Zaborowski
2011-03-16  2:25   ` Denis Kenzior
2011-03-16  2:24 ` [PATCH 1/3] sim: " Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.