aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bts.h4
-rw-r--r--src/decoding.cpp63
-rw-r--r--src/decoding.h4
-rw-r--r--src/encoding.cpp5
-rw-r--r--src/gprs_ms.cpp4
-rw-r--r--src/pcu_main.cpp4
6 files changed, 75 insertions, 9 deletions
diff --git a/src/bts.h b/src/bts.h
index a713c46d..807ce084 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -41,6 +41,8 @@ extern "C" {
#define LLC_CODEL_DISABLE 0
#define LLC_CODEL_USE_DEFAULT (-1)
+#define MAX_GPRS_CS 9
+
struct BTS;
struct GprsMs;
@@ -188,7 +190,7 @@ struct gprs_rlcmac_bts {
uint8_t cs_adj_enabled;
uint8_t cs_adj_upper_limit;
uint8_t cs_adj_lower_limit;
- struct {int16_t low; int16_t high;} cs_lqual_ranges[4];
+ struct {int16_t low; int16_t high; } cs_lqual_ranges[MAX_GPRS_CS];
uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */
uint16_t ws_base;
uint16_t ws_pdch; /* increase WS by this value per PDCH */
diff --git a/src/decoding.cpp b/src/decoding.cpp
index e1f8134c..7865be00 100644
--- a/src/decoding.cpp
+++ b/src/decoding.cpp
@@ -357,8 +357,8 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
cur_bit = rlc_parse_ul_data_header_egprs_type_2(rlc, data, cs);
break;
case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1 :
- /* TODO: Support both header type 1 */
- /* fall through */
+ cur_bit = rlc_parse_ul_data_header_egprs_type_1(rlc, data, cs);
+ break;
default:
LOGP(DRLCMACDL, LOGL_ERROR,
"Decoding of uplink %s data blocks not yet supported.\n",
@@ -455,6 +455,65 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_2(
return cur_bit;
}
+int Decoding::rlc_parse_ul_data_header_egprs_type_1(
+ struct gprs_rlc_data_info *rlc,
+ const uint8_t *data, const GprsCodingScheme &cs)
+{
+ struct gprs_rlc_ul_header_egprs_1 *egprs1;
+ unsigned int e_ti_header, cur_bit = 0, offs;
+ int punct, punct2, with_padding;
+
+ egprs1 = static_cast < struct gprs_rlc_ul_header_egprs_1 * >
+ ((void *)data);
+ gprs_rlc_mcs_cps_decode(egprs1->cps, cs, &punct, &punct2,
+ &with_padding);
+ gprs_rlc_data_info_init_ul(rlc, cs, with_padding);
+
+ rlc->r = egprs1->r;
+ rlc->si = egprs1->si;
+ rlc->tfi = (egprs1->tfi_a << 0) | (egprs1->tfi_b << 2);
+ rlc->cps = egprs1->cps;
+ rlc->rsb = egprs1->rsb;
+ rlc->num_data_blocks = 2;
+ rlc->block_info[0].cv = egprs1->cv;
+ rlc->block_info[0].pi = egprs1->pi;
+ rlc->block_info[0].bsn =
+ (egprs1->bsn1_a << 0) | (egprs1->bsn1_b << 5);
+
+ cur_bit += rlc->data_offs_bits[0] - 2;
+ offs = rlc->data_offs_bits[0] / 8;
+ OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 0);
+
+ e_ti_header = data[offs - 1] >> 6;
+ rlc->block_info[0].e = (e_ti_header & 0x01);
+ rlc->block_info[0].ti = !!(e_ti_header & 0x02);
+ cur_bit += 2;
+
+ rlc->block_info[1].cv = egprs1->cv;
+ rlc->block_info[1].pi = egprs1->pi;
+ rlc->block_info[1].bsn = rlc->block_info[0].bsn +
+ ((egprs1->bsn2_a << 0) | (egprs1->bsn2_b << 2));
+ rlc->block_info[1].bsn = rlc->block_info[1].bsn & (RLC_EGPRS_SNS - 1);
+
+ if ((rlc->block_info[1].bsn != rlc->block_info[0].bsn) &&
+ (rlc->block_info[0].cv == 0))
+ rlc->block_info[0].cv = 1;
+
+ cur_bit = rlc->data_offs_bits[1] - 2;
+
+ offs = rlc->data_offs_bits[1] / 8;
+ OSMO_ASSERT(rlc->data_offs_bits[1] % 8 == 2);
+
+ e_ti_header = (data[offs] & (0x03));
+ rlc->block_info[1].e = (e_ti_header & 0x01);
+ rlc->block_info[1].ti = !!(e_ti_header & 0x02);
+ cur_bit += 2;
+ /* skip data area */
+ cur_bit += cs.maxDataBlockBytes() * 8;
+
+ return cur_bit;
+}
+
int Decoding::rlc_parse_ul_data_header_gprs(struct gprs_rlc_data_info *rlc,
const uint8_t *data, const GprsCodingScheme &cs)
{
diff --git a/src/decoding.h b/src/decoding.h
index 736adf10..d1371d53 100644
--- a/src/decoding.h
+++ b/src/decoding.h
@@ -52,6 +52,10 @@ public:
struct gprs_rlc_data_info *rlc,
const uint8_t *data,
const GprsCodingScheme &cs);
+ static int rlc_parse_ul_data_header_egprs_type_1(
+ struct gprs_rlc_data_info *rlc,
+ const uint8_t *data,
+ const GprsCodingScheme &cs);
static int rlc_parse_ul_data_header_gprs(
struct gprs_rlc_data_info *rlc,
const uint8_t *data,
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 2102a1e5..e174c80c 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -610,8 +610,9 @@ static void write_packet_uplink_ack_egprs(
struct gprs_rlcmac_ul_tbf *tbf, bool is_final)
{
bitvec_write_field(dest, wp, 0, 2); // fixed 00
- bitvec_write_field(dest, wp, 2, 4); // CHANNEL_CODING_COMMAND: MCS-3
- // bitvec_write_field(dest, wp, tbf->current_cs() - 1, 4); // CHANNEL_CODING_COMMAND
+ /* CHANNEL_CODING_COMMAND */
+ bitvec_write_field(dest, wp,
+ tbf->current_cs().to_num() - 1, 4);
bitvec_write_field(dest, wp, 0, 1); // 0: no RESEGMENT (nyi)
bitvec_write_field(dest, wp, 1, 1); // PRE_EMPTIVE_TRANSMISSION, TODO: This resembles GPRS, change it?
bitvec_write_field(dest, wp, 0, 1); // 0: no PRR_RETRANSMISSION_REQUEST, TODO: clarify
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index 4296fd33..4f718922 100644
--- a/src/gprs_ms.cpp
+++ b/src/gprs_ms.cpp
@@ -632,8 +632,8 @@ void GprsMs::update_cs_ul(const pcu_l1_meas *meas)
high = bts_data->cs_lqual_ranges[current_cs_num-1].high;
} else if (m_current_cs_ul.isEgprs()) {
/* TODO, use separate table */
- if (current_cs_num > 4)
- current_cs_num = 4;
+ if (current_cs_num > MAX_GPRS_CS)
+ current_cs_num = MAX_GPRS_CS;
low = bts_data->cs_lqual_ranges[current_cs_num-1].low;
high = bts_data->cs_lqual_ranges[current_cs_num-1].high;
} else {
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index f66c6310..2d86cda5 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -189,8 +189,8 @@ int main(int argc, char *argv[])
bts->cs_adj_lower_limit = 10; /* Increase CS if the error rate is below */
bts->max_cs_ul = 4;
bts->max_cs_dl = 4;
- bts->max_mcs_ul = 4;
- bts->max_mcs_dl = 4;
+ bts->max_mcs_ul = MAX_GPRS_CS;
+ bts->max_mcs_dl = MAX_GPRS_CS;
/* CS-1 to CS-4 */
bts->cs_lqual_ranges[0].low = -256;
bts->cs_lqual_ranges[0].high = 6;