From a4d49e96ab45b12fe581d6ab3cecd0727bccb317 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 23 May 2009 06:39:58 +0000 Subject: 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) --- include/openbsc/tlv.h | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/openbsc/tlv.h b/include/openbsc/tlv.h index 453f1d0a0..ae88e6ed3 100644 --- a/include/openbsc/tlv.h +++ b/include/openbsc/tlv.h @@ -6,12 +6,21 @@ #include +#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 -- cgit v1.2.3