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(),