All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Parse SIM alpha fields (EF-SPN) according to TS 11.11.
@ 2009-07-05  3:14 Andrzej Zaborowski
  2009-07-07  0:42 ` Denis Kenzior
  0 siblings, 1 reply; 4+ messages in thread
From: Andrzej Zaborowski @ 2009-07-05  3:14 UTC (permalink / raw)
  To: ofono

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

---
 src/sim.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 114 insertions(+), 5 deletions(-)

diff --git a/src/sim.c b/src/sim.c
index 8485e1e..a5d2164 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -199,6 +199,115 @@ static GDBusMethodTable sim_manager_methods[] = {
 
 static GDBusSignalTable sim_manager_signals[] = { { } };
 
+static char *sim_alpha_field_parse(const unsigned char *buffer, int length)
+{
+	long utf_len, char_len;
+	unsigned char str[2];
+	int i;
+	char *r, *ret;
+
+	if (length < 1)
+		return NULL;
+
+	if (buffer[0] < 0x80)
+		return convert_gsm_to_utf8(buffer, length, NULL, NULL, 0xff);
+	switch (buffer[0]) {
+	case 0x80:
+		if (length < 2)
+			return NULL;
+
+		return convert_ucs2_to_utf8(buffer + 1, length - 1,
+				NULL, NULL, 0xffff);
+
+	case 0x81:
+		if (length < 4 || buffer[1] == 0 || buffer[1] > length - 3)
+			return NULL;
+
+		length = buffer[1];
+		utf_len = 0;
+		for (i = 0; i < length; i ++) {
+			if (buffer[3 + i] & 0x80) {
+				str[0] = (buffer[2] >> 1);
+				str[1] = (buffer[2] << 7) |
+					(buffer[3 + i] & 0x7f);
+				r = convert_ucs2_to_utf8(str, 2,
+						NULL, &char_len, 0xffff);
+			} else
+				r = convert_gsm_to_utf8(&buffer[3 + i], 1,
+						NULL, &char_len, 0xff);
+
+			if (!r)
+				break;
+			g_free(r);
+			utf_len += char_len;
+		}
+
+		ret = g_malloc(utf_len + 1);
+
+		for (i = 0; i < length; i ++) {
+			if (buffer[3 + i] & 0x80) {
+				str[0] = (buffer[2] >> 1);
+				str[1] = (buffer[2] << 7) |
+					(buffer[3 + i] & 0x7f);
+				r = convert_ucs2_to_utf8(str, 2,
+						NULL, &char_len, 0xffff);
+			} else
+				r = convert_gsm_to_utf8(&buffer[3 + i], 1,
+						NULL, &char_len, 0xff);
+
+			memcpy(ret + utf_len, r, char_len);
+			g_free(r);
+			utf_len += char_len;
+		}
+		ret[utf_len] = 0;
+
+		return ret;
+
+	case 0x82:
+		if (length < 5 || buffer[1] == 0 || buffer[1] > length - 4)
+			return NULL;
+
+		length = buffer[1];
+		for (i = 0; i < length; i ++) {
+			if (buffer[4 + i] & 0x80) {
+				str[0] = buffer[2];
+				str[1] = buffer[3] + (buffer[4 + i] & 0x7f);
+				r = convert_ucs2_to_utf8(str, 2,
+						NULL, &char_len, 0xffff);
+			} else
+				r = convert_gsm_to_utf8(&buffer[4 + i], 1,
+						NULL, &char_len, 0xff);
+
+			if (!r)
+				break;
+			g_free(r);
+			utf_len += char_len;
+		}
+
+		ret = g_malloc(utf_len + 1);
+
+		for (i = 0; i < length; i ++) {
+			if (buffer[4 + i] & 0x80) {
+				str[0] = buffer[2];
+				str[1] = buffer[3] + (buffer[4 + i] & 0x7f);
+				r = convert_ucs2_to_utf8(str, 2,
+						NULL, &char_len, 0xffff);
+			} else
+				r = convert_gsm_to_utf8(&buffer[4 + i], 1,
+						NULL, &char_len, 0xff);
+
+			memcpy(ret + utf_len, r, char_len);
+			g_free(r);
+			utf_len += char_len;
+		}
+		ret[utf_len] = 0;
+
+		return ret;
+	}
+
+	return NULL;
+}
+
 enum sim_fileids {
 	SIM_EFMSISDN_FILEID = 0x6f40,
 	SIM_EFSPN_FILEID = 0x6f46,
@@ -237,9 +346,7 @@ static void sim_spn_read_cb(const struct ofono_error *error,
 	if (endp)
 		length = endp - sdata;
 
-	/*
-	 * The specification has this to say about the encoding of SPN:
-	 * Coding:
+	/* TS 31.102 says:
 	 *
 	 * the string shall use:
 	 *
@@ -250,9 +357,11 @@ static void sim_spn_read_cb(const struct ofono_error *error,
 	 * - or one of the UCS2 code options defined in the annex of TS
 	 *   31.101 [11].
 	 *
-	 * Assume the first option.
+	 * 31.101 has no such annex though.  51.101 refers to Annex B of
+	 * itself which is not there either.  11.11 contains the same
+	 * paragraph as 51.101 and has an Annex B which we implement.
 	 */
-	sim->spn = convert_gsm_to_utf8(sdata, length, NULL, NULL, 0xff);
+	sim->spn = sim_alpha_field_parse(sdata, length);
 
 	for (l = sim->update_spn_notify; l; l = l->next)
 		sim_spn_notify(modem, l->data);
-- 
1.6.0


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

end of thread, other threads:[~2009-07-07 19:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-05  3:14 [PATCH] Parse SIM alpha fields (EF-SPN) according to TS 11.11 Andrzej Zaborowski
2009-07-07  0:42 ` Denis Kenzior
2009-07-07 13:04   ` Andrzej Zaborowski
2009-07-07 19:37     ` 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.