Change in libosmocore[master]: TLV: Add one-shot TLV encoder

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Wed Feb 13 21:26:41 UTC 2019


Harald Welte has uploaded this change for review. ( https://gerrit.osmocom.org/12900


Change subject: TLV: Add one-shot TLV encoder
......................................................................

TLV: Add one-shot TLV encoder

So far, the TLV code contained two types of functions
* tlp_parse() to parse all TLVs according to definition into tlvp_parsed
* various helper functions to encode individual TLVs during message
  generation

This patch implements the inverse of tlv_parse(): tlv_encode(), which
takes a full 'struct tlv_pared' and encodes all IEs found in it.  The
order of IEs is in numerically ascending order of the tag.

As many protocols have different IE/TLV ordering requirements, let's add
a tlv_encode_ordered() function where the caller can specify the TLV
ordering during the one-shot encode.

Change-Id: I761a30bf20355a9f80a4a8e0c60b0b0f78515efe
---
M include/osmocom/gsm/tlv.h
M src/gsm/libosmogsm.map
M src/gsm/tlv_parser.c
3 files changed, 96 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/00/12900/1

diff --git a/include/osmocom/gsm/tlv.h b/include/osmocom/gsm/tlv.h
index d0c9552..bb0e8fc 100644
--- a/include/osmocom/gsm/tlv.h
+++ b/include/osmocom/gsm/tlv.h
@@ -457,6 +457,12 @@
 /* take a master (src) tlv def and fill up all empty slots in 'dst' */
 void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src);
 
+int tlv_encode_one(struct msgb *msg, enum tlv_type type, uint8_t tag,
+		   unsigned int len, const uint8_t *val);
+int tlv_encode(struct msgb *msg, const struct tlv_definition *def, const struct tlv_parsed *tp);
+int tlv_encode_ordered(struct msgb *msg, const struct tlv_definition *def, const struct tlv_parsed *tp,
+			const uint8_t *tag_order, unsigned int tag_order_len);
+
 #define TLVP_PRESENT(x, y)	((x)->lv[y].val)
 #define TLVP_LEN(x, y)		(x)->lv[y].len
 #define TLVP_VAL(x, y)		(x)->lv[y].val
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index ae7c0a1..c123dfc 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -493,6 +493,9 @@
 tlv_parse;
 tlv_parse2;
 tlv_parse_one;
+tlv_encode;
+tlv_encode_ordered;
+tlv_encode_one;
 tvlv_att_def;
 vtvlv_gan_att_def;
 
diff --git a/src/gsm/tlv_parser.c b/src/gsm/tlv_parser.c
index 6e089f7..b227c84 100644
--- a/src/gsm/tlv_parser.c
+++ b/src/gsm/tlv_parser.c
@@ -120,6 +120,93 @@
 	return 0;
 }
 
+
+/*! Encode a single TLV into given message buffer
+ *  \param[inout] msg Caller-allocated message buffer with sufficient tailroom
+ *  \param[in] type TLV type/format to use during encode
+ *  \param[in] tag Tag of TLV to be encoded
+ *  \parma[in] len Length of TLV to be encoded
+ *  \param[in] val Value part of TLV to be encoded
+ *  \returns 0 on success; negative in case of error */
+int tlv_encode_one(struct msgb *msg, enum tlv_type type, uint8_t tag,
+		   unsigned int len, const uint8_t *val)
+{
+	switch (type) {
+	case TLV_TYPE_NONE:
+		break;
+	case TLV_TYPE_FIXED:
+		msgb_tv_fixed_put(msg, tag, len, val);
+		break;
+	case TLV_TYPE_T:
+		msgb_v_put(msg, tag);
+		break;
+	case TLV_TYPE_TV:
+		msgb_tv_put(msg, tag, val[0]);
+		break;
+	case TLV_TYPE_TLV:
+		msgb_tlv_put(msg, tag, len, val);
+		break;
+	case TLV_TYPE_TL16V:
+		msgb_tl16v_put(msg, tag, len, val);
+		break;
+	case TLV_TYPE_TvLV:
+		msgb_tvlv_put(msg, tag, len, val);
+		break;
+	case TLV_TYPE_SINGLE_TV:
+		msgb_v_put(msg, (tag << 4) | (val[0] & 0xf));
+		break;
+	case TLV_TYPE_vTvLV_GAN:
+		msgb_vtvlv_gan_put(msg, tag, len, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*! Encode a set of decoded TLVs according to a given definition into a message buffer
+ *  \param[inout] msg Caller-allocated message buffer with sufficient tailroom
+ *  \param[in] def structure defining the valid TLV tags / configurations
+ *  \param[in] tp decoded values to be encoded
+ *  \returns number of bytes consumed in msg; negative in case of error */
+int tlv_encode(struct msgb *msg, const struct tlv_definition *def, const struct tlv_parsed *tp)
+{
+	unsigned int tailroom_before = msgb_tailroom(msg);
+	unsigned int i;
+	int rc;
+
+	for (i = 0; i < ARRAY_SIZE(tp->lv); i++) {
+		rc = tlv_encode_one(msg, def->def[i].type, i, TLVP_LEN(tp, i), TLVP_VAL(tp, i));
+		if (rc < 0)
+			return rc;
+	}
+	return tailroom_before - msgb_tailroom(msg);
+}
+
+/*! Encode a set of decoded TLVs according to a given definition and IE order into a message buffer
+ *  \param[inout] msg Caller-allocated message buffer with sufficient tailroom
+ *  \param[in] def structure defining the valid TLV tags / configurations
+ *  \param[in] tp decoded values to be encoded
+ *  \param[in] tag_order array of tags determining the IE encoding order
+ *  \param[in] tag_order_len length of tag_order
+ *  \returns number of bytes consumed in msg; negative in case of error */
+int tlv_encode_ordered(struct msgb *msg, const struct tlv_definition *def, const struct tlv_parsed *tp,
+			const uint8_t *tag_order, unsigned int tag_order_len)
+{
+
+	unsigned int tailroom_before = msgb_tailroom(msg);
+	unsigned int i;
+	int rc;
+
+	for (i = 0; i < tag_order_len; i++) {
+		uint8_t tag = tag_order[i];
+		rc = tlv_encode_one(msg, def->def[tag].type, tag, TLVP_LEN(tp, i), TLVP_VAL(tp, i));
+		if (rc < 0)
+			return rc;
+	}
+	return tailroom_before - msgb_tailroom(msg);
+}
+
 /*! Parse a single TLV encoded IE
  *  \param[out] o_tag the tag of the IE that was found
  *  \param[out] o_len length of the IE that was found

-- 
To view, visit https://gerrit.osmocom.org/12900
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I761a30bf20355a9f80a4a8e0c60b0b0f78515efe
Gerrit-Change-Number: 12900
Gerrit-PatchSet: 1
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190213/4118e8a0/attachment.htm>


More information about the gerrit-log mailing list