aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bts.cpp29
-rw-r--r--src/bts.h16
-rw-r--r--src/gprs_ms.cpp37
-rw-r--r--src/gprs_ms.h23
4 files changed, 102 insertions, 3 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 6da8cdd8..d14420c6 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -1147,3 +1147,32 @@ void gprs_rlcmac_pdch::detach_tbf(gprs_rlcmac_tbf *tbf)
LOGP(DRLCMAC, LOGL_INFO, "PDCH(TS %d, TRX %d): Detaching %s, %d TBFs.\n",
ts_no, trx_no(), tbf->name(), m_num_tbfs[tbf->direction]);
}
+
+void gprs_rlcmac_pdch::reserve(enum gprs_rlcmac_tbf_direction dir)
+{
+ m_num_reserved[dir] += 1;
+}
+
+void gprs_rlcmac_pdch::unreserve(enum gprs_rlcmac_tbf_direction dir)
+{
+ OSMO_ASSERT(m_num_reserved[dir] > 0);
+ m_num_reserved[dir] -= 1;
+}
+
+void gprs_rlcmac_trx::reserve_slots(enum gprs_rlcmac_tbf_direction dir,
+ uint8_t slots)
+{
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(pdch); i += 1)
+ if (slots & (1 << i))
+ pdch[i].reserve(dir);
+}
+
+void gprs_rlcmac_trx::unreserve_slots(enum gprs_rlcmac_tbf_direction dir,
+ uint8_t slots)
+{
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(pdch); i += 1)
+ if (slots & (1 << i))
+ pdch[i].unreserve(dir);
+}
diff --git a/src/bts.h b/src/bts.h
index f6cc88fa..093a8e3e 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -71,6 +71,10 @@ struct gprs_rlcmac_pdch {
void detach_tbf(gprs_rlcmac_tbf *tbf);
unsigned num_tbfs(enum gprs_rlcmac_tbf_direction dir) const;
+
+ void reserve(enum gprs_rlcmac_tbf_direction dir);
+ void unreserve(enum gprs_rlcmac_tbf_direction dir);
+ unsigned num_reserved(enum gprs_rlcmac_tbf_direction dir) const;
#endif
uint8_t m_is_enabled; /* TS is enabled */
@@ -100,6 +104,7 @@ private:
#endif
uint8_t m_num_tbfs[2];
+ uint8_t m_num_reserved[2];
};
struct gprs_rlcmac_trx {
@@ -112,6 +117,11 @@ struct gprs_rlcmac_trx {
/* back pointers */
struct BTS *bts;
uint8_t trx_no;
+
+#ifdef __cplusplus
+ void reserve_slots(enum gprs_rlcmac_tbf_direction dir, uint8_t slots);
+ void unreserve_slots(enum gprs_rlcmac_tbf_direction dir, uint8_t slots);
+#endif
};
/**
@@ -311,6 +321,12 @@ inline unsigned gprs_rlcmac_pdch::num_tbfs(enum gprs_rlcmac_tbf_direction dir) c
return m_num_tbfs[dir];
}
+inline unsigned gprs_rlcmac_pdch::num_reserved(
+ enum gprs_rlcmac_tbf_direction dir) const
+{
+ return gprs_rlcmac_pdch::m_num_reserved[dir];
+}
+
inline struct rate_ctr_group *BTS::rate_counters() const
{
return m_ratectrs;
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index 4c0ecfde..f62facf5 100644
--- a/src/gprs_ms.cpp
+++ b/src/gprs_ms.cpp
@@ -91,7 +91,10 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) :
m_ref(0),
m_list(this),
m_delay(0),
- m_nack_rate_dl(0)
+ m_nack_rate_dl(0),
+ m_reserved_dl_slots(0),
+ m_reserved_ul_slots(0),
+ m_current_trx(NULL)
{
LOGP(DRLCMAC, LOGL_INFO, "Creating MS object, TLLI = 0x%08x\n", tlli);
@@ -115,6 +118,8 @@ GprsMs::~GprsMs()
{
LOGP(DRLCMAC, LOGL_INFO, "Destroying MS object, TLLI = 0x%08x\n", tlli());
+ set_reserved_slots(NULL, 0, 0);
+
if (osmo_timer_pending(&m_timer))
osmo_timer_del(&m_timer);
@@ -240,8 +245,12 @@ void GprsMs::detach_tbf(gprs_rlcmac_tbf *tbf)
if (tbf->ms() == this)
tbf->set_ms(NULL);
- if (!m_dl_tbf && !m_ul_tbf && tlli() != 0)
- start_timer();
+ if (!m_dl_tbf && !m_ul_tbf) {
+ set_reserved_slots(NULL, 0, 0);
+
+ if (tlli() != 0)
+ start_timer();
+ }
update_status();
}
@@ -529,6 +538,28 @@ int GprsMs::first_common_ts() const
return -1;
}
+void GprsMs::set_reserved_slots(gprs_rlcmac_trx *trx,
+ uint8_t ul_slots, uint8_t dl_slots)
+{
+ if (m_current_trx) {
+ m_current_trx->unreserve_slots(GPRS_RLCMAC_DL_TBF,
+ m_reserved_dl_slots);
+ m_current_trx->unreserve_slots(GPRS_RLCMAC_UL_TBF,
+ m_reserved_ul_slots);
+ m_reserved_dl_slots = 0;
+ m_reserved_ul_slots = 0;
+ }
+ m_current_trx = trx;
+ if (trx) {
+ m_reserved_dl_slots = dl_slots;
+ m_reserved_ul_slots = ul_slots;
+ m_current_trx->reserve_slots(GPRS_RLCMAC_DL_TBF,
+ m_reserved_dl_slots);
+ m_current_trx->reserve_slots(GPRS_RLCMAC_UL_TBF,
+ m_reserved_ul_slots);
+ }
+}
+
gprs_rlcmac_tbf *GprsMs::tbf(enum gprs_rlcmac_tbf_direction dir) const
{
switch (dir) {
diff --git a/src/gprs_ms.h b/src/gprs_ms.h
index 2c6061c6..910ccb83 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -37,6 +37,7 @@ extern "C" {
#include <stddef.h>
struct BTS;
+struct gprs_rlcmac_trx;
class GprsMs {
public:
@@ -79,6 +80,11 @@ public:
uint8_t current_cs_dl() const;
int first_common_ts() const;
+ uint8_t reserved_dl_slots() const;
+ uint8_t reserved_ul_slots() const;
+ gprs_rlcmac_trx *current_trx() const;
+ void set_reserved_slots(gprs_rlcmac_trx *trx,
+ uint8_t ul_slots, uint8_t dl_slots);
gprs_llc_queue *llc_queue();
const gprs_llc_queue *llc_queue() const;
@@ -144,6 +150,9 @@ private:
pcu_l1_meas m_l1_meas;
unsigned m_nack_rate_dl;
+ uint8_t m_reserved_dl_slots;
+ uint8_t m_reserved_ul_slots;
+ gprs_rlcmac_trx *m_current_trx;
};
inline uint32_t GprsMs::tlli() const
@@ -199,3 +208,17 @@ inline unsigned GprsMs::nack_rate_dl() const
return m_nack_rate_dl;
}
+inline uint8_t GprsMs::reserved_dl_slots() const
+{
+ return m_reserved_dl_slots;
+}
+
+inline uint8_t GprsMs::reserved_ul_slots() const
+{
+ return m_reserved_ul_slots;
+}
+
+inline gprs_rlcmac_trx *GprsMs::current_trx() const
+{
+ return m_current_trx;
+}