2009/9/14 Andrzej Zaborowski <[email protected]>:
> 2009/9/14 Denis Kenzior <[email protected]>:
>>> +     /* According to 31.102 the EFli is read first and EFpl is then
>>> +      * only read if none of the EFli languages are supported by user
>>> +      * interface.  51.011 mandates the exact opposite, making EFpl/EFelp
>>> +      * preferred over EFlp (same ID as EFli, different format).
>>> +      * However we don't depend on the user interface and so
>>> +      * need to read both files now.
>>> +      */
>>> +     ofono_sim_read(sim, SIM_EFLI_FILEID, sim_efli_read_cb, sim);
>>> +     ofono_sim_read(sim, SIM_EFPL_FILEID, sim_efpl_read_cb, sim);
>>
>> Strictly speaking 31.101 & 31.102 supersede 51.011.
>
> I think that was the plan but apparently they don't have all contents
> 51.011 has, and 31.102 even explicitely refers to 51.011 for the EFpl
> format (which 51.011 only says is defined by ETSI).
>
> Also the card I tested has a 5 byte EFli / EFlp, filled with 0xff
> bytes, which means it must be in the 51.011 format so the document is
> not obsolete.

So here's another version generated on top of HEAD and with an attempt
to detect when the card uses EFlp format instead of EFli.

Regards
From 763a0b12a6636d7f1ec5be99d8fe24c5925c6678 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <[email protected]>
Date: Mon, 14 Sep 2009 21:25:05 +0200
Subject: [PATCH] Present list of preferred languages on SimManager interface.

Patch made on top of [PATCH] Do the PIN check in SIMManager.
---
 src/sim.c     |  124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/simutil.h |    2 +
 2 files changed, 126 insertions(+), 0 deletions(-)

diff --git a/src/sim.c b/src/sim.c
index 3886485..7a42ee7 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -80,10 +80,13 @@ struct ofono_sim {
 	gboolean ready;
 	gboolean pin_ready;
 	int pin_type;
+	char **language_prefs;
 	GQueue *simop_q;
 	gint simop_source;
 	unsigned char efmsisdn_length;
 	unsigned char efmsisdn_records;
+	unsigned char *efli;
+	unsigned char efli_length;
 	unsigned int next_ready_watch_id;
 	GSList *ready_watches;
 	const struct ofono_sim_driver *driver;
@@ -224,6 +227,11 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
 					(void *) &pin_name);
 	}
 
+	if (sim->language_prefs)
+		ofono_dbus_dict_append_array(&dict, "PreferredLanguages",
+						DBUS_TYPE_STRING,
+						&sim->language_prefs);
+
 	dbus_message_iter_close_container(&iter, &dict);
 
 	return reply;
@@ -746,6 +754,116 @@ static void sim_pin_check(struct ofono_sim *sim)
 	sim->driver->query_passwd_state(sim, sim_pin_query_cb, sim);
 }
 
