[PATCH 3/8] Add STK-specific CTLV encoding utilities.

Andrzej Zaborowski andrew.zaborowski at intel.com
Mon May 10 02:33:58 PDT 2010


---
 src/stkutil.c |  155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 155 insertions(+), 0 deletions(-)

diff --git a/src/stkutil.c b/src/stkutil.c
index 50fa4c1..e51090c 100644
--- a/src/stkutil.c
+++ b/src/stkutil.c
@@ -2343,3 +2343,158 @@ void stk_command_free(struct stk_command *command)
 
 	g_free(command);
 }
+
+struct stk_tlv_builder {
+	struct comprehension_tlv_builder ctlv;
+	unsigned char *value;
+	int len;
+};
+
+static inline void stk_tlv_builder_init(struct stk_tlv_builder *iter,
+					unsigned char *pdu, unsigned int size)
+{
+	comprehension_tlv_builder_init(&iter->ctlv, pdu, size);
+	iter->value = NULL;
+}
+
+static inline gboolean stk_tlv_open_container(struct stk_tlv_builder *iter,
+						gboolean cr,
+						unsigned char shorttag,
+						gboolean relocatable)
+{
+	comprehension_tlv_builder_set_tag(&iter->ctlv, cr, shorttag);
+	comprehension_tlv_builder_set_length(&iter->ctlv,
+						relocatable ? 0xff : 0x7f);
+	iter->len = 0;
+	iter->value = comprehension_tlv_builder_get_data(&iter->ctlv);
+
+	return TRUE;
+}
+
+static inline gboolean stk_tlv_close_container(struct stk_tlv_builder *iter)
+{
+	return comprehension_tlv_builder_set_length(&iter->ctlv, iter->len) &&
+		comprehension_tlv_builder_next(&iter->ctlv);
+}
+
+static inline unsigned int stk_tlv_get_length(struct stk_tlv_builder *iter)
+{
+	return iter->ctlv.pos;
+}
+
+static inline void stk_tlv_append_byte(struct stk_tlv_builder *iter,
+					unsigned char num)
+{
+	iter->value[iter->len++] = num;
+}
+
+static inline void stk_tlv_append_short(struct stk_tlv_builder *iter,
+					unsigned short num)
+{
+	iter->value[iter->len++] = num >> 8;
+	iter->value[iter->len++] = num & 0xff;
+}
+
+static inline gboolean stk_tlv_append_text(struct stk_tlv_builder *iter,
+						int dcs, const char *text)
+{
+	unsigned int len;
+	unsigned char *gsm, *ucs2;
+	long written = 0;
+	gsize gwritten;
+
+	if (text == NULL)
+		return TRUE;
+
+	len = strlen(text);
+
+	switch (dcs) {
+	case 0x00:
+		gsm = convert_utf8_to_gsm(text, len, NULL, NULL, 0);
+		if (gsm == NULL && len > 0)
+			return FALSE;
+
+		iter->value[iter->len++] = 0x00;
+
+		pack_7bit_own_buf(gsm, len, 0, FALSE, &written, 0,
+					iter->value + iter->len);
+		g_free(gsm);
+		if (written < 1 && len > 0)
+			return FALSE;
+		iter->len += written;
+
+		return TRUE;
+	case 0x04:
+		gsm = convert_utf8_to_gsm(text, len, NULL, &written, 0);
+		if (gsm == NULL && len > 0)
+			return FALSE;
+
+		iter->value[iter->len++] = 0x04;
+
+		memcpy(iter->value + iter->len, gsm, written);
+		iter->len += written;
+
+		g_free(gsm);
+
+		return TRUE;
+	case 0x08:
+		ucs2 = (unsigned char *) g_convert((const gchar *) text, len,
+					"UCS-2BE", "UTF-8//TRANSLIT",
+					NULL, &gwritten, NULL);
+		if (ucs2 == NULL)
+			return FALSE;
+
+		iter->value[iter->len++] = 0x08;
+
+		memcpy(iter->value + iter->len, ucs2, gwritten);
+		iter->len += gwritten;
+
+		g_free(ucs2);
+
+		return TRUE;
+	case -1:
+		/* Fake DCS to mean unpacked GSM alphabet if possible
+		 * to encode the string and UCS2 if not.  */
+		gsm = convert_utf8_to_gsm(text, len, NULL, &written, 0);
+
+		if (gsm == NULL && len > 0) {
+			/* Use UCS2. */
+			ucs2 = (unsigned char *) g_convert(
+					(const gchar *) text, len,
+					"UCS-2BE", "UTF-8//TRANSLIT",
+					NULL, &gwritten, NULL);
+			if (ucs2 == NULL)
+				return FALSE;
+
+			iter->value[iter->len++] = 0x08;
+
+			memcpy(iter->value + iter->len, ucs2, gwritten);
+			iter->len += gwritten;
+
+			g_free(ucs2);
+
+			return TRUE;
+		}
+
+		iter->value[iter->len++] = 0x04;
+
+		memcpy(iter->value + iter->len, gsm, written);
+		iter->len += written;
+
+		g_free(gsm);
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static inline gboolean stk_tlv_append_bytes(struct stk_tlv_builder *iter,
+						const unsigned char *data,
+						unsigned int length)
+{
+	memcpy(iter->value + iter->len, data, length);
+	iter->len += length;
+
+	return TRUE;
+}
-- 
1.6.1



More information about the ofono mailing list