aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am3
-rw-r--r--src/rlc.cpp33
-rw-r--r--src/tbf.cpp23
-rw-r--r--src/tbf.h2
4 files changed, 50 insertions, 11 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index daa91ec..beee4c0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -48,7 +48,8 @@ libgprs_la_SOURCES = \
ta.cpp \
sba.cpp \
decoding.cpp \
- llc.cpp
+ llc.cpp \
+ rlc.cpp
if ENABLE_SYSMOBTS
libgprs_la_SOURCES += \
diff --git a/src/rlc.cpp b/src/rlc.cpp
new file mode 100644
index 0000000..4319c49
--- /dev/null
+++ b/src/rlc.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 by Holger Hans Peter Freyther
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "tbf.h"
+
+extern "C" {
+#include <osmocom/core/utils.h>
+}
+
+
+uint8_t *gprs_rlc_data::prepare(size_t block_data_len)
+{
+ /* todo.. only set it once if it turns out to be a bottleneck */
+ memset(block, 0x0, ARRAY_SIZE(block));
+ memset(block, 0x2b, block_data_len);
+
+ return block;
+}
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 3fd2481..0226691 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -878,8 +878,6 @@ struct msgb *gprs_rlcmac_tbf::create_dl_acked_block(uint32_t fn, uint8_t ts)
{
struct rlc_dl_header *rh;
struct rlc_li_field *li;
- uint8_t block_length; /* total length of block, including spare bits */
- uint8_t block_data; /* usable data of block, w/o spare bits, inc. MAC */
struct msgb *msg;
uint8_t bsn;
uint16_t mod_sns = sns - 1;
@@ -966,18 +964,21 @@ do_resend:
LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d\n",
dir.dl.v_s);
- /* now we still have untransmitted LLC data, so we fill mac block */
- index = dir.dl.v_s & mod_sns_half;
- data = m_rlc.blocks[index].block;
#warning "Selection of the CS doesn't belong here"
if (cs == 0) {
cs = bts_data()->initial_cs_dl;
if (cs < 1 || cs > 4)
cs = 1;
}
- block_length = gprs_rlcmac_cs[cs].block_length;
- block_data = gprs_rlcmac_cs[cs].block_data;
- memset(data, 0x2b, block_data); /* spare bits will be left 0 */
+ /* total length of block, including spare bits */
+ const uint8_t block_length = gprs_rlcmac_cs[cs].block_length;
+ /* length of usable data of block, w/o spare bits, inc. MAC */
+ const uint8_t block_data_len = gprs_rlcmac_cs[cs].block_data;
+
+ /* now we still have untransmitted LLC data, so we fill mac block */
+ index = dir.dl.v_s & mod_sns_half;
+ data = m_rlc.blocks[index].prepare(block_data_len);
+
rh = (struct rlc_dl_header *)data;
rh->pt = 0; /* Data Block */
rh->rrbp = rh->s_p = 0; /* Polling, set later, if required */
@@ -988,9 +989,9 @@ do_resend:
rh->bsn = dir.dl.v_s; /* Block Sequence Number */
rh->e = 0; /* Extension bit, maybe set later */
e_pointer = data + 2; /* points to E of current chunk */
- data += 3;
+ data += sizeof(*rh);
delimiter = data; /* where next length header would be stored */
- space = block_data - 3;
+ space = block_data_len - sizeof(*rh);
while (1) {
chunk = m_llc.chunk_size();
/* if chunk will exceed block limit */
@@ -1107,6 +1108,7 @@ do_resend:
}
LOGP(DRLCMACDL, LOGL_DEBUG, "data block: %s\n",
osmo_hexdump(m_rlc.blocks[index].block, block_length));
+#warning "move this up?"
m_rlc.blocks[index].len = block_length;
/* raise send state and set ack state array */
dir.dl.v_b[index] = 'U'; /* unacked */
@@ -1152,6 +1154,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_acked_block(
LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be "
"sheduled in this TS %d, waiting for "
"TS %d\n", ts, control_ts);
+#warning "What happens to the first_fin_ack in case something is already scheduled?"
else if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648))
LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be "
"sheduled, because single block alllocation "
diff --git a/src/tbf.h b/src/tbf.h
index bf5f32d..e95ed20 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -86,6 +86,8 @@ enum gprs_rlcmac_tbf_direction {
#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */
struct gprs_rlc_data {
+ uint8_t *prepare(size_t block_data_length);
+
/* block history */
uint8_t block[RLC_MAX_LEN];
/* block len of history */