+static void sim_efli_read_cb(int ok,
+				enum ofono_sim_file_structure structure,
+				int length, int record,
+				const unsigned char *data,
+				int record_length, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+
+	if (!ok || structure != OFONO_SIM_FILE_STRUCTURE_TRANSPARENT)
+		return;
+
+	if (length < 2)
+		return;
+
+	sim->efli = g_memdup(data, length);
+	sim->efli_length = length;
+}
+
+static void parse_language_list(char **out_list, int *count,
+				const unsigned char *sim_list, int length)
+{
+	int i, j;
+
+	length--;
+
+	for (i = 0; i < length; i += 2) {
+		if (sim_list[i] == 0xff || sim_list[i + 1] == 0xff)
+			continue;
+
+		for (j = 0; j < *count; j++)
+			if (!memcmp(out_list[j], sim_list + i, 2))
+				break;
+		if (j < *count)
+			continue;
+
+		/* ISO 639 codes contain only characters that are coded
+		 * identically in SMS 7 bit charset, ASCII or UTF8 so
+		 * no conversion.
+		 */
+		out_list[(*count)++] = g_strndup((char *) sim_list + i, 2);
+	}
+}
+
+static void sim_efpl_read_cb(int ok,
+				enum ofono_sim_file_structure structure,
+				int length, int record,
+				const unsigned char *data,
+				int record_length, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+	unsigned char *efli = sim->efli;
+	const unsigned char *efpl = data;
+	int efli_length = sim->efli_length;
+	int efpl_length = length;
+	int count;
+	const char *path = __ofono_atom_get_path(sim->atom);
+	DBusConnection *conn = ofono_dbus_get_connection();
+
+	if (!ok || structure != OFONO_SIM_FILE_STRUCTURE_TRANSPARENT)
+		efpl = NULL;
+
+	if (length < 2)
+		efpl = NULL;
+
+	sim->language_prefs = g_new0(char *,
+					(efli_length + efpl_length) / 2 + 1);
+
+	count = 0;
+
+	/* Make a list of languages in both files in order of preferences
+	 * following 31.102.
+	 */
+
+	if (efli && efpl && efli[0] == 0xff && efli[1] == 0xff) {
+		parse_language_list(sim->language_prefs, &count,
+					efpl, efpl_length);
+		efpl = NULL;
+	}
+
+	if (efli) {
+		parse_language_list(sim->language_prefs, &count,
+					efli, efli_length);
+		g_free(efli);
+		sim->efli = NULL;
+	}
+
+	if (efpl)
+		parse_language_list(sim->language_prefs, &count,
+					efpl, efpl_length);
+
+	ofono_dbus_signal_array_property_changed(conn, path,
+							SIM_MANAGER_INTERFACE,
+							"PreferredLanguages",
+							DBUS_TYPE_STRING,
+							&sim->language_prefs);
+}
+
+static void sim_retrieve_efli(struct ofono_sim *sim)
+{
+	/* According to 31.102 the EFli is read first and EFpl is then
+	 * only read if none of the EFli languages are supported by user
+	 * interface.  51.011 mandates the exact opposite, making EFpl/EFelp
+	 * preferred over EFlp (same ID as EFli, different format).
+	 * However we don't depend on the user interface and so
+	 * need to read both files now.
+	 */
+	ofono_sim_read(sim, SIM_EFLI_FILEID, sim_efli_read_cb, sim);
+	ofono_sim_read(sim, SIM_EFPL_FILEID, sim_efpl_read_cb, sim);
+}
+
 static void sim_op_error(struct ofono_sim *sim)
 {
 	struct sim_file_op *op = g_queue_pop_head(sim->simop_q);
@@ -1357,6 +1475,11 @@ static void sim_remove(struct ofono_atom *atom)
 		sim->service_numbers = NULL;
 	}
 
+	if (sim->language_prefs) {
+		g_strfreev(sim->language_prefs);
+		sim->language_prefs = NULL;
+	}
+
 	if (sim->simop_source) {
 		g_source_remove(sim->simop_source);
 		sim->simop_source = 0;
@@ -1446,6 +1569,7 @@ void ofono_sim_register(struct ofono_sim *sim)
 	 * arbitrary files to be written or read, assuming their presence
 	 * in the EFust
 	 */
+	sim_retrieve_efli(sim);
 	sim_pin_check(sim);
 }
 
diff --git a/src/simutil.h b/src/simutil.h
index fc4f063..d1517ed 100644
--- a/src/simutil.h
+++ b/src/simutil.h
@@ -20,6 +20,8 @@
  */
 
 enum sim_fileid {
+	SIM_EFPL_FILEID = 0x2f05,
+	SIM_EFLI_FILEID = 0x6f05,
 	SIM_EFMSISDN_FILEID = 0x6f40,
 	SIM_EFSPN_FILEID = 0x6f46,
 	SIM_EFSDN_FILEID = 0x6f49,
-- 
1.6.1

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to