Some messages have one or two length-value information elements. The is
no IE type included in the message. These information elements are
mandatory, so their actual IE type is known. The improved parse_tlv()
function allows to parse zero, one, or two length-value elements.
(Andreas Eversberg)

diff --git a/src/abis_nm.c b/src/abis_nm.c
index 6909f78..0107c29 100644
--- a/src/abis_nm.c
+++ b/src/abis_nm.c
@@ -365,7 +365,7 @@
 
 int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len)
 {
-	return tlv_parse(tp, &nm_att_tlvdef, buf, len);
+	return tlv_parse(tp, &nm_att_tlvdef, buf, len, 0, 0);
 }
 
 static int is_in_arr(enum abis_nm_msgtype mt, const enum abis_nm_msgtype *arr, int size)
diff --git a/src/abis_rsl.c b/src/abis_rsl.c
index e7f953e..753a666 100644
--- a/src/abis_rsl.c
+++ b/src/abis_rsl.c
@@ -112,7 +112,8 @@
 		[0xfc]				= { TLV_TYPE_TV },
 	},
 };
-#define rsl_tlv_parse(dec, buf, len)     tlv_parse(dec, &rsl_att_tlvdef, buf, len)
+#define rsl_tlv_parse(dec, buf, len)     \
+			tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
 
 static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
 {
diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c
index ad7bba6..849ef48 100644
--- a/src/gsm_04_08.c
+++ b/src/gsm_04_08.c
@@ -1119,7 +1119,7 @@
 	call->local_lchan = msg->lchan;
 	call->transaction_id = gh->proto_discr & 0xf0;
 
-	tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len);
+	tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
 	if (!TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD))
 		goto err;
 
diff --git a/src/tlv_parser.c b/src/tlv_parser.c
index fe6d289..e835f95 100644
--- a/src/tlv_parser.c
+++ b/src/tlv_parser.c
@@ -13,16 +13,47 @@
 	return 0;
 }
 
+/* dec:    output: a caller-allocated pointer to a struct tlv_parsed,
+ * def:     input: a structure defining the valid TLV tags / configurations
+ * buf:     input: the input data buffer to be parsed
+ * buf_len: input: the length of the input data buffer
+ * lv_tag:  input: an initial LV tag at the start of the buffer
+ * lv_tag2: input: a second initial LV tag following lv_tag 
+ */
 int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
-	      const u_int8_t *buf, int buf_len)
+	      const u_int8_t *buf, int buf_len, u_int8_t lv_tag,
+	      u_int8_t lv_tag2)
 {
 	u_int8_t tag, len = 1;
-	const u_int8_t *pos;
+	const u_int8_t *pos = buf;
 	int num_parsed = 0;
 
 	memset(dec, 0, sizeof(*dec));
 
-	for (pos = buf; pos < buf+buf_len; pos += len) {
+	if (lv_tag) {
+		if (pos > buf + buf_len)
+			return -1;
+		dec->lv[lv_tag].val = pos+1;
+		dec->lv[lv_tag].len = *pos;
+		len = dec->lv[lv_tag].len + 1;
+		if (pos + len > buf + buf_len)
+			return -2;
+		num_parsed++;
+		pos += len;
+	}
+	if (lv_tag2) {
+		if (pos > buf + buf_len)
+			return -1;
+		dec->lv[lv_tag2].val = pos+1;
+		dec->lv[lv_tag2].len = *pos;
+		len = dec->lv[lv_tag2].len + 1;
+		if (pos + len > buf + buf_len)
+			return -2;
+		num_parsed++;
+		pos += len;
+	}
+
+	for (; pos < buf+buf_len; pos += len) {
 		tag = *pos;
 		/* FIXME: use tables for knwon IEI */
 		switch (def->def[tag].type) {