aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gprs_bssgp_pcu.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index 838c667..07d610c 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;