Open Source Telephony
 help / color / mirror / Atom feed
From: Yang Gu <yang.gu@intel.com>
To: ofono@ofono.org
Subject: [PATCH 04/13] Break out stk_file iterator to parse file list objects
Date: Tue, 06 Apr 2010 18:06:38 +0800	[thread overview]
Message-ID: <1270548407-12042-4-git-send-email-yang.gu@intel.com> (raw)
In-Reply-To: <1270548407-12042-3-git-send-email-yang.gu@intel.com>

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

---
 src/stkutil.c |  166 +++++++++++++++++++++++++++++++++------------------------
 1 files changed, 97 insertions(+), 69 deletions(-)

diff --git a/src/stkutil.c b/src/stkutil.c
index c249a3a..8b53e6d 100644
--- a/src/stkutil.c
+++ b/src/stkutil.c
@@ -39,6 +39,14 @@ enum stk_data_object_flag {
 	DATAOBJ_FLAG_MINIMUM = 2
 };
 
+struct stk_file_iter {
+	const unsigned char *start;
+	unsigned int pos;
+	unsigned int max;
+	unsigned char len;
+	const unsigned char *file;
+};
+
 typedef gboolean (*dataobj_handler)(struct comprehension_tlv_iter *, void *);
 
 /*
@@ -157,6 +165,86 @@ static gboolean parse_dataobj_common_byte_array(
 	return TRUE;
 }
 
+static void stk_file_iter_init(struct stk_file_iter *iter,
+				const unsigned char *start, unsigned int len)
+{
+	iter->start = start;
+	iter->max = len;
+	iter->pos = 0;
+}
+
+static gboolean stk_file_iter_next(struct stk_file_iter *iter)
+{
+	unsigned int pos = iter->pos;
+	const unsigned int max = iter->max;
+	const unsigned char *start = iter->start;
+	unsigned int i;
+	unsigned char last_type;
+
+	/* SIM EFs always start with ROOT MF, 0x3f */
+	if (start[iter->pos] != 0x3f)
+		return FALSE;
+
+	if (pos + 2 >= max)
+		return FALSE;
+
+	last_type = 0x3f;
+
+	for (i = pos + 2; i < max; i += 2) {
+		/*
+		 * Check the validity of file type.
+		 * According to TS 11.11, each file id contains of two bytes,
+		 * in which the first byte is the type of file. For GSM is:
+		 * 0x3f: master file
+		 * 0x7f: 1st level dedicated file
+		 * 0x5f: 2nd level dedicated file
+		 * 0x2f: elementary file under the master file
+		 * 0x6f: elementary file under 1st level dedicated file
+		 * 0x4f: elementary file under 2nd level dedicated file
+		 */
+		switch (start[i]) {
+		case 0x2f:
+			if (last_type != 0x3f)
+				return FALSE;
+			break;
+		case 0x6f:
+			if (last_type != 0x7f)
+				return FALSE;
+			break;
+		case 0x4f:
+			if (last_type != 0x5f)
+				return FALSE;
+			break;
+		case 0x7f:
+			if (last_type != 0x3f)
+				return FALSE;
+			break;
+		case 0x5f:
+			if (last_type != 0x7f)
+				return FALSE;
+			break;
+		default:
+			return FALSE;
+		}
+
+		if ((start[i] == 0x2f) || (start[i] == 0x6f) ||
+						(start[i] == 0x4f)) {
+			if (i + 1 >= max)
+				return FALSE;
+
+			iter->file = start + pos;
+			iter->len = i - pos + 2;
+			iter->pos = i + 2;
+
+			return TRUE;
+		}
+
+		last_type = start[i];
+	}
+
+	return FALSE;
+}
+
 /* Defined in TS 102.223 Section 8.1 */
 static gboolean parse_dataobj_address(struct comprehension_tlv_iter *iter,
 					void *user)
