[TLV] extend TLV parser with support for TvLV

Tag-variableLength-Value is an encoding scheme used in the GPRS NS
and BSSGP protocols, where the length value can be 8 or 16 bits,
depending on actual demand.
diff --git a/openbsc/src/tlv_parser.c b/openbsc/src/tlv_parser.c
index e835f95..8321b88 100644
--- a/openbsc/src/tlv_parser.c
+++ b/openbsc/src/tlv_parser.c
@@ -1,5 +1,8 @@
 #include <stdio.h>
 #include <openbsc/tlv.h>
+#include <openbsc/gsm_data.h>
+
+struct tlv_definition tvlv_att_def;
 
 int tlv_dump(struct tlv_parsed *dec)
 {
@@ -87,6 +90,20 @@
 				return -2;
 			num_parsed++;
 			break;
+		case TLV_TYPE_TvLV:
+			if (*(pos+1) & 0x80) {
+				/* like TLV, but without highest bit of len */
+				if (pos + 1 > buf + buf_len)
+					return -1;
+				dec->lv[tag].val = pos+2;
+				dec->lv[tag].len = *(pos+1) & 0x7f;
+				len = dec->lv[tag].len + 2;
+				if (pos + len > buf + buf_len)
+					return -2;
+				num_parsed++;
+				break;
+			}
+			/* like TL16V, fallthrough */
 		case TLV_TYPE_TL16V:
 			if (pos + 2 > buf + buf_len)
 				return -1;
@@ -103,3 +120,9 @@
 	return num_parsed;
 }
 
+static __attribute__((constructor)) void on_dso_load_tlv(void)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++)
+		tvlv_att_def.def[i].type = TLV_TYPE_TvLV;
+}