diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-02-15 03:34:15 +0000 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-02-15 03:34:15 +0000 |
commit | e0590df5242af3178dbf75d527536634be0b890b (patch) | |
tree | dbd35075876c1976b944f4a273a9b4148b7483fe /src/tlv_parser.c | |
parent | 49314f60802dac6950479fc5ee6cdb190a943d41 (diff) |
* extend TLV parser to use a list of TLV type descriptions
* implement TLV type descriptions for NM
* add operational/administrative/availability state keeping logic to abis_nm
* explicitly print all NACK's in abis_nm
* make sure we produce [not just for BS-11] valid channel attributes
Diffstat (limited to 'src/tlv_parser.c')
-rw-r--r-- | src/tlv_parser.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/src/tlv_parser.c b/src/tlv_parser.c index b790d3cd8..f047d0bbc 100644 --- a/src/tlv_parser.c +++ b/src/tlv_parser.c @@ -1,6 +1,19 @@ +#include <stdio.h> #include <openbsc/tlv.h> -int tlv_parse(struct tlv_parsed *dec, u_int8_t *buf, int buf_len) +int tlv_dump(struct tlv_parsed *dec) +{ + int i; + + for (i = 0; i <= 0xff; i++) { + if (!dec->lv[i].val) + continue; + printf("T=%02x L=%d\n", i, dec->lv[i].len); + } + return 0; +} + +int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def, u_int8_t *buf, int buf_len) { u_int8_t tag, len = 1; u_int8_t *pos; @@ -11,13 +24,27 @@ int tlv_parse(struct tlv_parsed *dec, u_int8_t *buf, int buf_len) for (pos = buf; pos < buf+buf_len; pos += len) { tag = *pos; /* FIXME: use tables for knwon IEI */ - if (tag & 0x80) { + switch (def->def[tag].type) { + case TLV_TYPE_T: /* GSM TS 04.07 11.2.4: Type 1 TV or Type 2 T */ dec->lv[tag].val = pos; dec->lv[tag].len = 0; len = 1; num_parsed++; - } else { + break; + case TLV_TYPE_TV: + dec->lv[tag].val = pos+1; + dec->lv[tag].len = 1; + len = 2; + num_parsed++; + break; + case TLV_TYPE_FIXED: + dec->lv[tag].val = pos+1; + dec->lv[tag].len = def->def[tag].fixed_len; + len = def->def[tag].fixed_len + 1; + num_parsed++; + break; + case TLV_TYPE_TLV: /* GSM TS 04.07 11.2.4: Type 4 TLV */ if (pos + 1 > buf + buf_len) return -1; @@ -27,7 +54,20 @@ int tlv_parse(struct tlv_parsed *dec, u_int8_t *buf, int buf_len) if (pos + len > buf + buf_len) return -2; num_parsed++; + break; + case TLV_TYPE_TL16V: + if (pos + 2 > buf + buf_len) + return -1; + dec->lv[tag].val = pos+3; + dec->lv[tag].len = *(pos+1) << 8 | *(pos+2); + len = dec->lv[tag].len + 3; + if (pos + len > buf + buf_len) + return -2; + num_parsed++; + break; } } + //tlv_dump(dec); return num_parsed; } + |