diff options
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 838c667d..07d610c0 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -113,6 +113,72 @@ static int parse_ra_cap_ms_class(struct tlv_parsed *tp) return ms_class; } +struct gprs_ra_cap +{ + uint8_t ms_class; + uint8_t exist_egprs_ms_class; + uint8_t egprs_ms_class; + uint8_t support_8psk_uplink; +}; + +static int parse_ra_cap(struct tlv_parsed *tp, struct gprs_ra_cap *rac) __attribute__((__unused__)); +static int parse_ra_cap(struct tlv_parsed *tp, struct gprs_ra_cap *rac) +{ + bitvec *block; + unsigned rp = 0; + uint8_t ms_class = 0; + uint8_t cap_len; + uint8_t *cap; + + memset(rac, 0, sizeof(gprs_ra_cap)); + + if (!TLVP_PRESENT(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP)) + return -EINVAL; + + cap_len = TLVP_LEN(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); + cap = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP); + + block = bitvec_alloc(cap_len); + bitvec_unpack(block, cap); + bitvec_read_field(block, rp, 4); // Access Technology Type + bitvec_read_field(block, rp, 7); // Length of Access Capabilities + bitvec_read_field(block, rp, 3); // RF Power Capability + if (bitvec_read_field(block, rp, 1)) // A5 Bits Present + bitvec_read_field(block, rp, 7); // A5 Bits + bitvec_read_field(block, rp, 1); // ES IND + bitvec_read_field(block, rp, 1); // PS + bitvec_read_field(block, rp, 1); // VGCS + bitvec_read_field(block, rp, 1); // VBS + if (bitvec_read_field(block, rp, 1)) { // Multislot Cap Present + if (bitvec_read_field(block, rp, 1)) // HSCSD Present + bitvec_read_field(block, rp, 5); // Class + if (bitvec_read_field(block, rp, 1)) { // GPRS Present + rac->ms_class = bitvec_read_field(block, rp, 5); // Class + bitvec_read_field(block, rp, 1); // Ext. + } + if (bitvec_read_field(block, rp, 1)) // SMS Present + bitvec_read_field(block, rp, 4); // SMS Value + /* Additions in release 99 */ + if (bitvec_read_field(block, rp, 1)) // ECSD multislot class Present + bitvec_read_field(block, rp, 5); // Class + if (bitvec_read_field(block, rp, 1)) { // EGPRS Present + rac->egprs_ms_class = bitvec_read_field(block, rp, 5); // Class + bitvec_read_field(block, rp, 1); // Ext. + } + if (bitvec_read_field(block, rp, 1)) { // DTM Present + bitvec_read_field(block, rp, 2); // GPRS Class + bitvec_read_field(block, rp, 1); // Single Slot DTM + if (bitvec_read_field(block, rp, 1)) // EGPRS Present + bitvec_read_field(block, rp, 2); // EGPRS Class + } + } + if (bitvec_read_field(block, rp, 1)) // 8PSK Power Cap Present + rac->support_8psk_uplink = bitvec_read_field(block, rp, 2); // Power Cap + + bitvec_free(block); + return ms_class; +} + static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) { struct bssgp_ud_hdr *budh; |