[PATCH 4/8] Encoding of the four TERMINAL RESPONSE pdus.

Andrzej Zaborowski andrew.zaborowski at intel.com
Mon May 10 02:34:09 PDT 2010


---
 src/stkutil.c |  171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/stkutil.h |   45 +++++++++++++++
 2 files changed, 216 insertions(+), 0 deletions(-)

diff --git a/src/stkutil.c b/src/stkutil.c
index e51090c..1205f40 100644
--- a/src/stkutil.c
+++ b/src/stkutil.c
@@ -2498,3 +2498,174 @@ static inline gboolean stk_tlv_append_bytes(struct stk_tlv_builder *iter,
 
 	return TRUE;
 }
+
+/* Described in TS 102.223 Section 8.8 */
+static gboolean build_dataobj_duration(struct stk_tlv_builder *tlv,
+					const void *data)
+{
+	const struct stk_duration *duration = data;
+
+	if (duration->interval == 0x00)
+		return TRUE;
+
+	if (stk_tlv_open_container(tlv, FALSE, STK_DATA_OBJECT_TYPE_DURATION,
+					FALSE) != TRUE)
+		return FALSE;
+
+	stk_tlv_append_byte(tlv, duration->unit);
+	stk_tlv_append_byte(tlv, duration->interval);
+
+	return stk_tlv_close_container(tlv);
+}
+
+/* Described in TS 102.223 Section 8.12 */
+static gboolean build_dataobj_result(struct stk_tlv_builder *tlv,
+					const void *data)
+{
+	const struct stk_result *result = data;
+
+	if (stk_tlv_open_container(tlv, TRUE, STK_DATA_OBJECT_TYPE_RESULT,
+					FALSE) != TRUE)
+		return FALSE;
+
+	stk_tlv_append_byte(tlv, result->type);
+	if (result->additional_len)
+		if (stk_tlv_append_bytes(tlv, result->additional,
+						result->additional_len) !=
+				TRUE)
+			return FALSE;
+
+	return stk_tlv_close_container(tlv);
+}
+
+/* Defined in TS 102.223 Section 8.15 */
+static gboolean build_dataobj_text(struct stk_tlv_builder *tlv,
+					const void *data)
+{
+	const struct stk_answer_text *text = data;
+
+	if (!text->text && !text->yesno)
+		return TRUE;
+
+	/* See note about CR in stk_pdu_from_response */
+	if (stk_tlv_open_container(tlv, TRUE, STK_DATA_OBJECT_TYPE_TEXT,
+					TRUE) != TRUE)
+		return FALSE;
+
+	if (text->yesno == TRUE) {
+		/* Section 6.8.5:
+		 * When the terminal issues [...] command qualifier set
+		 * to "Yes/No", it shall supply the value "01" when the
+		 * answer is "positive" and the value '00' when the
+		 * answer is "negative" in the text string data object.
+		 */
+		stk_tlv_append_byte(tlv, 0x04);
+		stk_tlv_append_byte(tlv, text->text ? 0x01 : 0x00);
+	} else if (text->packed) {
+		if (stk_tlv_append_text(tlv, 0x00, text->text) != TRUE)
+			return FALSE;
+	} else {
+		if (stk_tlv_append_text(tlv, -1, text->text) != TRUE)
+			return FALSE;
+	}
+	return stk_tlv_close_container(tlv);
+}
+
+static gboolean build_dataobj(struct stk_tlv_builder *tlv, gboolean
+				(*builder_func)(struct stk_tlv_builder *,
+						const void *), ...)
+{
+	va_list args;
+
+	va_start(args, builder_func);
+
+	while (builder_func) {
+		const void *data = va_arg(args, const void *);
+
+		if (builder_func(tlv, data) != TRUE)
+			return FALSE;
+
+		builder_func = va_arg(args, gboolean (*)(
+						struct stk_tlv_builder *,
+						const void *));
+	}
+
+	return TRUE;
+}
+
+unsigned int stk_pdu_from_response(const struct stk_response *response,
+					unsigned char *pdu, unsigned int size)
+{
+	struct stk_tlv_builder builder;
+	gboolean ok = TRUE;
+
+	stk_tlv_builder_init(&builder, pdu, size);
+
+	/*
+	 * Encode command details, they come in order with
+	 * Command Details TLV first, followed by Device Identities TLV
+	 * and the Result TLV.  Comprehension required everywhere.
+	 */
+	if (stk_tlv_open_container(&builder, TRUE,
+					STK_DATA_OBJECT_TYPE_COMMAND_DETAILS,
+					FALSE) != TRUE)
+		return 0;
+
+	stk_tlv_append_byte(&builder, response->number);
+	stk_tlv_append_byte(&builder, response->type);
+	stk_tlv_append_byte(&builder, response->qualifier);
+
+	if (stk_tlv_close_container(&builder) != TRUE)
+		return 0;
+
+	/* TS 102 223 section 6.8 states:
+	 * "For all COMPREHENSION-TLV objects with Min = N, the terminal
+	 * should set the CR flag to comprehension not required."
+	 * All the data objects except "Command Details" and "Result" have
+	 * Min = N.
+	 *
+	 * However comprehension required is set for all of the TLVs in
+	 * TS 102 384 conformace tests so we set it everywhere too.
+	 */
+	if (stk_tlv_open_container(&builder, TRUE,
+					STK_DATA_OBJECT_TYPE_DEVICE_IDENTITIES,
+					FALSE) != TRUE)
+		return 0;
+
+	stk_tlv_append_byte(&builder, response->src);
+	stk_tlv_append_byte(&builder, response->dst);
+
+	if (stk_tlv_close_container(&builder) != TRUE)
+		return 0;
+
+	if (build_dataobj_result(&builder, &response->result) != TRUE)
+		return 0;
+
+	switch (response->type) {
+	case STK_COMMAND_TYPE_DISPLAY_TEXT:
+		break;
+	case STK_COMMAND_TYPE_GET_INKEY:
+		ok = build_dataobj(&builder,
+					build_dataobj_text,
+					&response->get_inkey.text,
+					build_dataobj_duration,
+					&response->get_inkey.duration,
+					NULL);
+		break;
+	case STK_COMMAND_TYPE_GET_INPUT:
+		ok = build_dataobj(&builder,
+					build_dataobj_text,
+					&response->get_input.text,
+					NULL);
+		break;
+	case STK_COMMAND_TYPE_SEND_SMS:
+		break;
+	default:
+		return 0;
+	};
+
+	if (ok != TRUE)
+		return 0;
+
+	return stk_tlv_get_length(&builder);
+}
diff --git a/src/stkutil.h b/src/stkutil.h
index 41c03a7..6879909 100644
--- a/src/stkutil.h
+++ b/src/stkutil.h
@@ -841,6 +841,51 @@ struct stk_command {
 	void (*destructor)(struct stk_command *command);
 };
 
