diff options
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/rlc.cpp | 33 | ||||
-rw-r--r-- | src/tbf.cpp | 23 | ||||
-rw-r--r-- | src/tbf.h | 2 |
4 files changed, 50 insertions, 11 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index daa91ec6..beee4c09 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 00000000..4319c499 --- /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 3fd24815..0226691f 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 " @@ -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 */ |