TLV: add new "vTvLV" type for GAN

This new TLV type is specific to TS 44.318.  Contrary to the TvLV type
of TS 08.16/08.18, it has an inverted meaning of the extension (0x80)
bit:
	* if the extension bit is not set, 1-byte length
	* if the extension bit is set, 2-byte length

Futhermore, it has support for variable-length tags, where the tag part
can be optionally two bytes in length.  As this esoteric option hasn't
been seen in the wild yet, we only add encoding support but skip
decoding for now.
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 9ef5ccd..3373888 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -227,6 +227,7 @@
 tlv_parse;
 tlv_parse_one;
 tvlv_att_def;
+vtvlv_gan_att_def;
 
 gan_msgt_vals;
 gan_pdisc_vals;
diff --git a/src/gsm/tlv_parser.c b/src/gsm/tlv_parser.c
index 0ac9092..d18a6bf 100644
--- a/src/gsm/tlv_parser.c
+++ b/src/gsm/tlv_parser.c
@@ -9,6 +9,7 @@
 /*! \file tlv.c */
 
 struct tlv_definition tvlv_att_def;
+struct tlv_definition vtvlv_gan_att_def;
 
 /*! \brief Dump pasred TLV structure to stdout */
 int tlv_dump(struct tlv_parsed *dec)
@@ -69,7 +70,7 @@
 		len = def->def[tag].fixed_len + 1;
 		break;
 	case TLV_TYPE_TLV:
-		/* GSM TS 04.07 11.2.4: Type 4 TLV */
+tlv:		/* GSM TS 04.07 11.2.4: Type 4 TLV */
 		if (buf + 1 > buf + buf_len)
 			return -1;
 		*o_val = buf+2;
@@ -78,6 +79,22 @@
 		if (len > buf_len)
 			return -2;
 		break;
+	case TLV_TYPE_vTvLV_GAN:	/* 44.318 / 11.1.4 */
+		/* FIXME: variable-length TAG! */
+		if (*(buf+1) & 0x80) {
+			/* like TL16Vbut without highest bit of len */
+			if (2 > buf_len)
+				return -1;
+			*o_val = buf+3;
+			*o_len = (*(buf+1) & 0x7F) << 8 | *(buf+2);
+			len = *o_len + 3;
+			if (len > buf_len)
+				return -2;
+		} else {
+			/* like TLV */
+			goto tlv;
+		}
+		break;
 	case TLV_TYPE_TvLV:
 		if (*(buf+1) & 0x80) {
 			/* like TLV, but without highest bit of len */
@@ -184,6 +201,9 @@
 	int i;
 	for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++)
 		tvlv_att_def.def[i].type = TLV_TYPE_TvLV;
+
+	for (i = 0; i < ARRAY_SIZE(vtvlv_gan_att_def.def); i++)
+		vtvlv_gan_att_def.def[i].type = TLV_TYPE_vTvLV_GAN;
 }
 
 /*! @} */