@@ -443,10 +531,8 @@ static gboolean parse_dataobj_file_list(struct comprehension_tlv_iter *iter,
 	GSList **fl = user;
 	const unsigned char *data;
 	unsigned int len;
-	unsigned int i;
-	unsigned int start;
 	struct stk_file *sf;
-	unsigned char last_type;
+	struct stk_file_iter sf_iter;
 
 	len = comprehension_tlv_iter_get_length(iter);
 	if (len < 5)
@@ -454,77 +540,19 @@ static gboolean parse_dataobj_file_list(struct comprehension_tlv_iter *iter,
 
 	data = comprehension_tlv_iter_get_data(iter);
 
-	/* SIM EFs always start with ROOT MF, 0x3f */
-	if (data[1] != 0x3f)
-		return FALSE;
-
-	start = 1;
-	last_type = 0x3f;
-
-	for (i = 3; i < len; i += 2) {
-		/*
-		 * Check the validity of file type.
-		 * According to TS 11.11, each file id contains of two bytes,
-		 * in which the first byte is the type of file. For GSM is:
-		 * 0x3f: master file
-		 * 0x7f: 1st level dedicated file
-		 * 0x5f: 2nd level dedicated file
-		 * 0x2f: elementary file under the master file
-		 * 0x6f: elementary file under 1st level dedicated file
-		 * 0x4f: elementary file under 2nd level dedicated file
-		 */
-		switch (data[i]) {
-		case 0x3f:
-			if ((last_type != 0x2f) && (last_type != 0x6f) &&
-					(last_type != 0x4f))
-				goto error;
-
-			start = i;
+	stk_file_iter_init(&sf_iter, data + 1, len - 1);
 
-			break;
-		case 0x2f:
-			if (last_type != 0x3f)
-				goto error;
-			break;
-		case 0x6f:
-			if (last_type != 0x7f)
-				goto error;
-			break;
-		case 0x4f:
-			if (last_type != 0x5f)
-				goto error;
-			break;
-		case 0x7f:
-			if (last_type != 0x3f)
-				goto error;
-			break;
-		case 0x5f:
-			if (last_type != 0x7f)
-				goto error;
-			break;
-		default:
+	while (stk_file_iter_next(&sf_iter)) {
+		sf = g_try_new0(struct stk_file, 1);
+		if (sf == NULL)
 			goto error;
-		}
-
-		if ((data[i] == 0x2f) || (data[i] == 0x6f) ||
-						(data[i] == 0x4f)) {
-			if (i + 1 >= len)
-				goto error;
-
-			sf = g_try_new0(struct stk_file, 1);
-			if (sf == NULL)
-				goto error;
-
-			sf->len = i - start + 2;
-			memcpy(sf->file, data + start, i - start + 2);
-			*fl = g_slist_prepend(*fl, sf);
-		}
 
-		last_type = data[i];
+		sf->len = sf_iter.len;
+		memcpy(sf->file, sf_iter.file, sf_iter.len);
+		*fl = g_slist_prepend(*fl, sf);
 	}
 
-	if ((data[len - 2] != 0x2f) && (data[len - 2] != 0x6f) &&
-						(data[len - 2] != 0x4f))
+	if (sf_iter.pos != sf_iter.max)
 		goto error;
 
 	*fl = g_slist_reverse(*fl);
-- 
1.6.3.3


  reply	other threads:[~2010-04-06 10:06 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-06 10:06 [PATCH 01/13] Fix the logic when parsing c-apdu objects Yang Gu
2010-04-06 10:06 ` [PATCH 02/13] Add parser for url objects Yang Gu
2010-04-06 10:06   ` [PATCH 03/13] Add parser for bearer objects Yang Gu
2010-04-06 10:06     ` Yang Gu [this message]
2010-04-06 10:06       ` [PATCH 05/13] Add parser for provisioning file reference objects Yang Gu
2010-04-06 10:06         ` [PATCH 06/13] Add parser for browser termination cause objects Yang Gu
2010-04-06 10:06           ` [PATCH 07/13] Add parser for bearer description objects Yang Gu
2010-04-06 10:06             ` [PATCH 08/13] Add parser for channel data objects Yang Gu
2010-04-06 10:06               ` [PATCH 09/13] Add parser for channel data length objects Yang Gu
2010-04-06 10:06                 ` [PATCH 10/13] Add parser for buffer size objects Yang Gu
2010-04-06 10:06                   ` [PATCH 11/13] Add parser for channel status objects Yang Gu
2010-04-06 10:06                     ` [PATCH 12/13] Add parser for card reader identifier objects Yang Gu
2010-04-06 10:06                       ` [PATCH 13/13] Add parser for other address objects Yang Gu
2010-04-14 18:13 ` [PATCH 01/13] Fix the logic when parsing c-apdu objects Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1270548407-12042-4-git-send-email-yang.gu@intel.com \
    --to=yang.gu@intel.com \
    --cc=ofono@ofono.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox