Harald Welte | 91b5b0d | 2009-02-06 12:51:39 +0000 | [diff] [blame] | 1 | #include <openbsc/tlv.h> |
| 2 | |
Harald Welte | 2fa7934 | 2009-02-14 19:07:10 +0000 | [diff] [blame] | 3 | int tlv_parse(struct tlv_parsed *dec, u_int8_t *buf, int buf_len) |
Harald Welte | 91b5b0d | 2009-02-06 12:51:39 +0000 | [diff] [blame] | 4 | { |
Harald Welte | 2fa7934 | 2009-02-14 19:07:10 +0000 | [diff] [blame] | 5 | u_int8_t tag, len = 1; |
| 6 | u_int8_t *pos; |
| 7 | int num_parsed = 0; |
Harald Welte | 91b5b0d | 2009-02-06 12:51:39 +0000 | [diff] [blame] | 8 | |
Harald Welte | 2fa7934 | 2009-02-14 19:07:10 +0000 | [diff] [blame] | 9 | memset(dec, 0, sizeof(*dec)); |
Harald Welte | 91b5b0d | 2009-02-06 12:51:39 +0000 | [diff] [blame] | 10 | |
Harald Welte | 2fa7934 | 2009-02-14 19:07:10 +0000 | [diff] [blame] | 11 | 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 Welte | 91b5b0d | 2009-02-06 12:51:39 +0000 | [diff] [blame] | 31 | } |
Harald Welte | 2fa7934 | 2009-02-14 19:07:10 +0000 | [diff] [blame] | 32 | return num_parsed; |
Harald Welte | 91b5b0d | 2009-02-06 12:51:39 +0000 | [diff] [blame] | 33 | } |