From c3c58046c7223d48c61eb7126f33dca300254485 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 28 Sep 2015 17:55:32 +0200 Subject: [PATCH] edge: Get EGPRS multislot class The EGPRS MS class ist contained in the MS_RA_capability information. Its presence indicates, that the MS is able (and willing) to use EGPRS. This commit implements basic support for retrieving, storing, and showing it in the VTY. The information is stored in the MS object. Sponsored-by: On-Waves ehf --- src/bts.cpp | 18 ++++++++++++++++-- src/decoding.cpp | 15 +++++++++++++++ src/decoding.h | 1 + src/gprs_ms.cpp | 13 +++++++++++++ src/gprs_ms.h | 8 ++++++++ src/pcu_vty_functions.cpp | 1 + 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index edae7371..26077c21 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -990,6 +990,7 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, struct gprs_rlcmac_dl_tbf *dl_tbf = NULL; uint32_t tlli = request->ID.u.TLLI; uint8_t ms_class = 0; + uint8_t egprs_ms_class = 0; uint8_t ta = 0; struct pcu_l1_meas meas; @@ -1039,10 +1040,19 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, ta = sba->ta; bts()->sba()->free_sba(sba); } - if (request->Exist_MS_Radio_Access_capability) - ms_class = Decoding::get_ms_class_by_capability(&request->MS_Radio_Access_capability); + if (request->Exist_MS_Radio_Access_capability) { + ms_class = Decoding::get_ms_class_by_capability( + &request->MS_Radio_Access_capability); + egprs_ms_class = + Decoding::get_egprs_ms_class_by_capability( + &request->MS_Radio_Access_capability); + } if (!ms_class) LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n"); + if (egprs_ms_class) + LOGP(DRLCMAC, LOGL_NOTICE, + "MS supports EGPRS multislot class %d.\n", + egprs_ms_class); ul_tbf = tbf_alloc_ul(bts_data(), trx_no(), ms_class, tlli, ta, ms); if (!ul_tbf) return; @@ -1053,6 +1063,10 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, /* schedule uplink assignment */ ul_tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + /* get capabilities */ + if (ul_tbf->ms()) + ul_tbf->ms()->set_egprs_ms_class(egprs_ms_class); + /* get measurements */ if (ul_tbf->ms()) { get_meas(&meas, request); diff --git a/src/decoding.cpp b/src/decoding.cpp index fce8124f..d4f014b2 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -83,6 +83,21 @@ uint8_t Decoding::get_ms_class_by_capability(MS_Radio_Access_capability_t *cap) return 0; } +uint8_t Decoding::get_egprs_ms_class_by_capability(MS_Radio_Access_capability_t *cap) +{ + int i; + + for (i = 0; i < cap->Count_MS_RA_capability_value; i++) { + if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability) + continue; + if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_EGPRS_multislot_class) + continue; + return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.EGPRS_multislot_class; + } + + return 0; +} + /** * show_rbb needs to be an array with 65 elements * The index of the array is the bit position in the rbb diff --git a/src/decoding.h b/src/decoding.h index 31be0320..03dad47e 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -28,6 +28,7 @@ public: static int tlli_from_ul_data(const uint8_t *data, uint8_t len, uint32_t *tlli); static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap); + static uint8_t get_egprs_ms_class_by_capability(MS_Radio_Access_capability_t *cap); static void extract_rbb(const uint8_t *rbb, char *extracted_rbb); }; diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index 807f3459..76fe47c2 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -96,6 +96,7 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) : m_new_dl_tlli(0), m_ta(0), m_ms_class(0), + m_egprs_ms_class(0), m_current_cs_ul(1), m_current_cs_dl(1), m_is_idle(true), @@ -447,6 +448,18 @@ void GprsMs::set_ms_class(uint8_t ms_class_) m_ms_class = ms_class_; } +void GprsMs::set_egprs_ms_class(uint8_t ms_class_) +{ + if (ms_class_ == m_egprs_ms_class) + return; + + LOGP(DRLCMAC, LOGL_INFO, + "Modifying MS object, TLLI = 0x%08x, EGPRS MS class %d -> %d\n", + tlli(), m_egprs_ms_class, ms_class_); + + m_egprs_ms_class = ms_class_; +} + void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) { struct gprs_rlcmac_bts *bts_data; diff --git a/src/gprs_ms.h b/src/gprs_ms.h index e820e196..f9b63f26 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -81,7 +81,9 @@ public: uint8_t ta() const; void set_ta(uint8_t ta); uint8_t ms_class() const; + uint8_t egprs_ms_class() const; void set_ms_class(uint8_t ms_class); + void set_egprs_ms_class(uint8_t ms_class); uint8_t current_cs_ul() const; uint8_t current_cs_dl() const; @@ -148,6 +150,7 @@ private: char m_imsi[16]; uint8_t m_ta; uint8_t m_ms_class; + uint8_t m_egprs_ms_class; /* current coding scheme */ uint8_t m_current_cs_ul; uint8_t m_current_cs_dl; @@ -212,6 +215,11 @@ inline uint8_t GprsMs::ms_class() const return m_ms_class; } +inline uint8_t GprsMs::egprs_ms_class() const +{ + return m_egprs_ms_class; +} + inline uint8_t GprsMs::current_cs_ul() const { return m_current_cs_ul; diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index d2a3641a..ce2a006a 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -70,6 +70,7 @@ static int show_ms(struct vty *vty, GprsMs *ms) vty_out(vty, " Coding scheme downlink: CS-%d%s", ms->current_cs_dl(), VTY_NEWLINE); vty_out(vty, " MS class: %d%s", ms->ms_class(), VTY_NEWLINE); + vty_out(vty, " EGPRS MS class: %d%s", ms->egprs_ms_class(), VTY_NEWLINE); vty_out(vty, " LLC queue length: %d%s", ms->llc_queue()->size(), VTY_NEWLINE); vty_out(vty, " LLC queue octets: %d%s", ms->llc_queue()->octets(),