aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/encoding.cpp13
-rw-r--r--src/encoding.h16
-rw-r--r--src/pcu_vty_functions.cpp3
-rw-r--r--src/tbf.cpp91
-rw-r--r--src/tbf.h3
-rw-r--r--src/tbf_dl.cpp31
-rw-r--r--src/tbf_ul.cpp23
7 files changed, 111 insertions, 69 deletions
diff --git a/src/encoding.cpp b/src/encoding.cpp
index a26a5db4..a5e50646 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -169,7 +169,7 @@ void Encoding::write_packet_uplink_assignment(
struct gprs_rlcmac_bts *bts,
bitvec * dest, uint8_t old_tfi,
uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli,
- struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t alpha,
+ struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t rrbp, uint8_t alpha,
uint8_t gamma, int8_t ta_idx, int8_t use_egprs)
{
// TODO We should use our implementation of encode RLC/MAC Control messages.
@@ -275,8 +275,8 @@ void Encoding::write_packet_uplink_assignment(
/* generate downlink assignment */
void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block,
uint8_t old_tfi, uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf,
- uint8_t poll, uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts,
- bool use_egprs)
+ uint8_t poll, uint8_t rrbp, uint8_t alpha, uint8_t gamma, int8_t ta_idx,
+ uint8_t ta_ts, bool use_egprs)
{
// Packet downlink assignment TS 44.060 11.2.7
@@ -286,7 +286,7 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block,
unsigned int ws_enc;
block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header
- block->RRBP = 0x0; // N+13
+ block->RRBP = rrbp; // 0: N+13
block->SP = poll; // RRBP field is valid
block->USF = 0x0; // Uplink state flag
@@ -564,7 +564,8 @@ static void write_packet_uplink_ack_egprs(
void Encoding::write_packet_uplink_ack(
struct gprs_rlcmac_bts *bts, bitvec * dest,
- struct gprs_rlcmac_ul_tbf *tbf, bool is_final)
+ struct gprs_rlcmac_ul_tbf *tbf, bool is_final,
+ uint8_t rrbp)
{
unsigned wp = 0;
@@ -572,7 +573,7 @@ void Encoding::write_packet_uplink_ack(
"(final=%d)\n", tbf_name(tbf), is_final);
bitvec_write_field(dest, wp, 0x1, 2); // Payload Type
- bitvec_write_field(dest, wp, 0x0, 2); // Uplink block with TDMA framenumber (N+13)
+ bitvec_write_field(dest, wp, rrbp, 2); // Uplink block with TDMA framenumber
bitvec_write_field(dest, wp, is_final, 1); // Suppl/Polling Bit
bitvec_write_field(dest, wp, 0x0, 3); // Uplink state flag
bitvec_write_field(dest, wp, 0x9, 6); // MESSAGE TYPE Uplink Ack/Nack
diff --git a/src/encoding.h b/src/encoding.h
index 4c357578..6ee30ac8 100644
--- a/src/encoding.h
+++ b/src/encoding.h
@@ -49,21 +49,23 @@ public:
static void write_packet_uplink_assignment(
struct gprs_rlcmac_bts *bts,
bitvec * dest, uint8_t old_tfi,
- uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli,
- struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t alpha,
- uint8_t gamma, int8_t ta_idx, int8_t use_egprs);
+ uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli,
+ struct gprs_rlcmac_ul_tbf *tbf, uint8_t poll, uint8_t rrbp,
+ uint8_t alpha, uint8_t gamma, int8_t ta_idx,
+ int8_t use_egprs);
static void write_packet_downlink_assignment(RlcMacDownlink_t * block,
uint8_t old_tfi, uint8_t old_downlink,
- struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha,
- uint8_t gamma, int8_t ta_idx, uint8_t ta_ts,
- bool use_egprs);
+ struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t rrbp,
+ uint8_t alpha, uint8_t gamma,
+ int8_t ta_idx, uint8_t ta_ts, bool use_egprs);
static void encode_rbb(const char *show_rbb, uint8_t *rbb);
static void write_packet_uplink_ack(
struct gprs_rlcmac_bts *bts, bitvec * dest,
- struct gprs_rlcmac_ul_tbf *tbf, bool is_final);
+ struct gprs_rlcmac_ul_tbf *tbf, bool is_final,
+ uint8_t rrbp);
static int write_paging_request(bitvec * dest, uint8_t *ptmsi, uint16_t ptmsi_len);
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index 6567962d..3fcd3e60 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -51,7 +51,8 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf)
vty_out(vty, " created=%lu state=%08x 1st_TS=%d 1st_cTS=%d ctrl_TS=%d "
"MS_CLASS=%d/%d%s",
tbf->created_ts(), tbf->state_flags, tbf->first_ts,
- tbf->first_common_ts, tbf->control_ts, tbf->ms_class(),
+ tbf->first_common_ts, tbf->control_ts,
+ tbf->ms_class(),
tbf->ms() ? tbf->ms()->egprs_ms_class() : -1,
VTY_NEWLINE);
vty_out(vty, " TS_alloc=");
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 6e516280..1694bbbc 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -435,6 +435,49 @@ void gprs_rlcmac_tbf::stop_timer()
}
}
+int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts,
+ uint32_t *poll_fn_, unsigned int *rrbp_)
+{
+ uint32_t fn_offs = 13;
+ uint32_t new_poll_fn = (fn + fn_offs) % 2715648;
+
+ if (!is_control_ts(ts)) {
+ LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be "
+ "scheduled in this TS %d (first control TS %d)\n",
+ ts, control_ts);
+ return -EINVAL;
+ }
+ if (poll_state != GPRS_RLCMAC_POLL_NONE) {
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "Polling is already scheduled for %s\n",
+ name());
+ return -EBUSY;
+ }
+ if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) {
+ LOGP(DRLCMAC, LOGL_DEBUG, "%s: Polling is already scheduled "
+ "for single block allocation at FN %d TS %d ...\n",
+ name(), new_poll_fn, ts);
+ return -EBUSY;
+ }
+
+ *poll_fn_ = new_poll_fn;
+ *rrbp_ = 0;
+
+ return 0;
+}
+
+void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts)
+{
+ LOGP(DRLCMAC, LOGL_DEBUG,
+ "%s: Scheduling polling at FN %d TS %d\n",
+ name(), new_poll_fn, ts);
+
+ /* schedule polling */
+ poll_state = GPRS_RLCMAC_POLL_SCHED;
+ poll_fn = new_poll_fn;
+ poll_ts = ts;
+}
+
void gprs_rlcmac_tbf::poll_timeout()
{
LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout for FN=%d, TS=%d (curr FN %d)\n",
@@ -861,6 +904,9 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
struct msgb *msg;
struct gprs_rlcmac_dl_tbf *new_dl_tbf = NULL;
int poll_ass_dl = 1;
+ unsigned int rrbp = 0;
+ uint32_t new_poll_fn = 0;
+ int rc;
if (direction == GPRS_RLCMAC_DL_TBF && !is_control_ts(ts)) {
LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink "
@@ -870,17 +916,17 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
poll_ass_dl = 0;
}
if (poll_ass_dl) {
- if (poll_state != GPRS_RLCMAC_POLL_NONE) {
- LOGP(DRLCMAC, LOGL_DEBUG, "Polling is already sheduled "
- "for %s, so we must wait for downlink "
- "assignment...\n", tbf_name(this));
- return NULL;
- }
- if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) {
+ if (poll_state == GPRS_RLCMAC_POLL_SCHED &&
+ ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK)
+ {
LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
- "scheduled for single block allocation...\n");
+ "scheduled for %s, so we must wait for the uplink "
+ "assignment...\n", tbf_name(this));
return NULL;
}
+ rc = check_polling(fn, ts, &new_poll_fn, &rrbp);
+ if (rc < 0)
+ return NULL;
}
/* on uplink TBF we get the downlink TBF to be assigned. */
@@ -923,7 +969,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
Encoding::write_packet_downlink_assignment(mac_control_block, m_tfi,
(direction == GPRS_RLCMAC_DL_TBF), new_dl_tbf,
- poll_ass_dl, bts_data()->alpha, bts_data()->gamma, -1, 0,
+ poll_ass_dl, rrbp, bts_data()->alpha, bts_data()->gamma, -1, 0,
is_egprs_enabled());
LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n");
encode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
@@ -934,9 +980,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
talloc_free(mac_control_block);
if (poll_ass_dl) {
- poll_state = GPRS_RLCMAC_POLL_SCHED;
- poll_fn = (fn + 13) % 2715648;
- poll_ts = ts;
+ set_polling(new_poll_fn, ts);
dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK;
LOGP(DRLCMACDL, LOGL_INFO,
"%s Scheduled DL Assignment polling on FN=%d, TS=%d\n",
@@ -957,18 +1001,21 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts)
{
struct msgb *msg;
struct gprs_rlcmac_ul_tbf *new_tbf = NULL;
+ int rc;
+ unsigned int rrbp;
+ uint32_t new_poll_fn;
- if (poll_state != GPRS_RLCMAC_POLL_NONE) {
+ if (poll_state == GPRS_RLCMAC_POLL_SCHED &&
+ ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
- "sheduled for %s, so we must wait for uplink "
+ "scheduled for %s, so we must wait for the uplink "
"assignment...\n", tbf_name(this));
return NULL;
}
- if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) {
- LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already scheduled for "
- "single block allocation...\n");
- return NULL;
- }
+
+ rc = check_polling(fn, ts, &new_poll_fn, &rrbp);
+ if (rc < 0)
+ return NULL;
if (ms())
new_tbf = ms()->ul_tbf();
@@ -993,7 +1040,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts)
"2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
Encoding::write_packet_uplink_assignment(bts_data(), ass_vec, m_tfi,
(direction == GPRS_RLCMAC_DL_TBF), tlli(),
- is_tlli_valid(), new_tbf, 1, bts_data()->alpha,
+ is_tlli_valid(), new_tbf, 1, rrbp, bts_data()->alpha,
bts_data()->gamma, -1, is_egprs_enabled());
bitvec_pack(ass_vec, msgb_put(msg, 23));
RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
@@ -1004,9 +1051,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts)
bitvec_free(ass_vec);
talloc_free(mac_control_block);
- poll_state = GPRS_RLCMAC_POLL_SCHED;
- poll_fn = (fn + 13) % 2715648;
- poll_ts = ts;
+ set_polling(new_poll_fn, ts);
ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK;
LOGP(DRLCMACDL, LOGL_INFO,
"%s Scheduled UL Assignment polling on FN=%d, TS=%d\n",
diff --git a/src/tbf.h b/src/tbf.h
index d23cf933..edb8280e 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -119,6 +119,9 @@ struct gprs_rlcmac_tbf {
void stop_t3191();
int establish_dl_tbf_on_pacch();
+ int check_polling(uint32_t fn, uint8_t ts,
+ uint32_t *poll_fn, unsigned int *rrbp);
+ void set_polling(uint32_t poll_fn, uint8_t ts);
void poll_timeout();
/** tlli handling */
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 10b376ff..03f0cc4d 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -527,6 +527,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
bool need_poll;
/* TODO: support MCS-7 - MCS-9, where data_block_idx can be 1 */
unsigned int data_block_idx = 0;
+ unsigned int rrbp;
+ uint32_t new_poll_fn;
+ int rc;
gprs_rlc_data_info rlc;
GprsCodingScheme cs;
@@ -570,32 +573,18 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
"polling, because %d blocks sent.\n",
POLL_ACK_AFTER_FRAMES);
}
- /* scheduling not possible, because: */
- if (poll_state != GPRS_RLCMAC_POLL_NONE)
- LOGP(DRLCMACDL, LOGL_DEBUG, "Polling is already "
- "sheduled for %s, so we must wait for "
- "requesting downlink ack\n", tbf_name(this));
- else if (!is_control_ts(ts))
- LOGP(DRLCMACDL, LOGL_DEBUG, "Polling cannot be "
- "sheduled in this TS %d, waiting for "
- "TS %d\n", ts, control_ts);
- else if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648))
- LOGP(DRLCMACDL, LOGL_DEBUG, "Polling cannot be "
- "sheduled, because single block alllocation "
- "already exists\n");
- else {
- LOGP(DRLCMACDL, LOGL_DEBUG, "Polling sheduled in this "
+
+ rc = check_polling(fn, ts, &new_poll_fn, &rrbp);
+ if (rc >= 0) {
+ set_polling(new_poll_fn, ts);
+
+ LOGP(DRLCMACDL, LOGL_DEBUG, "Polling scheduled in this "
"TS %d\n", ts);
m_tx_counter = 0;
/* start timer whenever we send the final block */
if (rdbi->cv == 0)
tbf_timer_start(this, 3191, bts_data()->t3191, 0);
- /* schedule polling */
- poll_state = GPRS_RLCMAC_POLL_SCHED;
- poll_fn = (fn + 13) % 2715648;
- poll_ts = ts;
-
/* Clear poll timeout flag */
state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
@@ -603,7 +592,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
m_dl_ack_requested = false;
/* set polling in header */
- rlc.rrbp = 0; /* N+13 */
+ rlc.rrbp = rrbp;
rlc.es_p = 1; /* Polling */
m_last_dl_poll_fn = poll_fn;
diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp
index 4754e11f..9e763f4c 100644
--- a/src/tbf_ul.cpp
+++ b/src/tbf_ul.cpp
@@ -91,19 +91,22 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts)
{
int final = (state_is(GPRS_RLCMAC_FINISHED));
struct msgb *msg;
+ int rc;
+ unsigned int rrbp = 0;
+ uint32_t new_poll_fn = 0;
if (final) {
- if (poll_state != GPRS_RLCMAC_POLL_NONE) {
+ if (poll_state == GPRS_RLCMAC_POLL_SCHED &&
+ ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
- "sheduled for %s, so we must wait for "
- "final uplink ack...\n", tbf_name(this));
+ "scheduled for %s, so we must wait for "
+ "the final uplink ack...\n", tbf_name(this));
return NULL;
}
- if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) {
- LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
- "scheduled for single block allocation...\n");
+
+ rc = check_polling(fn, ts, &new_poll_fn, &rrbp);
+ if (rc < 0)
return NULL;
- }
}
msg = msgb_alloc(23, "rlcmac_ul_ack");
@@ -116,7 +119,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts)
}
bitvec_unhex(ack_vec,
"2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
- Encoding::write_packet_uplink_ack(bts_data(), ack_vec, this, final);
+ Encoding::write_packet_uplink_ack(bts_data(), ack_vec, this, final, rrbp);
bitvec_pack(ack_vec, msgb_put(msg, 23));
bitvec_free(ack_vec);
@@ -125,9 +128,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts)
m_contention_resolution_done = 1;
if (final) {
- poll_state = GPRS_RLCMAC_POLL_SCHED;
- poll_fn = (fn + 13) % 2715648;
- poll_ts = ts;
+ set_polling(new_poll_fn, ts);
/* waiting for final acknowledge */
ul_ack_state = GPRS_RLCMAC_UL_ACK_WAIT_ACK;
m_final_ack_sent = 1;