aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2016-01-20 12:22:07 +0100
committerJacob Erlbeck <jerlbeck@sysmocom.de>2016-02-08 00:45:36 +0100
commit4a07a3be11e7366b557bab795aa23b42725ec23e (patch)
treeda6ab2b018681e6e280290bab0359199cc71e5d8
parent0df80be95e3604656ff36024f793ef3c36455051 (diff)
edge: Get EGPRS MS class from downlink BSSGP
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. Remove the old parse_ra_cap_ms_class function. Sponsored-by: On-Waves ehf
-rw-r--r--src/gprs_bssgp_pcu.cpp49
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;