diff options
Diffstat (limited to 'src/gsm')
-rw-r--r-- | src/gsm/libosmogsm.map | 1 | ||||
-rw-r--r-- | src/gsm/tlv_parser.c | 22 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 9ef5ccd4..33738881 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -227,6 +227,7 @@ tlv_dump; tlv_parse; tlv_parse_one; tvlv_att_def; +vtvlv_gan_att_def; gan_msgt_vals; gan_pdisc_vals; diff --git a/src/gsm/tlv_parser.c b/src/gsm/tlv_parser.c index 0ac90929..d18a6bfd 100644 --- a/src/gsm/tlv_parser.c +++ b/src/gsm/tlv_parser.c @@ -9,6 +9,7 @@ /*! \file tlv.c */ struct tlv_definition tvlv_att_def; +struct tlv_definition vtvlv_gan_att_def; /*! \brief Dump pasred TLV structure to stdout */ int tlv_dump(struct tlv_parsed *dec) @@ -69,7 +70,7 @@ int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val, len = def->def[tag].fixed_len + 1; break; case TLV_TYPE_TLV: - /* GSM TS 04.07 11.2.4: Type 4 TLV */ +tlv: /* GSM TS 04.07 11.2.4: Type 4 TLV */ if (buf + 1 > buf + buf_len) return -1; *o_val = buf+2; @@ -78,6 +79,22 @@ int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val, if (len > buf_len) return -2; break; + case TLV_TYPE_vTvLV_GAN: /* 44.318 / 11.1.4 */ + /* FIXME: variable-length TAG! */ + if (*(buf+1) & 0x80) { + /* like TL16Vbut without highest bit of len */ + if (2 > buf_len) + return -1; + *o_val = buf+3; + *o_len = (*(buf+1) & 0x7F) << 8 | *(buf+2); + len = *o_len + 3; + if (len > buf_len) + return -2; + } else { + /* like TLV */ + goto tlv; + } + break; case TLV_TYPE_TvLV: if (*(buf+1) & 0x80) { /* like TLV, but without highest bit of len */ @@ -184,6 +201,9 @@ static __attribute__((constructor)) void on_dso_load_tlv(void) int i; for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++) tvlv_att_def.def[i].type = TLV_TYPE_TvLV; + + for (i = 0; i < ARRAY_SIZE(vtvlv_gan_att_def.def); i++) + vtvlv_gan_att_def.def[i].type = TLV_TYPE_vTvLV_GAN; } /*! @} */ |