diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2016-01-20 12:22:07 +0100 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2016-02-02 17:06:36 +0100 |
commit | b9f4dc16c039a7e808ca9f4347794da656642f2d (patch) | |
tree | ce2b944e367036bd02605b92493a296b90a0532e /src/gprs_bssgp_pcu.cpp | |
parent | 51bb0c9ecd82f3e9665a2aabb4eed143ac389e01 (diff) |
edge: Get EGPRS MS class from downlink BSSGP (TODO)
In case there is no MS object present that matches a DL UNITDATA,
the EGPRS class is currently assumed to be 0, since the Radio
Access Capabilities IE is not fully decoded if present.
This commit uses the CSN.1 decoder to parse the IE and uses the
same functions like the uplink related code does to get the GPRS
and EGPRS multislot classes.
TODO:
- test and remove assert
- remove old function
Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/gprs_bssgp_pcu.cpp')
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 49 |
1 files changed, 22 insertions, 27 deletions
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 838c667d..c66dbae4 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -23,6 +23,7 @@ #include <pcu_l1_if.h> #include <bts.h> #include <tbf.h> +#include <decoding.h> #define BSSGP_TIMER_T1 30 /* Guards the (un)blocking procedures */ #define BSSGP_TIMER_T2 30 /* Guards the reset procedure */ @@ -73,44 +74,30 @@ static int parse_imsi(struct tlv_parsed *tp, char *imsi) return 0; } -static int parse_ra_cap_ms_class(struct tlv_parsed *tp) +static int parse_ra_cap(struct tlv_parsed *tp, MS_Radio_Access_capability_t *rac) { bitvec *block; - unsigned rp = 0; - uint8_t ms_class = 0; uint8_t cap_len; uint8_t *cap; + memset(rac, 0, sizeof(*rac)); + if (!TLVP_PRESENT(tp, BSSGP_IE_MS_RADIO_ACCESS_CAP)) - return ms_class; + 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); + LOGP(DBSSGP, LOGL_DEBUG, "Got BSSGP RA Capability of size %d\n", cap_len); + 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 - 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 - } + + /* TS 24.008, 10.5.5.12a */ + decode_gsm_ra_cap(block, rac); bitvec_free(block); - return ms_class; + return 0; } static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) @@ -122,6 +109,9 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) uint8_t *data; uint16_t len; char imsi[16] = "000"; + uint8_t ms_class = 0; + uint8_t egprs_ms_class = 0; + MS_Radio_Access_capability_t rac; budh = (struct bssgp_ud_hdr *)msgb_bssgph(msg); tlli = ntohl(budh->tlli); @@ -147,9 +137,14 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) parse_imsi(tp, imsi); /* parse ms radio access capability */ - uint8_t ms_class = parse_ra_cap_ms_class(tp); - /* TODO: Get the EGPRS class from the CSN.1 RA capability */ - uint8_t egprs_ms_class = 0; + if (parse_ra_cap(tp, &rac) >= 0) { + /* Get the EGPRS class from the RA capability */ + ms_class = Decoding::get_ms_class_by_capability(&rac); + egprs_ms_class = + Decoding::get_egprs_ms_class_by_capability(&rac); + LOGP(DBSSGP, LOGL_DEBUG, "Got downlink MS class %d/%d\n", + ms_class, egprs_ms_class); + } /* get lifetime */ uint16_t delay_csec = 0xffff; |