aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2020-05-29 23:58:01 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2020-06-10 14:20:49 +0200
commitc71f771a8411105c9437afd50c08772150591f58 (patch)
treefcc42257641dd800702d89585bec2787ae016624
parent7dde1f40a293dbac575b294f82ba905d8f45b7b7 (diff)
tlv.h: add msgb_tvl_put() to add a TvLV without the value part
So far, we have msgb_tl_put(), which allows putting the TL header of a TLV, without the value part. Add the same for a variable-size length TvLV: put a TvL header of a TvLV without the value part. In a subsequent patch, osmo_mobile_identity will be introduced, which will allow writing the encoded MI directly to the end of a msgb. For BSSGP_IE_IMSI, which is a TvLV, it would hence be simplest to write only the TvL first. Change-Id: I02cca5182fe42e40b63680a2fd470f03bcc11076
-rw-r--r--include/osmocom/gsm/tlv.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/include/osmocom/gsm/tlv.h b/include/osmocom/gsm/tlv.h
index bb0e8fc9..254c21bc 100644
--- a/include/osmocom/gsm/tlv.h
+++ b/include/osmocom/gsm/tlv.h
@@ -111,6 +111,14 @@ static inline uint8_t *tlv_put(uint8_t *buf, uint8_t tag, uint8_t len,
return buf + len;
}
+/*! put (append) a TL field (a TLV field but omitting the value part). */
+static inline uint8_t *tl_put(uint8_t *buf, uint8_t tag, uint8_t len)
+{
+ *buf++ = tag;
+ *buf++ = len;
+ return buf;
+}
+
/*! put (append) a TLV16 field */
static inline uint8_t *tlv16_put(uint8_t *buf, uint8_t tag, uint8_t len,
const uint16_t *val)
@@ -132,6 +140,15 @@ static inline uint8_t *tl16v_put(uint8_t *buf, uint8_t tag, uint16_t len,
return buf + len*2;
}
+/*! put (append) a TL16 field. */
+static inline uint8_t *tl16_put(uint8_t *buf, uint8_t tag, uint16_t len)
+{
+ *buf++ = tag;
+ *buf++ = len >> 8;
+ *buf++ = len & 0xff;
+ return buf;
+}
+
/*! put (append) a TL16V field */
static inline uint8_t *t16lv_put(uint8_t *buf, uint16_t tag, uint8_t len,
const uint8_t *val)
@@ -158,6 +175,23 @@ static inline uint8_t *tvlv_put(uint8_t *buf, uint8_t tag, uint16_t len,
return ret;
}
+/*! put (append) a TvL field (a TvLV with variable-size length, where the value part's length is already known, but will
+ * be put() later).
+ * \returns pointer to the value's start position.
+ */
+static inline uint8_t *tvl_put(uint8_t *buf, uint8_t tag, uint16_t len)
+{
+ uint8_t *ret;
+
+ if (len <= TVLV_MAX_ONEBYTE) {
+ ret = tl_put(buf, tag, len);
+ buf[1] |= 0x80;
+ } else
+ ret = tl16_put(buf, tag, len);
+
+ return ret;
+}
+
/*! put (append) a variable-length tag or variable-length length * */
static inline uint8_t *vt_gan_put(uint8_t *buf, uint16_t tag)
{
@@ -215,6 +249,17 @@ static inline uint8_t *msgb_t16lv_put(struct msgb *msg, uint16_t tag, uint8_t le
return t16lv_put(buf, tag, len, val);
}
+/*! put (append) a TvL field to \ref msgb, i.e. a TvLV with variable-size length, where the value's length is already
+ * known, but will be put() later. The value section is not yet reserved, only tag and variable-length are put in the
+ * msgb.
+ * \returns pointer to the value's start position and end of the msgb.
+ */
+static inline uint8_t *msgb_tvl_put(struct msgb *msg, uint8_t tag, uint16_t len)
+{
+ uint8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
+ return tvl_put(buf, tag, len);
+}
+
/*! put (append) a TvLV field to \ref msgb */
static inline uint8_t *msgb_tvlv_put(struct msgb *msg, uint8_t tag, uint16_t len,
const uint8_t *val)