diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2016-02-02 11:48:37 +0100 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2016-02-02 17:06:39 +0100 |
commit | 1a880da4f9548145dfc8cbe54fd7f6c3eb9edc1b (patch) | |
tree | 2b32fc38ca57b87e96ac0dd1a6ea9719b33742cf /src/encoding.cpp | |
parent | 205a943205ac2c65e14c012bac8c936a6a642c44 (diff) |
rlc: Support encoding of EGPRS header type 1 + 2
Currently only header type 3 (MCS-1 to MCS-4) is supported.
Add header structs to rlc.h and extend
Encoding::rlc_write_dl_data_header accordingly.
Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/encoding.cpp')
-rw-r--r-- | src/encoding.cpp | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/src/encoding.cpp b/src/encoding.cpp index e3e1245e..7a6abb75 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -711,10 +711,13 @@ unsigned Encoding::write_repeated_page_info(bitvec * dest, unsigned& wp, uint8_t int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, uint8_t *data) { + struct gprs_rlc_dl_header_egprs_1 *egprs1; + struct gprs_rlc_dl_header_egprs_2 *egprs2; struct gprs_rlc_dl_header_egprs_3 *egprs3; struct rlc_dl_header *gprs; unsigned int e_fbi_header; GprsCodingScheme cs = rlc->cs; + unsigned int offs; switch(cs.headerTypeData()) { case GprsCodingScheme::HEADER_GPRS_DATA: @@ -733,6 +736,62 @@ 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: + egprs1 = static_cast<struct gprs_rlc_dl_header_egprs_1 *> + ((void *)data); + + egprs1->usf = rlc->usf; + egprs1->es_p = rlc->es_p; + egprs1->rrbp = rlc->rrbp; + egprs1->tfi_a = rlc->tfi >> 0; /* 1 bit LSB */ + egprs1->tfi_b = rlc->tfi >> 1; /* 4 bits */ + egprs1->pr = rlc->pr; + egprs1->cps = rlc->cps; + + egprs1->bsn1_a = rlc->block_info[0].bsn >> 0; /* 2 bits LSB */ + egprs1->bsn1_b = rlc->block_info[0].bsn >> 2; /* 8 bits */ + egprs1->bsn1_c = rlc->block_info[0].bsn >> 10; /* 1 bit */ + + egprs1->bsn2_a = rlc->block_info[1].bsn >> 0; /* 7 bits LSB */ + egprs1->bsn2_b = rlc->block_info[1].bsn >> 7; /* 3 bits */ + + /* first FBI/E header */ + e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; + e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + e_fbi_header <<= 0; + data[5] = (data[5] & 0b11111100) | e_fbi_header; + + /* second FBI/E header */ + e_fbi_header = rlc->block_info[1].e ? 0x01 : 0; + e_fbi_header |= rlc->block_info[1].cv == 0 ? 0x02 : 0; /* FBI */ + offs = rlc->data_offs_bits[1] / 8; + OSMO_ASSERT(rlc->data_offs_bits[1] % 8 == 4); + e_fbi_header <<= 2; + data[offs] = (data[offs] & 0b11110011) | e_fbi_header; + break; + + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2: + egprs2 = static_cast<struct gprs_rlc_dl_header_egprs_2 *> + ((void *)data); + + egprs2->usf = rlc->usf; + egprs2->es_p = rlc->es_p; + egprs2->rrbp = rlc->rrbp; + egprs2->tfi_a = rlc->tfi >> 0; /* 1 bit LSB */ + egprs2->tfi_b = rlc->tfi >> 1; /* 4 bits */ + egprs2->pr = rlc->pr; + egprs2->cps = rlc->cps; + + egprs2->bsn1_a = rlc->block_info[0].bsn >> 0; /* 2 bits LSB */ + egprs2->bsn1_b = rlc->block_info[0].bsn >> 2; /* 8 bits */ + egprs2->bsn1_c = rlc->block_info[0].bsn >> 10; /* 1 bit */ + + e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; + e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + e_fbi_header <<= 4; + data[3] = (data[3] & 0b11001111) | e_fbi_header; + break; + case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3: egprs3 = static_cast<struct gprs_rlc_dl_header_egprs_3 *> ((void *)data); @@ -758,10 +817,6 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, data[4] = (data[4] & 0b11111110) | (e_fbi_header >> 8); break; - case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1: - case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2: - /* TODO: Support both header types */ - /* fall through */ default: LOGP(DRLCMACDL, LOGL_ERROR, "Encoding of uplink %s data blocks not yet supported.\n", |