aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--debian/copyright1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/coding_scheme.c65
-rw-r--r--src/coding_scheme.h17
-rw-r--r--src/decoding.cpp8
-rw-r--r--src/encoding.cpp8
-rw-r--r--src/gprs_bssgp_pcu.cpp3
-rw-r--r--src/gprs_coding_scheme.cpp68
-rw-r--r--src/gprs_coding_scheme.h16
-rw-r--r--src/rlc.cpp8
-rw-r--r--src/tbf_dl.cpp14
-rw-r--r--tests/edge/EdgeTest.cpp9
12 files changed, 126 insertions, 92 deletions
diff --git a/debian/copyright b/debian/copyright
index 2e800a7a..0069d0cc 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -15,6 +15,7 @@ Files: src/gprs_ms_storage.h
src/gprs_ms.h
src/gprs_coding_scheme.cpp
src/gprs_coding_scheme.h
+ src/coding_scheme.c
src/coding_scheme.h
src/cxx_linuxlist.h
src/pcu_vty_functions.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index eb4a2bba..51b047ef 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -63,6 +63,7 @@ libgprs_la_SOURCES = \
rlc.cpp \
osmobts_sock.cpp \
gprs_codel.c \
+ coding_scheme.c \
gprs_coding_scheme.cpp \
egprs_rlc_compression.cpp
diff --git a/src/coding_scheme.c b/src/coding_scheme.c
new file mode 100644
index 00000000..a6f2905c
--- /dev/null
+++ b/src/coding_scheme.c
@@ -0,0 +1,65 @@
+/* coding_scheme.c
+ *
+ * Copyright (C) 2019 by sysmocom s.f.m.c. GmbH
+ *
+ * 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 <stdint.h>
+#include <stdbool.h>
+
+#include <osmocom/core/utils.h>
+
+#include "coding_scheme.h"
+
+static struct {
+ struct {
+ uint8_t data_header_bits;
+ } uplink, downlink;
+ uint8_t data_block_header_bits;
+ uint8_t num_blocks;
+ const char *name;
+} hdr_type_info[NUM_HEADER_TYPES] = {
+ { { 0 }, { 0 }, 0, 0, "INVALID" },
+ { { 1 * 8 + 0 }, { 1 * 8 + 0 }, 0, 0, "CONTROL" },
+ { { 3 * 8 + 0 }, { 3 * 8 + 0 }, 0, 1, "GPRS_DATA" },
+ { { 5 * 8 + 6 }, { 5 * 8 + 0 }, 2, 2, "EGPRS_DATA_TYPE1" },
+ { { 4 * 8 + 5 }, { 3 * 8 + 4 }, 2, 1, "EGPRS_DATA_TYPE2" },
+ { { 3 * 8 + 7 }, { 3 * 8 + 7 }, 2, 1, "EGPRS_DATA_TYPE3" },
+};
+
+uint8_t num_data_blocks(enum HeaderType ht)
+{
+ OSMO_ASSERT(ht < NUM_HEADER_TYPES);
+ return hdr_type_info[ht].num_blocks;
+}
+
+uint8_t num_data_header_bits_UL(enum HeaderType ht)
+{
+ OSMO_ASSERT(ht < NUM_HEADER_TYPES);
+ return hdr_type_info[ht].uplink.data_header_bits;
+}
+
+uint8_t num_data_header_bits_DL(enum HeaderType ht)
+{
+ OSMO_ASSERT(ht < NUM_HEADER_TYPES);
+ return hdr_type_info[ht].downlink.data_header_bits;
+}
+
+uint8_t num_data_block_header_bits(enum HeaderType ht)
+{
+ OSMO_ASSERT(ht < NUM_HEADER_TYPES);
+ return hdr_type_info[ht].data_block_header_bits;
+}
diff --git a/src/coding_scheme.h b/src/coding_scheme.h
index 3705ea42..b0b85e34 100644
--- a/src/coding_scheme.h
+++ b/src/coding_scheme.h
@@ -27,3 +27,20 @@ enum CodingScheme {
MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9,
NUM_SCHEMES
};
+
+enum HeaderType {
+ HEADER_INVALID,
+ HEADER_GPRS_CONTROL,
+ HEADER_GPRS_DATA,
+ HEADER_EGPRS_DATA_TYPE_1,
+ HEADER_EGPRS_DATA_TYPE_2,
+ HEADER_EGPRS_DATA_TYPE_3,
+ NUM_HEADER_TYPES
+};
+
+enum HeaderType headerTypeData(enum CodingScheme mcs);
+
+uint8_t num_data_blocks(enum HeaderType ht);
+uint8_t num_data_header_bits_UL(enum HeaderType ht);
+uint8_t num_data_header_bits_DL(enum HeaderType ht);
+uint8_t num_data_block_header_bits(enum HeaderType ht);
diff --git a/src/decoding.cpp b/src/decoding.cpp
index 0dbb10aa..3410291e 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -355,16 +355,16 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
{
unsigned int cur_bit = 0;
switch(cs.headerTypeData()) {
- case GprsCodingScheme::HEADER_GPRS_DATA :
+ case HEADER_GPRS_DATA :
cur_bit = rlc_parse_ul_data_header_gprs(rlc, data, cs);
break;
- case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3 :
+ case HEADER_EGPRS_DATA_TYPE_3 :
cur_bit = rlc_parse_ul_data_header_egprs_type_3(rlc, data, cs);
break;
- case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2 :
+ case HEADER_EGPRS_DATA_TYPE_2 :
cur_bit = rlc_parse_ul_data_header_egprs_type_2(rlc, data, cs);
break;
- case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1 :
+ case HEADER_EGPRS_DATA_TYPE_1 :
cur_bit = rlc_parse_ul_data_header_egprs_type_1(rlc, data, cs);
break;
default:
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 019de52f..58df95f0 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -1118,7 +1118,7 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc,
unsigned int bsn_delta;
switch(cs.headerTypeData()) {
- case GprsCodingScheme::HEADER_GPRS_DATA:
+ case HEADER_GPRS_DATA:
gprs = static_cast<struct rlc_dl_header *>
((void *)data);
@@ -1134,7 +1134,7 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc,
gprs->bsn = rlc->block_info[0].bsn;
break;
- case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1:
+ case HEADER_EGPRS_DATA_TYPE_1:
egprs1 = static_cast<struct gprs_rlc_dl_header_egprs_1 *>
((void *)data);
@@ -1173,7 +1173,7 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc,
data[offs] = (data[offs] & 0b11110011) | e_fbi_header;
break;
- case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2:
+ case HEADER_EGPRS_DATA_TYPE_2:
egprs2 = static_cast<struct gprs_rlc_dl_header_egprs_2 *>
((void *)data);
@@ -1197,7 +1197,7 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc,
data[offs] = (data[offs] & 0b11001111) | e_fbi_header;
break;
- case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3:
+ case HEADER_EGPRS_DATA_TYPE_3:
egprs3 = static_cast<struct gprs_rlc_dl_header_egprs_3 *>
((void *)data);
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index f63fac30..7ac5ab16 100644
--- a/src/gprs_bssgp_pcu.cpp
+++ b/src/gprs_bssgp_pcu.cpp
@@ -26,6 +26,7 @@
#include <tbf.h>
#include <gprs_coding_scheme.h>
#include <pdch.h>
+#include "coding_scheme.h"
#define BSSGP_TIMER_T1 30 /* Guards the (un)blocking procedures */
#define BSSGP_TIMER_T2 30 /* Guards the reset procedure */
@@ -607,7 +608,7 @@ static unsigned count_pdch(const struct gprs_rlcmac_bts *bts)
static uint32_t gprs_bssgp_max_leak_rate(GprsCodingScheme cs, int num_pdch)
{
- int bytes_per_rlc_block = cs.maxDataBlockBytes() * cs.numDataBlocks();
+ int bytes_per_rlc_block = cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData());
/* n byte payload per 20ms */
return bytes_per_rlc_block * (1000 / 20) * num_pdch;
diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp
index c0955d33..0616a49c 100644
--- a/src/gprs_coding_scheme.cpp
+++ b/src/gprs_coding_scheme.cpp
@@ -82,55 +82,39 @@ static struct {
uint8_t data_bytes;
uint8_t optional_padding_bits;
const char *name;
- GprsCodingScheme::HeaderType data_hdr;
+ enum HeaderType data_hdr;
enum Family family;
} mcs_info[NUM_SCHEMES] = {
{{0, 0}, {0, 0}, 0, 0, "UNKNOWN",
- GprsCodingScheme::HEADER_INVALID, FAMILY_INVALID},
+ HEADER_INVALID, FAMILY_INVALID},
{{23, 0}, {23, 0}, 20, 0, "CS-1",
- GprsCodingScheme::HEADER_GPRS_DATA, FAMILY_INVALID},
+ HEADER_GPRS_DATA, FAMILY_INVALID},
{{33, 7}, {33, 7}, 30, 0, "CS-2",
- GprsCodingScheme::HEADER_GPRS_DATA, FAMILY_INVALID},
+ HEADER_GPRS_DATA, FAMILY_INVALID},
{{39, 3}, {39, 3}, 36, 0, "CS-3",
- GprsCodingScheme::HEADER_GPRS_DATA, FAMILY_INVALID},
+ HEADER_GPRS_DATA, FAMILY_INVALID},
{{53, 7}, {53, 7}, 50, 0, "CS-4",
- GprsCodingScheme::HEADER_GPRS_DATA, FAMILY_INVALID},
+ HEADER_GPRS_DATA, FAMILY_INVALID},
{{26, 1}, {26, 1}, 22, 0, "MCS-1",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
+ HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
{{32, 1}, {32, 1}, 28, 0, "MCS-2",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, FAMILY_B},
+ HEADER_EGPRS_DATA_TYPE_3, FAMILY_B},
{{41, 1}, {41, 1}, 37, 48, "MCS-3",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, FAMILY_A},
+ HEADER_EGPRS_DATA_TYPE_3, FAMILY_A},
{{48, 1}, {48, 1}, 44, 0, "MCS-4",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
+ HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
{{60, 7}, {59, 6}, 56, 0, "MCS-5",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2, FAMILY_B},
+ HEADER_EGPRS_DATA_TYPE_2, FAMILY_B},
{{78, 7}, {77, 6}, 74, 48, "MCS-6",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2, FAMILY_A},
+ HEADER_EGPRS_DATA_TYPE_2, FAMILY_A},
{{118, 2}, {117, 4}, 56, 0, "MCS-7",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, FAMILY_B},
+ HEADER_EGPRS_DATA_TYPE_1, FAMILY_B},
{{142, 2}, {141, 4}, 68, 0, "MCS-8",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
+ HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
{{154, 2}, {153, 4}, 74, 0, "MCS-9",
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
-};
-
-static struct {
- struct {
- uint8_t data_header_bits;
- } uplink, downlink;
- uint8_t data_block_header_bits;
- uint8_t num_blocks;
- const char *name;
-} hdr_type_info[GprsCodingScheme::NUM_HEADER_TYPES] = {
- {{0}, {0}, 0, 0, "INVALID"},
- {{1*8 + 0}, {1*8 + 0}, 0, 0, "CONTROL"},
- {{3*8 + 0}, {3*8 + 0}, 0, 1, "GPRS_DATA"},
- {{5*8 + 6}, {5*8 + 0}, 2, 2, "EGPRS_DATA_TYPE1"},
- {{4*8 + 5}, {3*8 + 4}, 2, 1, "EGPRS_DATA_TYPE2"},
- {{3*8 + 7}, {3*8 + 7}, 2, 1, "EGPRS_DATA_TYPE3"},
+ HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
};
GprsCodingScheme GprsCodingScheme::getBySizeUL(unsigned size)
@@ -210,32 +194,12 @@ uint8_t GprsCodingScheme::optionalPaddingBits() const
return mcs_info[m_scheme].optional_padding_bits;
}
-uint8_t GprsCodingScheme::numDataBlocks() const
-{
- return hdr_type_info[headerTypeData()].num_blocks;
-}
-
-uint8_t GprsCodingScheme::numDataHeaderBitsUL() const
-{
- return hdr_type_info[headerTypeData()].uplink.data_header_bits;
-}
-
-uint8_t GprsCodingScheme::numDataHeaderBitsDL() const
-{
- return hdr_type_info[headerTypeData()].downlink.data_header_bits;
-}
-
-uint8_t GprsCodingScheme::numDataBlockHeaderBits() const
-{
- return hdr_type_info[headerTypeData()].data_block_header_bits;
-}
-
const char *GprsCodingScheme::name() const
{
return mcs_info[m_scheme].name;
}
-GprsCodingScheme::HeaderType GprsCodingScheme::headerTypeData() const
+enum HeaderType GprsCodingScheme::headerTypeData() const
{
return mcs_info[m_scheme].data_hdr;
}
diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h
index 80f85024..56ee0023 100644
--- a/src/gprs_coding_scheme.h
+++ b/src/gprs_coding_scheme.h
@@ -40,16 +40,6 @@ public:
EGPRS,
};
- enum HeaderType {
- HEADER_INVALID,
- HEADER_GPRS_CONTROL,
- HEADER_GPRS_DATA,
- HEADER_EGPRS_DATA_TYPE_1,
- HEADER_EGPRS_DATA_TYPE_2,
- HEADER_EGPRS_DATA_TYPE_3,
- NUM_HEADER_TYPES
- };
-
GprsCodingScheme(CodingScheme s = UNKNOWN);
operator bool() const {return m_scheme != UNKNOWN;}
@@ -83,13 +73,9 @@ public:
uint8_t spareBitsUL() const;
uint8_t spareBitsDL() const;
uint8_t maxDataBlockBytes() const;
- uint8_t numDataBlocks() const;
- uint8_t numDataHeaderBitsUL() const;
- uint8_t numDataHeaderBitsDL() const;
- uint8_t numDataBlockHeaderBits() const;
uint8_t optionalPaddingBits() const;
const char *name() const;
- HeaderType headerTypeData() const;
+ enum HeaderType headerTypeData() const;
static GprsCodingScheme getBySizeUL(unsigned size);
static GprsCodingScheme getGprsByNum(unsigned num);
diff --git a/src/rlc.cpp b/src/rlc.cpp
index 323fde40..e5067c9d 100644
--- a/src/rlc.cpp
+++ b/src/rlc.cpp
@@ -336,7 +336,7 @@ static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc,
rlc->es_p = 0;
rlc->rrbp = 0;
rlc->pr = 0;
- rlc->num_data_blocks = cs.numDataBlocks();
+ rlc->num_data_blocks = num_data_blocks(cs.headerTypeData());
rlc->with_padding = with_padding;
OSMO_ASSERT(rlc->num_data_blocks <= ARRAY_SIZE(rlc->block_info));
@@ -347,7 +347,7 @@ static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc,
rlc->data_offs_bits[i] =
header_bits + padding_bits +
- (i+1) * cs.numDataBlockHeaderBits() +
+ (i+1) * num_data_block_header_bits(cs.headerTypeData()) +
i * 8 * rlc->block_info[0].data_len;
}
}
@@ -356,7 +356,7 @@ void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc,
GprsCodingScheme cs, bool with_padding, const unsigned int spb)
{
return gprs_rlc_data_header_init(rlc, cs, with_padding,
- cs.numDataHeaderBitsDL(), spb);
+ num_data_header_bits_DL(cs.headerTypeData()), spb);
}
void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc,
@@ -367,7 +367,7 @@ void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc,
* for both DL and UL
*/
return gprs_rlc_data_header_init(rlc, cs, with_padding,
- cs.numDataHeaderBitsUL(), 0);
+ num_data_header_bits_UL(cs.headerTypeData()), 0);
}
void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi,
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 7b0052fb..2f4781ca 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -457,7 +457,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
bts->rlc_resent();
}
- *may_combine = m_rlc.block(bsn)->cs_current_trans.numDataBlocks() > 1;
+ *may_combine = num_data_blocks(m_rlc.block(bsn)->cs_current_trans.headerTypeData()) > 1;
return bsn;
}
@@ -1259,7 +1259,7 @@ enum egprs_rlc_dl_reseg_bsn_state
* MCS4: second segment starts at 44/2 = 22
*/
if (cs_current_trans.headerTypeData() ==
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3) {
+ HEADER_EGPRS_DATA_TYPE_3) {
if (*block_status_dl == EGPRS_RESEG_FIRST_SEG_SENT) {
switch (CodingScheme(cs_init)) {
case MCS6 :
@@ -1287,9 +1287,9 @@ enum egprs_rlc_dl_reseg_bsn_state
}
return EGPRS_RESEG_SECOND_SEG_SENT;
} else if ((cs_init.headerTypeData() ==
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1) ||
+ HEADER_EGPRS_DATA_TYPE_1) ||
(cs_init.headerTypeData() ==
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2)) {
+ HEADER_EGPRS_DATA_TYPE_2)) {
return EGPRS_RESEG_FIRST_SEG_SENT;
} else if ((CodingScheme(cs_init) ==
MCS4) &&
@@ -1327,7 +1327,7 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn)
/* Table 10.4.8b.1 of 44.060 */
if (cs_current_trans.headerTypeData() ==
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3) {
+ HEADER_EGPRS_DATA_TYPE_3) {
/*
* if we are sending the second segment the spb should be 3
* other wise it should be 2
@@ -1338,9 +1338,9 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn)
bts->spb_downlink_second_segment();
return EGPRS_RLCMAC_DL_SEC_SEG;
} else if ((cs_init.headerTypeData() ==
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1) ||
+ HEADER_EGPRS_DATA_TYPE_1) ||
(cs_init.headerTypeData() ==
- GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2)) {
+ HEADER_EGPRS_DATA_TYPE_2)) {
bts->spb_downlink_first_segment();
return EGPRS_RLCMAC_DL_FIRST_SEG;
} else if ((CodingScheme(cs_init) ==
diff --git a/tests/edge/EdgeTest.cpp b/tests/edge/EdgeTest.cpp
index 9db90ca1..23abadab 100644
--- a/tests/edge/EdgeTest.cpp
+++ b/tests/edge/EdgeTest.cpp
@@ -71,8 +71,8 @@ static void check_coding_scheme(GprsCodingScheme& cs, GprsCodingScheme::Mode mod
OSMO_ASSERT(expected_size == cs.sizeDL());
/* Check data block sizes */
- OSMO_ASSERT(cs.maxDataBlockBytes() * cs.numDataBlocks() < cs.maxBytesDL());
- OSMO_ASSERT(cs.maxDataBlockBytes() * cs.numDataBlocks() < cs.maxBytesUL());
+ OSMO_ASSERT(cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData()) < cs.maxBytesDL());
+ OSMO_ASSERT(cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData()) < cs.maxBytesUL());
/* Check inc/dec */
new_cs = cs;
@@ -168,8 +168,7 @@ static void test_coding_scheme()
last_size_DL = current_cs.maxBytesDL();
/* Check header types */
- OSMO_ASSERT(current_cs.headerTypeData() ==
- GprsCodingScheme::HEADER_GPRS_DATA);
+ OSMO_ASSERT(current_cs.headerTypeData() == HEADER_GPRS_DATA);
check_coding_scheme(current_cs, GprsCodingScheme::GPRS);
}
@@ -1099,7 +1098,7 @@ static void test_rlc_unaligned_copy()
test_block[cs.maxDataBlockBytes()-1] = pattern ^ 0xff;
for (block_idx = 0;
- block_idx < cs.numDataBlocks();
+ block_idx < num_data_blocks(cs.headerTypeData());
block_idx++)
{
struct gprs_rlc_data_info rlc;