aboutsummaryrefslogtreecommitdiffstats
path: root/include/openbsc
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-05-23 06:39:58 +0000
committerHarald Welte <laforge@gnumonks.org>2009-05-23 06:39:58 +0000
commita4d49e96ab45b12fe581d6ab3cecd0727bccb317 (patch)
treedbeebd5e255e0ef1b07c1be083f8691027e46afa /include/openbsc
parente7b452a7a07b75f880fadeeb650efe2bac931c7b (diff)
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)
Diffstat (limited to 'include/openbsc')
-rw-r--r--include/openbsc/tlv.h29
1 files changed, 28 insertions, 1 deletions
diff --git a/include/openbsc/tlv.h b/include/openbsc/tlv.h
index 453f1d0a..ae88e6ed 100644
--- a/include/openbsc/tlv.h
+++ b/include/openbsc/tlv.h
@@ -6,12 +6,21 @@
#include <openbsc/msgb.h>
+#define LV_GROSS_LEN(x) (x+1)
#define TLV_GROSS_LEN(x) (x+2)
#define TLV16_GROSS_LEN(x) ((2*x)+2)
#define TL16V_GROSS_LEN(x) (x+3)
/* TLV generation */
+static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len,
+ const u_int8_t *val)
+{
+ *buf++ = len;
+ memcpy(buf, val, len);
+ return buf + len;
+}
+
static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
const u_int8_t *val)
{
@@ -53,6 +62,12 @@ static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t
return tl16v_put(buf, tag, len, val);
}
+static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val)
+{
+ *buf++ = val;
+ return buf;
+}
+
static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag,
u_int8_t val)
{
@@ -70,6 +85,12 @@ static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag,
return buf;
}
+static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val)
+{
+ u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
+ return lv_put(buf, len, val);
+}
+
static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
{
u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
@@ -82,6 +103,12 @@ static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val
return tv_put(buf, tag, val);
}
+static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val)
+{
+ u_int8_t *buf = msgb_put(msg, 1);
+ return v_put(buf, val);
+}
+
static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
{
u_int8_t *buf = msgb_put(msg, 3);
@@ -135,7 +162,7 @@ struct tlv_parsed {
};
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);
#define TLVP_PRESENT(x, y) ((x)->lv[y].val)
#define TLVP_LEN(x, y) (x)->lv[y].len