blob: b790d3cd825f3d1a1c59b34dce6bf1bc9bb45d65 [file] [log] [blame]
Harald Welte91b5b0d2009-02-06 12:51:39 +00001#include <openbsc/tlv.h>
2
Harald Welte2fa79342009-02-14 19:07:10 +00003int tlv_parse(struct tlv_parsed *dec, u_int8_t *buf, int buf_len)
Harald Welte91b5b0d2009-02-06 12:51:39 +00004{
Harald Welte2fa79342009-02-14 19:07:10 +00005 u_int8_t tag, len = 1;
6 u_int8_t *pos;
7 int num_parsed = 0;
Harald Welte91b5b0d2009-02-06 12:51:39 +00008
Harald Welte2fa79342009-02-14 19:07:10 +00009 memset(dec, 0, sizeof(*dec));
Harald Welte91b5b0d2009-02-06 12:51:39 +000010
Harald Welte2fa79342009-02-14 19:07:10 +000011 for (pos = buf; pos < buf+buf_len; pos += len) {
12 tag = *pos;
13 /* FIXME: use tables for knwon IEI */
14 if (tag & 0x80) {
15 /* GSM TS 04.07 11.2.4: Type 1 TV or Type 2 T */
16 dec->lv[tag].val = pos;
17 dec->lv[tag].len = 0;
18 len = 1;
19 num_parsed++;
20 } else {
21 /* GSM TS 04.07 11.2.4: Type 4 TLV */
22 if (pos + 1 > buf + buf_len)
23 return -1;
24 dec->lv[tag].val = pos+2;
25 dec->lv[tag].len = *(pos+1);
26 len = dec->lv[tag].len + 2;
27 if (pos + len > buf + buf_len)
28 return -2;
29 num_parsed++;
30 }
Harald Welte91b5b0d2009-02-06 12:51:39 +000031 }
Harald Welte2fa79342009-02-14 19:07:10 +000032 return num_parsed;
Harald Welte91b5b0d2009-02-06 12:51:39 +000033}