aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2012-10-08 12:40:49 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2012-12-18 10:03:50 +0100
commitf01929bcb6b16ecd09108f9851da1f4847de1704 (patch)
tree0e5770a5d2c5b812776f44ce62d9d48fc06b767f
parent8c3680dcc9819c337ab7629e86164b14017aab28 (diff)
Rework on multislot allocation algorithm
The slots are choosen in a way that later selection of slots for concurrent TBFs will have the same downlink/uplink control channel (PACCH). This is required for polling acknowledge of new TBF assignment on PACCH. The MS will always have the same PACCH uplink slot while beeing in packet transfer 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) {