+/* TERMINAL RESPONSEs defined in TS 102.223 Section 6.8 */
+struct stk_response_generic {
+};
+
+struct stk_answer_text {
+	char *text;
+	ofono_bool_t packed;
+	ofono_bool_t yesno;
+	/* If a "Yes/No" answer was requested in a GET INKEY command,
+	 * .yesno must be TRUE and text should be non-NULL to indicate
+	 * a Yes response or NULL to indicate a No response.
+	 */
+};
+
+struct stk_response_get_inkey {
+	struct stk_answer_text text;
+	struct stk_duration duration;
+};
+
+struct stk_response_get_input {
+	struct stk_answer_text text;
+};
+
+struct stk_response {
+	unsigned char number;
+	unsigned char type;
+	unsigned char qualifier;
+	enum stk_device_identity_type src;
+	enum stk_device_identity_type dst;
+	struct stk_result result;
+
+	union {
+		struct stk_response_generic display_text;
+		struct stk_response_get_inkey get_inkey;
+		struct stk_response_get_input get_input;
+		struct stk_response_generic send_sms;
+	};
+
+	void (*destructor)(struct stk_response *response);
+};
+
 struct stk_command *stk_command_new_from_pdu(const unsigned char *pdu,
 						unsigned int len);
 void stk_command_free(struct stk_command *command);
+
+/* Returns # of bytes written or zero on error */
+unsigned int stk_pdu_from_response(const struct stk_response *response,
+					unsigned char *pdu, unsigned int size);
-- 
1.6.1



More information about the ofono mailing list