diff --git a/src/decoding.cpp b/src/decoding.cpp index f4b539b1..f2b548c1 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -348,16 +348,16 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, const struct rlc_ul_header *gprs; unsigned int e_ti_header; unsigned int cur_bit = 0; - unsigned int data_len = 0; - - rlc->cs = cs; - - data_len = cs.maxDataBlockBytes(); + int punct, punct2, with_padding, cps; + unsigned int offs; switch(cs.headerTypeData()) { case GprsCodingScheme::HEADER_GPRS_DATA: gprs = static_cast ((void *)data); + + gprs_rlc_data_info_init_ul(rlc, cs, false); + rlc->r = gprs->r; rlc->si = gprs->si; rlc->tfi = gprs->tfi; @@ -372,20 +372,23 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, rlc->block_info[0].ti = gprs->ti; rlc->block_info[0].spb = 0; - cur_bit += 3 * 8; - - rlc->data_offs_bits[0] = cur_bit; - rlc->block_info[0].data_len = data_len; - cur_bit += data_len * 8; + cur_bit += rlc->data_offs_bits[0]; + /* skip data area */ + cur_bit += cs.maxDataBlockBytes() * 8; break; case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3: egprs3 = static_cast ((void *)data); + + cps = (egprs3->cps_a << 0) | (egprs3->cps_b << 2); + gprs_rlc_mcs_cps_decode(cps, cs, &punct, &punct2, &with_padding); + gprs_rlc_data_info_init_ul(rlc, cs, with_padding); + rlc->r = egprs3->r; rlc->si = egprs3->si; rlc->tfi = (egprs3->tfi_a << 0) | (egprs3->tfi_b << 2); - rlc->cps = (egprs3->cps_a << 0) | (egprs3->cps_b << 2); + rlc->cps = cps; rlc->rsb = egprs3->rsb; rlc->num_data_blocks = 1; @@ -395,17 +398,18 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, rlc->block_info[0].bsn = (egprs3->bsn1_a << 0) | (egprs3->bsn1_b << 5); - cur_bit += 3 * 8 + 7; + cur_bit += rlc->data_offs_bits[0] - 2; - e_ti_header = (data[3] + (data[4] << 8)) >> 7; + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1); + + e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7; rlc->block_info[0].e = !!(e_ti_header & 0x01); rlc->block_info[0].ti = !!(e_ti_header & 0x02); cur_bit += 2; - rlc->data_offs_bits[0] = cur_bit; - rlc->block_info[0].data_len = data_len; - cur_bit += data_len * 8; - + /* skip data area */ + cur_bit += cs.maxDataBlockBytes() * 8; break; case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1: diff --git a/src/encoding.cpp b/src/encoding.cpp index a7d7b169..6c50abe3 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -762,8 +762,10 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, /* 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 */ + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 2); e_fbi_header <<= 0; - data[5] = (data[5] & 0b11111100) | e_fbi_header; + data[offs] = (data[offs] & 0b11111100) | e_fbi_header; /* second FBI/E header */ e_fbi_header = rlc->block_info[1].e ? 0x01 : 0; @@ -792,8 +794,10 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 6); e_fbi_header <<= 4; - data[3] = (data[3] & 0b11001111) | e_fbi_header; + data[offs] = (data[offs] & 0b11001111) | e_fbi_header; break; case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3: @@ -816,9 +820,11 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc, e_fbi_header = rlc->block_info[0].e ? 0x01 : 0; e_fbi_header |= rlc->block_info[0].cv == 0 ? 0x02 : 0; /* FBI */ + offs = rlc->data_offs_bits[0] / 8; + OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1); e_fbi_header <<= 7; - data[3] = (data[3] & 0b01111111) | (e_fbi_header >> 0); - data[4] = (data[4] & 0b11111110) | (e_fbi_header >> 8); + data[offs-1] = (data[offs-1] & 0b01111111) | (e_fbi_header >> 0); + data[offs] = (data[offs] & 0b11111110) | (e_fbi_header >> 8); break; default: