blob: 3bb586225a6c5a9c72835f2f176ae9d153ccc72d [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001#ifndef _TLV_H
2#define _TLV_H
3
4#include <sys/types.h>
5#include <string.h>
6
Harald Welte91b5b0d2009-02-06 12:51:39 +00007#include <openbsc/msgb.h>
8
Harald Welte52b1f982008-12-23 20:25:15 +00009#define TLV_GROSS_LEN(x) (x+2)
10#define TLV16_GROSS_LEN(x) ((2*x)+2)
Harald Welte702d8702008-12-26 20:25:35 +000011#define TL16V_GROSS_LEN(x) (x+3)
Harald Welte52b1f982008-12-23 20:25:15 +000012
Harald Welte91b5b0d2009-02-06 12:51:39 +000013/* TLV generation */
14
Harald Welte52b1f982008-12-23 20:25:15 +000015static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
16 const u_int8_t *val)
17{
18 *buf++ = tag;
19 *buf++ = len;
20 memcpy(buf, val, len);
21 return buf + len;
22}
23
24static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
25 const u_int16_t *val)
26{
27 *buf++ = tag;
28 *buf++ = len;
29 memcpy(buf, val, len*2);
30 return buf + len*2;
31}
32
Harald Welte702d8702008-12-26 20:25:35 +000033static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
34 const u_int8_t *val)
35{
36 *buf++ = tag;
37 *buf++ = len >> 8;
38 *buf++ = len & 0xff;
39 memcpy(buf, val, len);
40 return buf + len*2;
41}
42
Harald Welte52b1f982008-12-23 20:25:15 +000043static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val)
44{
45 u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
46 return tlv16_put(buf, tag, len, val);
47}
48
Harald Welte702d8702008-12-26 20:25:35 +000049static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
50 const u_int8_t *val)
51{
52 u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
53 return tl16v_put(buf, tag, len, val);
54}
55
Harald Welte52b1f982008-12-23 20:25:15 +000056static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag,
57 u_int8_t val)
58{
59 *buf++ = tag;
60 *buf++ = val;
61 return buf;
62}
63
Harald Welte4b634542008-12-27 01:55:51 +000064static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag,
65 u_int16_t val)
66{
67 *buf++ = tag;
68 *buf++ = val >> 8;
69 *buf++ = val & 0xff;
70 return buf;
71}
72
Harald Welte52b1f982008-12-23 20:25:15 +000073static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
74{
75 u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
76 return tlv_put(buf, tag, len, val);
77}
78
79static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val)
80{
81 u_int8_t *buf = msgb_put(msg, 2);
82 return tv_put(buf, tag, val);
83}
84
Harald Welte4b634542008-12-27 01:55:51 +000085static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
86{
87 u_int8_t *buf = msgb_put(msg, 3);
88 return tv16_put(buf, tag, val);
89}
90
Harald Welte52b1f982008-12-23 20:25:15 +000091static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
92{
93 u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
94 return tlv_put(buf, tag, len, val);
95}
96
97static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val)
98{
99 u_int8_t *buf = msgb_push(msg, 2);
100 return tv_put(buf, tag, val);
101}
102
Harald Welte4b634542008-12-27 01:55:51 +0000103static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val)
104{
105 u_int8_t *buf = msgb_push(msg, 3);
106 return tv16_put(buf, tag, val);
107}
108
Harald Welte91b5b0d2009-02-06 12:51:39 +0000109/* TLV parsing */
110
111struct tlv_p_entry {
112 u_int8_t len;
113 u_int8_t *val;
114};
115
Harald Welte2fa79342009-02-14 19:07:10 +0000116struct tlv_parsed {
Harald Welte91b5b0d2009-02-06 12:51:39 +0000117 struct tlv_p_entry lv[0xff];
118};
119
Harald Welte2fa79342009-02-14 19:07:10 +0000120int tlv_parse(struct tlv_parsed *dec, u_int8_t *buf, int buf_len);
121
122#define TLVP_PRESENT(x, y) ((x)->lv[y].val)
123#define TLVP_LEN(x, y) (x)->lv[y].len
124#define TLVP_VAL(x, y) (x)->lv[y].val
Harald Welte4b634542008-12-27 01:55:51 +0000125
Harald Welte52b1f982008-12-23 20:25:15 +0000126#endif /* _TLV_H */