aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2019-02-19 15:37:03 +0100
committerMax <msuraev@sysmocom.de>2019-02-19 18:58:04 +0100
commit0160a29b6c544b0392a44e1e5b2460409e065df5 (patch)
treee1f0191e93520da7a4c5bf6d7ede60516568543a
parentfc8afc2f332c2e595e0429c048bbb55196fe3563 (diff)
Restructure IA Rest Octets encoders
In preparation for upcoming patches with 11 bit RACH and TA support, let's restructure existing encoders to simplify further modifications: * move consistency checks to top-level Imm. Ass. encoder * use consistent formatting * constify pointers where appropriate * split SBA and MBA encoders into separate functions Those changes also make it obvious which parameters are necessary for Rest Octets in each specific case (DL, UL-SBA, UL-MBA, UL-SBA-EGPRS, UL-MBA-EGPRS). There're no functional code changes so there's no need to adjust tests. Change-Id: I0ad1bc786c3a8055ea9666f64ae82c512bd01603 Related: OS#1548
-rw-r--r--src/encoding.cpp255
1 files changed, 132 insertions, 123 deletions
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 2c898196..2648b027 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -87,18 +87,11 @@ static inline void write_ta_ie(bitvec *dest, unsigned& wp,
bitvec_write_field(dest, &wp, ts, 3);
}
-static int write_ia_rest_downlink(
- gprs_rlcmac_dl_tbf *tbf,
- bitvec * dest, unsigned& wp,
- bool polling, bool ta_valid, uint32_t fn,
- uint8_t alpha, uint8_t gamma, int8_t ta_idx)
+static int write_ia_rest_downlink(const gprs_rlcmac_dl_tbf *tbf, bitvec * dest, bool polling, bool ta_valid,
+ uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx, unsigned& wp)
{
- if (!tbf) {
- LOGP(DRLCMACDL, LOGL_ERROR,
- "Cannot encode DL IMMEDIATE ASSIGNMENT without TBF\n");
- return -EINVAL;
- }
- // GSM 04.08 10.5.2.16 IA Rest Octets
+ int rc = 0;
+
bitvec_write_field(dest, &wp, 3, 2); // "HH"
bitvec_write_field(dest, &wp, 1, 2); // "01" Packet Downlink Assignment
bitvec_write_field(dest, &wp,tbf->tlli(),32); // TLLI
@@ -127,128 +120,126 @@ static int write_ia_rest_downlink(
// bitvec_write_field(dest, &wp,0x1,1); // P0 not present
// bitvec_write_field(dest, &wp,,0xb,4);
if (tbf->is_egprs_enabled()) {
- /* see GMS 44.018, 10.5.2.16 */
bitvec_write_field(dest, &wp, 1, 1); // "H"
write_ws(dest, &wp, tbf->window_size()); // EGPRS Window Size
bitvec_write_field(dest, &wp, 0x0, 2); // LINK_QUALITY_MEASUREMENT_MODE
bitvec_write_field(dest, &wp, 0, 1); // BEP_PERIOD2 not present
}
- return 0;
+ return rc;
}
-static int write_ia_rest_uplink(
- gprs_rlcmac_ul_tbf *tbf,
- bitvec * dest, unsigned& wp,
- uint8_t usf, uint32_t fn,
- uint8_t alpha, uint8_t gamma, int8_t ta_idx)
+static int write_ia_rest_uplink_sba(bitvec *dest, uint32_t fn, uint8_t alpha, uint8_t gamma, int8_t ta_idx,
+ unsigned& wp)
{
- OSMO_ASSERT(!tbf || !tbf->is_egprs_enabled());
-
- // GMS 04.08 10.5.2.37b 10.5.2.16
- bitvec_write_field(dest, &wp, 3, 2); // "HH"
- bitvec_write_field(dest, &wp, 0, 2); // "0" Packet Uplink Assignment
- if (tbf == NULL) {
- bitvec_write_field(dest, &wp, 0, 1); // Block Allocation : Single Block Allocation
- if (alpha) {
- bitvec_write_field(dest, &wp,0x1,1); // ALPHA = present
- bitvec_write_field(dest, &wp,alpha,4); // ALPHA = present
- } else
- bitvec_write_field(dest, &wp,0x0,1); // ALPHA = not present
- bitvec_write_field(dest, &wp,gamma,5); // GAMMA power control parameter
- write_tai(dest, wp, ta_idx);
- bitvec_write_field(dest, &wp, 1, 1); // TBF_STARTING_TIME_FLAG
- bitvec_write_field(dest, &wp,(fn / (26 * 51)) % 32,5); // T1'
- bitvec_write_field(dest, &wp,fn % 51,6); // T3
- bitvec_write_field(dest, &wp,fn % 26,5); // T2
- } else {
- bitvec_write_field(dest, &wp, 1, 1); // Block Allocation : Not Single Block Allocation
- bitvec_write_field(dest, &wp, tbf->tfi(), 5); // TFI_ASSIGNMENT Temporary Flow Identity
- bitvec_write_field(dest, &wp, 0, 1); // POLLING
- bitvec_write_field(dest, &wp, 0, 1); // ALLOCATION_TYPE: dynamic
- bitvec_write_field(dest, &wp, usf, 3); // USF
- bitvec_write_field(dest, &wp, 0, 1); // USF_GRANULARITY
- bitvec_write_field(dest, &wp, 0, 1); // "0" power control: Not Present
- bitvec_write_field(dest, &wp, tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND
- bitvec_write_field(dest, &wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING
- if (alpha) {
- bitvec_write_field(dest, &wp,0x1,1); // ALPHA = present
- bitvec_write_field(dest, &wp,alpha,4); // ALPHA
- } else
- bitvec_write_field(dest, &wp,0x0,1); // ALPHA = not present
- bitvec_write_field(dest, &wp,gamma,5); // GAMMA power control parameter
- /* note: there is no choise for TAI and no starting time */
- bitvec_write_field(dest, &wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off
- bitvec_write_field(dest, &wp, 0, 1); // TBF_STARTING_TIME_FLAG
- }
- return 0;
+ int rc = 0;
+
+ bitvec_write_field(dest, &wp, 0, 1); // Block Allocation: Single Block Allocation
+
+ if (alpha) {
+ bitvec_write_field(dest, &wp, 0x1, 1); // ALPHA = present
+ bitvec_write_field(dest, &wp, alpha, 4);
+ } else
+ bitvec_write_field(dest, &wp, 0x0, 1); // ALPHA = not present
+
+ bitvec_write_field(dest, &wp, gamma, 5); // GAMMA power control parameter
+ write_tai(dest, wp, ta_idx);
+ bitvec_write_field(dest, &wp, 1, 1); // TBF_STARTING_TIME_FLAG
+ bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5); // T1'
+ bitvec_write_field(dest, &wp, fn % 51, 6); // T3
+ bitvec_write_field(dest, &wp, fn % 26, 5); // T2
+
+ return rc;
}
-static int write_ia_rest_egprs_uplink(
- gprs_rlcmac_ul_tbf *tbf,
- bitvec * dest, unsigned& wp,
- uint8_t usf, uint32_t fn,
- uint8_t alpha, uint8_t gamma, int8_t ta_idx,
- enum ph_burst_type burst_type, uint16_t ra)
+static int write_ia_rest_uplink_mba(const gprs_rlcmac_ul_tbf *tbf, bitvec *dest, uint8_t usf,
+ uint8_t alpha, uint8_t gamma, unsigned& wp)
{
- uint8_t extended_ra = 0;
+ int rc = 0;
+
+ bitvec_write_field(dest, &wp, 1, 1); // Block Allocation: Not Single Block Allocation
+ bitvec_write_field(dest, &wp, tbf->tfi(), 5); // TFI_ASSIGNMENT Temporary Flow Identity
+ bitvec_write_field(dest, &wp, 0, 1); // POLLING
+ bitvec_write_field(dest, &wp, 0, 1); // ALLOCATION_TYPE: dynamic
+ bitvec_write_field(dest, &wp, usf, 3); // USF
+ bitvec_write_field(dest, &wp, 0, 1); // USF_GRANULARITY
+ bitvec_write_field(dest, &wp, 0, 1); // "0" power control: Not Present
+ bitvec_write_field(dest, &wp, tbf->current_cs().to_num() - 1, 2); // CHANNEL_CODING_COMMAND
+ bitvec_write_field(dest, &wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING
+ if (alpha) {
+ bitvec_write_field(dest, &wp, 0x1, 1); // ALPHA = present
+ bitvec_write_field(dest, &wp, alpha, 4); // ALPHA
+ } else
+ bitvec_write_field(dest, &wp, 0x0, 1); // ALPHA = not present
+
+ bitvec_write_field(dest, &wp, gamma, 5); // GAMMA power control parameter
- extended_ra = (ra & 0x1F);
+ /* note: there is no choise for TAI and no starting time */
+ bitvec_write_field(dest, &wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off
+ bitvec_write_field(dest, &wp, 0, 1); // TBF_STARTING_TIME_FLAG
- bitvec_write_field(dest, &wp, 1, 2); /* LH */
- bitvec_write_field(dest, &wp, 0, 2); /* 0 EGPRS Uplink Assignment */
- bitvec_write_field(dest, &wp, extended_ra, 5); /* Extended RA */
- bitvec_write_field(dest, &wp, 0, 1); /* Access technology Request */
+ return rc;
+}
- if (tbf == NULL) {
+static int write_ia_rest_egprs_uplink_mba(bitvec * dest, uint32_t fn, uint8_t alpha, uint8_t gamma, unsigned& wp)
+{
+ int rc = 0;
- bitvec_write_field(dest, &wp, 0, 1); /* multiblock allocation */
+ bitvec_write_field(dest, &wp, 0, 1); /* multiblock allocation */
- if (alpha) {
- bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA =yes */
- bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */
- } else {
- bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */
- }
+ if (alpha) {
+ bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA =yes */
+ bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */
+ } else {
+ bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */
+ }
- bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */
- bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5);/* T1' */
- bitvec_write_field(dest, &wp, fn % 51, 6); /* T3 */
- bitvec_write_field(dest, &wp, fn % 26, 5); /* T2 */
- bitvec_write_field(dest, &wp, 0, 2); /* Radio block allocation */
+ bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */
+ bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5);/* T1' */
+ bitvec_write_field(dest, &wp, fn % 51, 6); /* T3 */
+ bitvec_write_field(dest, &wp, fn % 26, 5); /* T2 */
+ bitvec_write_field(dest, &wp, 0, 2); /* Radio block allocation */
- bitvec_write_field(dest, &wp, 0, 1);
+ bitvec_write_field(dest, &wp, 0, 1);
- } else {
- bitvec_write_field(dest, &wp, 1, 1); /* single block alloc */
- bitvec_write_field(dest, &wp, tbf->tfi(), 5);/* TFI assignment */
- bitvec_write_field(dest, &wp, 0, 1); /* polling bit */
- bitvec_write_field(dest, &wp, 0, 1); /* constant */
- bitvec_write_field(dest, &wp, usf, 3); /* USF bit */
- bitvec_write_field(dest, &wp, 0, 1); /* USF granularity */
- bitvec_write_field(dest, &wp, 0, 1); /* P0 */
- /* MCS */
- bitvec_write_field(dest, &wp, tbf->current_cs().to_num()-1, 4);
- /* tlli channel block */
- bitvec_write_field(dest, &wp, tbf->tlli(), 1);
- bitvec_write_field(dest, &wp, 0, 1); /* BEP period present */
- bitvec_write_field(dest, &wp, 0, 1); /* resegmentation */
- write_ws(dest, &wp, tbf->window_size()); /* EGPRS window size */
-
- if (alpha) {
- bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA =yes */
- bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */
- } else {
- bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */
- }
+ return rc;
+}
+
+static int write_ia_rest_egprs_uplink_sba(const gprs_rlcmac_ul_tbf *tbf, bitvec * dest, uint8_t usf,
+ uint8_t alpha, uint8_t gamma, unsigned& wp)
+{
+ int rc = 0;
+
+ bitvec_write_field(dest, &wp, 1, 1); /* single block allocation */
+ bitvec_write_field(dest, &wp, tbf->tfi(), 5); /* TFI assignment */
+ bitvec_write_field(dest, &wp, 0, 1); /* polling bit */
+ bitvec_write_field(dest, &wp, 0, 1); /* constant */
+ bitvec_write_field(dest, &wp, usf, 3); /* USF bit */
+ bitvec_write_field(dest, &wp, 0, 1); /* USF granularity */
+ bitvec_write_field(dest, &wp, 0, 1); /* P0 */
- bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */
- bitvec_write_field(dest, &wp, 0, 1); /* TIMING_ADVANCE_INDEX */
- bitvec_write_field(dest, &wp, 0, 1); /* TBF_STARTING_TIME_FLAG */
- bitvec_write_field(dest, &wp, 0, 1); /* NULL */
+ /* MCS */
+ bitvec_write_field(dest, &wp, tbf->current_cs().to_num() - 1, 4);
+
+ /* TLLI channel block */
+ bitvec_write_field(dest, &wp, tbf->tlli(), 1);
+ bitvec_write_field(dest, &wp, 0, 1); /* BEP period present */
+ bitvec_write_field(dest, &wp, 0, 1); /* resegmentation */
+ write_ws(dest, &wp, tbf->window_size()); /* EGPRS window size */
+
+ if (alpha) {
+ bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA = yes */
+ bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */
+ } else {
+ bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */
}
- return 0;
+ bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */
+ bitvec_write_field(dest, &wp, 0, 1); /* TIMING_ADVANCE_INDEX */
+ bitvec_write_field(dest, &wp, 0, 1); /* TBF_STARTING_TIME_FLAG */
+ bitvec_write_field(dest, &wp, 0, 1); /* NULL */
+
+ return rc;
}
/*
@@ -396,19 +387,37 @@ int Encoding::write_immediate_assignment(
plen = wp / 8;
- if (downlink)
- rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, wp,
- polling, gsm48_ta_is_valid(ta), fn,
- alpha, gamma, ta_idx);
- else if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) ||
- (burst_type == GSM_L1_BURST_TYPE_ACCESS_2)))
- rc = write_ia_rest_egprs_uplink(as_ul_tbf(tbf), dest, wp,
- usf, fn,
- alpha, gamma, ta_idx, burst_type, ra);
- else
- rc = write_ia_rest_uplink(as_ul_tbf(tbf), dest, wp,
- usf, fn,
- alpha, gamma, ta_idx);
+ /* 3GPP TS 44.018 ยง10.5.2.16 IA Rest Octets */
+ if (downlink) {
+ if (!as_dl_tbf(tbf)) {
+ LOGP(DRLCMACDL, LOGL_ERROR, "Cannot encode DL IMMEDIATE ASSIGNMENT without TBF\n");
+ return -EINVAL;
+ }
+ rc = write_ia_rest_downlink(as_dl_tbf(tbf), dest, polling, gsm48_ta_is_valid(ta), fn, alpha, gamma,
+ ta_idx, wp);
+ } else if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) {
+ bitvec_write_field(dest, &wp, 1, 2); /* LH */
+ bitvec_write_field(dest, &wp, 0, 2); /* 0 EGPRS Uplink Assignment */
+ bitvec_write_field(dest, &wp, ra & 0x1F, 5); /* Extended RA */
+ bitvec_write_field(dest, &wp, 0, 1); /* Access technology Request */
+
+ if (as_ul_tbf(tbf) != NULL) {
+ rc = write_ia_rest_egprs_uplink_sba(as_ul_tbf(tbf), dest, usf, alpha, gamma, wp);
+ } else {
+ rc = write_ia_rest_egprs_uplink_mba(dest, fn, alpha, gamma, wp);
+ }
+ } else {
+ OSMO_ASSERT(!tbf || !tbf->is_egprs_enabled());
+
+ bitvec_write_field(dest, &wp, 3, 2); // "HH"
+ bitvec_write_field(dest, &wp, 0, 2); // "0" Packet Uplink Assignment
+
+ if (as_ul_tbf(tbf) != NULL) {
+ rc = write_ia_rest_uplink_mba(as_ul_tbf(tbf), dest, usf, alpha, gamma, wp);
+ } else {
+ rc = write_ia_rest_uplink_sba(dest, fn, alpha, gamma, ta_idx, wp);
+ }
+ }
if (rc < 0) {
LOGP(DRLCMAC, LOGL_ERROR,