aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gprs_rlcmac.cpp90
-rw-r--r--src/gprs_rlcmac.h6
-rw-r--r--src/gprs_rlcmac_data.cpp4
3 files changed, 69 insertions, 31 deletions
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp
index ff423d2c..ee76e82a 100644
--- a/src/gprs_rlcmac.cpp
+++ b/src/gprs_rlcmac.cpp
@@ -371,13 +371,9 @@ next_diagram:
tbf->ms_class = ms_class;
tbf->ws = 64;
tbf->sns = 128;
- /* select algorithm A in case we don't have multislot class info */
- if (single_slot || ms_class == 0)
- rc = alloc_algorithm_a(old_tbf, tbf,
- bts->alloc_algorithm_curst);
- else
- rc = bts->alloc_algorithm(old_tbf, tbf,
- bts->alloc_algorithm_curst);
+ /* select algorithm */
+ rc = bts->alloc_algorithm(old_tbf, tbf, bts->alloc_algorithm_curst,
+ single_slot);
/* if no ressource */
if (rc < 0) {
talloc_free(tbf);
@@ -414,7 +410,7 @@ next_diagram:
* Assign single slot for uplink and downlink
*/
int alloc_algorithm_a(struct gprs_rlcmac_tbf *old_tbf,
- struct gprs_rlcmac_tbf *tbf, uint32_t cust)
+ struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single)
{
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
struct gprs_rlcmac_pdch *pdch;
@@ -463,7 +459,7 @@ int alloc_algorithm_a(struct gprs_rlcmac_tbf *old_tbf,
*
*/
int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
- struct gprs_rlcmac_tbf *tbf, uint32_t cust)
+ struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single)
{
struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
struct gprs_rlcmac_pdch *pdch;
@@ -478,9 +474,8 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
int8_t usf[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; /* must be signed */
int8_t tsc = -1; /* must be signed */
uint8_t i, ts;
+ uint8_t slotcount = 0;
- LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for class "
- "%d\n", tbf->ms_class);
if (tbf->ms_class >= 32) {
LOGP(DRLCMAC, LOGL_ERROR, "Multislot class %d out of range.\n",
@@ -488,7 +483,16 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
return -EINVAL;
}
- ms_class = &gprs_ms_multislot_class[tbf->ms_class];
+ if (tbf->ms_class) {
+ ms_class = &gprs_ms_multislot_class[tbf->ms_class];
+ LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
+ "class %d\n", tbf->ms_class);
+ } else {
+ ms_class = &gprs_ms_multislot_class[12];
+ LOGP(DRLCMAC, LOGL_DEBUG, "Slot Allocation (Algorithm B) for "
+ "unknow class (assuming 12)\n");
+ }
+
if (ms_class->tx == MS_NA) {
LOGP(DRLCMAC, LOGL_NOTICE, "Multislot class %d not "
"applicable.\n", tbf->ms_class);
@@ -496,7 +500,15 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
}
Rx = ms_class->rx;
+ if (Rx > 4) {
+ LOGP(DRLCMAC, LOGL_DEBUG, "- Degrading max Rx slots to 4\n");
+ Rx = 4;
+ }
Tx = ms_class->tx;
+ if (Tx > 4) {
+ LOGP(DRLCMAC, LOGL_DEBUG, "- Degrading max Tx slots to 4\n");
+ Tx = 4;
+ }
Sum = ms_class->sum;
Tta = ms_class->ta;
Ttb = ms_class->tb;
@@ -554,7 +566,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
* This must be done for uplink TBF also, because it is the basis
* for calculating control slot and uplink slot(s). */
rx_win_min = rx_win_max = tbf->first_ts;
- for (ts = tbf->first_ts, i = 0; ts < 8; ts++) {
+ for (ts = 0, i = 0; ts < 8; ts++) {
pdch = &bts->trx[tbf->trx].pdch[ts];
/* check if enabled */
if (!pdch->enable) {
@@ -741,15 +753,15 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
tx_window |= (1 << ts);
LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", ts);
- if (!(cust & 1)) {
+ if (1) { /* FIXME: multislot UL assignment */
LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because "
"1 slot assigned\n");
break;
}
if (++i == Tx) {
LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because "
- "slots / window reached maximum alowed "
- "Tx size\n");
+ "slots / window reached maximum "
+ "allowed Tx size\n");
break;
}
}
@@ -773,8 +785,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
}
if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
- uint8_t slotcount = 0;
-
/* assign downlink */
if (rx_window == 0) {
LOGP(DRLCMAC, LOGL_NOTICE, "No downlink slots "
@@ -783,6 +793,11 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
}
for (ts = 0; ts < 8; ts++) {
if ((rx_window & (1 << ts))) {
+ /* be sure to select a single downlink slots
+ * that can be used for uplink, if multiple
+ * slots are assigned later. */
+ if (single && tx_win_min != ts)
+ continue;
LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS "
"%d\n", ts);
pdch = &bts->trx[tbf->trx].pdch[ts];
@@ -790,11 +805,12 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
pdch->dl_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
slotcount++;
+ if (slotcount == 1)
+ tbf->first_ts = ts;
+ if (single)
+ break;
}
}
- if (slotcount)
- LOGP(DRLCMAC, LOGL_INFO, "Using Multislot with %d "
- "slots DL\n", slotcount);
} else {
/* assign uplink */
if (tx_window == 0) {
@@ -811,13 +827,33 @@ int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
pdch->ul_tbf[tbf->tfi] = tbf;
tbf->pdch[ts] = pdch;
tbf->dir.ul.usf[ts] = usf[ts];
+ slotcount++;
+ if (slotcount == 1)
+ tbf->first_ts = ts;
+ if (single)
+ break;
}
}
}
+ if (single && slotcount) {
+ LOGP(DRLCMAC, LOGL_INFO, "Using single slot at TS %d for %s\n",
+ tbf->first_ts,
+ (tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
+ } else {
+ LOGP(DRLCMAC, LOGL_INFO, "Using %d slots for %s\n", slotcount,
+ (tbf->direction == GPRS_RLCMAC_DL_TBF) ? "DL" : "UL");
+ }
+ if (slotcount == 0)
+ return -EBUSY;
- /* the timeslot of the TX window start is always
- * available in RX window */
- tbf->first_common_ts = tx_win_min;
+ if (single) {
+ /* the only one TS is the common TS */
+ tbf->first_common_ts = tbf->first_ts;
+ } else {
+ /* the timeslot of the TX window start is always
+ * available in RX window */
+ tbf->first_common_ts = tx_win_min;
+ }
return 0;
}
@@ -895,7 +931,7 @@ int tbf_update(struct gprs_rlcmac_tbf *tbf)
ul_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF);
tbf_unlink_pdch(tbf);
- rc = bts->alloc_algorithm(ul_tbf, tbf, bts->alloc_algorithm_curst);
+ rc = bts->alloc_algorithm(ul_tbf, tbf, bts->alloc_algorithm_curst, 0);
/* if no ressource */
if (rc < 0) {
LOGP(DRLCMAC, LOGL_ERROR, "No ressource after update???\n");
@@ -908,10 +944,10 @@ int tbf_update(struct gprs_rlcmac_tbf *tbf)
int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf)
{
if (tbf->control_ts == 0xff)
- LOGP(DRLCMAC, LOGL_DEBUG, "- Setting Control TS %d\n",
+ LOGP(DRLCMAC, LOGL_INFO, "- Setting Control TS %d\n",
tbf->first_common_ts);
else if (tbf->control_ts != tbf->first_common_ts)
- LOGP(DRLCMAC, LOGL_DEBUG, "- Changing Control TS %d\n",
+ LOGP(DRLCMAC, LOGL_INFO, "- Changing Control TS %d\n",
tbf->first_common_ts);
tbf->control_ts = tbf->first_common_ts;
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index b26f58b5..24a84e52 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -83,7 +83,7 @@ struct gprs_rlcmac_bts {
uint8_t n3105;
struct gprs_rlcmac_trx trx[8];
int (*alloc_algorithm)(struct gprs_rlcmac_tbf *old_tbf,
- struct gprs_rlcmac_tbf *tbf, uint32_t cust);
+ struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single);
uint32_t alloc_algorithm_curst; /* options to customize algorithm */
uint8_t force_two_phase;
uint8_t alpha, gamma;
@@ -396,10 +396,10 @@ struct msgb *gprs_rlcmac_send_packet_paging_request(
extern "C" {
#endif
int alloc_algorithm_a(struct gprs_rlcmac_tbf *old_tbf,
- struct gprs_rlcmac_tbf *tbf, uint32_t cust);
+ struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single);
int alloc_algorithm_b(struct gprs_rlcmac_tbf *old_tbf,
- struct gprs_rlcmac_tbf *tbf, uint32_t cust);
+ struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single);
#ifdef __cplusplus
}
#endif
diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp
index c3e49d97..8e9f4711 100644
--- a/src/gprs_rlcmac_data.cpp
+++ b/src/gprs_rlcmac_data.cpp
@@ -1699,7 +1699,9 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment(
if (poll_ass_dl && tbf->direction == GPRS_RLCMAC_DL_TBF
&& tbf->control_ts != tbf->first_common_ts) {
LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink "
- "assigment, because MS cannot reply.\n");
+ "assigment, because MS cannot reply. (control TS=%d, "
+ "first common TS=%d)\n", tbf->control_ts,
+ tbf->first_common_ts);
poll_ass_dl = 0;
}
if (poll_ass_dl) {