aboutsummaryrefslogtreecommitdiffstats
path: root/src/encoding.cpp
diff options
context:
space:
mode:
authorPravin Kumarvel <pmanohar@radisys.com>2016-12-29 20:05:28 +0530
committerPravin Kumarvel <pmanohar@radisys.com>2016-12-29 20:05:28 +0530
commit17ee61703200271cfe86486c007b1d2d03ba24ee (patch)
tree24168c9e70d36164f4893b876b24fb0cf75d0fb1 /src/encoding.cpp
parent366931baa646a7e7fb74e9021f37d5de1c0df033 (diff)
Add compression support in EGPRS PUAN
This adds compression of bitmap in PUAN. The compressed bitmap is used only if the number of bits in the bitmap does not fit in the message and there is a gain after compression. The algorithm is part of libosmocore and so there is dependency on the libosmocore for compilation. The algorithm is tested on integration setup by forcing compression.
Diffstat (limited to 'src/encoding.cpp')
-rw-r--r--src/encoding.cpp131
1 files changed, 108 insertions, 23 deletions
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 8fa4bf6..ea38b77 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -24,6 +24,7 @@
#include <bts.h>
#include <tbf.h>
#include <gprs_debug.h>
+#include <egprs_rlc_compression.h>
extern "C" {
#include <osmocom/gprs/protocol/gsm_04_60.h>
@@ -699,20 +700,44 @@ static void write_packet_uplink_ack_gprs(
static void write_packet_ack_nack_desc_egprs(
struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp,
- gprs_rlc_ul_window *window, bool is_final)
+ gprs_rlc_ul_window *window, bool is_final, unsigned& rest_bits)
{
- int urbb_len = 0;
- int len;
+ unsigned int urbb_len = 0;
+ uint8_t crbb_len = 0;
+ uint8_t len;
bool bow = true;
bool eow = true;
int ssn = window->mod_sns(window->v_q() + 1);
- int num_blocks = window->mod_sns(window->v_r() - window->v_q());
+ unsigned int num_blocks = window->mod_sns(window->v_r() - window->v_q());
int esn_crbb = window->mod_sns(ssn - 1);
- /* Bit 0 at the end is mandatory Table 11.2.28.1 in 44.060 */
- int rest_bits = dest->data_len * 8 - wp - 1;
+ static uint8_t rbb[RLC_EGPRS_MAX_WS] = {'\0'};
+ uint8_t iter = 0;
int is_compressed = 0;
+ bool try_compression = false;
+ uint8_t ucmp_bmplen;
+ uint8_t crbb_bitmap[23] = {'\0'};
+ bitvec ucmp_vec;
+ bitvec crbb_vec;
+ uint8_t uclen_crbb = 0;
bool len_coded = true;
+ uint8_t crbb_start_clr_code;
uint8_t i;
+#if 0
+ /* static size of 16 bits*/
+ ..0. .... = ACKNACK: (Union)
+ Desc
+
+ ...0 .... = FINAL_ACK_INDICATION: False
+
+ .... 1... = BEGINNING_OF_WINDOW: 1
+
+ .... .1.. = END_OF_WINDOW: 1
+
+ .... ..10 0101 0001 1... .... = STARTING_SEQUENCE_NUMBER: 1187
+
+ .0.. .... = CRBB Exist: 0
+#endif
+ rest_bits -= 16;
if (num_blocks > 0)
/* V(Q) is NACK and omitted -> SSN = V(Q) + 1 */
@@ -720,27 +745,67 @@ static void write_packet_ack_nack_desc_egprs(
if (num_blocks > window->ws())
num_blocks = window->ws();
- /* TODO Compression support */
- if (is_compressed == 0) {
- /* Union bit takes 1 bit */
- /* Other fields in descr for uncompresed bitmap takes 15 bits*/
+ /* Try Compression as number of blocks does not fit */
+ if (num_blocks > rest_bits) {
+ try_compression = true;
+ }
+ if (try_compression == true) {
+ ucmp_bmplen = window->update_egprs_rbb(rbb);
+ ucmp_vec.data = rbb;
+ ucmp_vec.cur_bit = ucmp_bmplen;
+ ucmp_vec.data_len = 127;
+ crbb_vec.data = crbb_bitmap;
+ crbb_vec.cur_bit = 0;
+ crbb_vec.data_len = 127;
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "rest_bits=%d uncompressed len %d and uncompressed bitmap = %s\n",
+ rest_bits, ucmp_bmplen,
+ osmo_hexdump(ucmp_vec.data, (ucmp_bmplen+7)/8));
+
+ is_compressed = egprs_compress::compress_rbb(&ucmp_vec, /* Uncompressed bitmap*/
+ &crbb_vec, /*Compressed bitmap vector */
+ &uclen_crbb,
+ (rest_bits - 16));/* CRBBlength:7 colourcode:1 dissector length:8*/
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "the ucmp len=%d uclen_crbb=%d num_blocks=%d crbb length %d, "
+ "and the CRBB bitmap = %s\n",
+ ucmp_bmplen, uclen_crbb, num_blocks, crbb_vec.cur_bit,
+ osmo_hexdump(crbb_bitmap, (crbb_vec.cur_bit+7)/8));
+ crbb_len = crbb_vec.cur_bit;
+ }
- if (num_blocks > rest_bits - 15 - 1) {
+ if (is_compressed == 0) {
+ /* length field takes 8 bits*/
+ if (num_blocks > rest_bits - 8) {
eow = false;
- urbb_len = rest_bits - 15 - 1;
+ urbb_len = rest_bits;
len_coded = false;
- } else if (num_blocks == rest_bits - 15 - 1) {
- urbb_len = rest_bits - 15 - 1;
+ } else if (num_blocks == rest_bits) {
+ urbb_len = rest_bits;
len_coded = false;
- /* Union bit takes 1 bit length field takes 8 bits*/
- } else if (num_blocks > rest_bits - 15 - 9) {
- eow = false;
- urbb_len = rest_bits - 15 - 9;
} else
urbb_len = num_blocks;
+
len = urbb_len + 15;
} else {
- /* TODO Compressed bitmap */
+ if (num_blocks > uclen_crbb) {
+ eow = false;
+ urbb_len = num_blocks - uclen_crbb;
+ }
+ /* Union bit takes 1 bit */
+ /* Other fields in descr of compresed bitmap takes 23 bits
+ * -8 = CRBB_STARTING_COLOR_CODE + CRBB_LENGTH */
+ if (urbb_len > (rest_bits - crbb_len - 8)) {
+ eow = false;
+ len_coded = false;
+ urbb_len = rest_bits - crbb_len - 8;
+ /* -16 = ACKNACK Dissector length + CRBB_STARTING_COLOR_CODE + CRBB_LENGTH */
+ } else if (urbb_len > (rest_bits - crbb_len - 16)) {
+ eow = false;
+ len_coded = false;
+ urbb_len = rest_bits - crbb_len - 16;
+ }
+ len = urbb_len + crbb_len + 23;
}
/* EGPRS Ack/Nack Description IE */
@@ -756,14 +821,32 @@ static void write_packet_ack_nack_desc_egprs(
bitvec_write_field(dest, wp, eow, 1); // END_OF_WINDOW
bitvec_write_field(dest, wp, ssn, 11); // STARTING_SEQUENCE_NUMBER
if (is_compressed) {
- /* TODO Add CRBB support */
- } else
+ bitvec_write_field(dest, wp, 1, 1); // CRBB_Exist
+ bitvec_write_field(dest, wp, crbb_len, 7); // CRBB_LENGTH
+ crbb_start_clr_code = (0x80 & ucmp_vec.data[0])>>7;
+ bitvec_write_field(dest, wp, crbb_start_clr_code, 1); // CRBB_clr_code
+ LOGP(DRLCMACUL, LOGL_DEBUG,
+ "EGPRS CRBB, crbb_len = %d, crbb_start_clr_code = %d\n",
+ crbb_len, crbb_start_clr_code);
+ while (crbb_len != 0) {
+ if (crbb_len > 8) {
+ bitvec_write_field(dest, wp, crbb_bitmap[iter], 8);
+ crbb_len = crbb_len - 8;
+ iter++;
+ } else {
+ bitvec_write_field(dest, wp, crbb_bitmap[iter], crbb_len);
+ crbb_len = 0;
+ }
+ }
+ esn_crbb = window->mod_sns(esn_crbb + uclen_crbb);
+ } else {
bitvec_write_field(dest, wp, 0, 1); // CRBB_Exist
+ }
LOGP(DRLCMACUL, LOGL_DEBUG,
"EGPRS URBB, urbb len = %d, SSN = %d, ESN_CRBB = %d, "
"len present = %s,desc len = %d, "
"SNS = %d, WS = %d, V(Q) = %d, V(R) = %d%s%s\n",
- urbb_len, ssn, esn_crbb, len_coded ? "yes" : "No", len,
+ urbb_len, ssn, esn_crbb, len_coded ? "yes" : "No" , len,
window->sns(), window->ws(), window->v_q(), window->v_r(),
bow ? ", BOW" : "", eow ? ", EOW" : "");
@@ -795,7 +878,9 @@ static void write_packet_uplink_ack_egprs(
bitvec_write_field(dest, wp, 0, 1); // 0: don't have Power Control Parameters
bitvec_write_field(dest, wp, 0, 1); // 0: don't have Extension Bits
- write_packet_ack_nack_desc_egprs(bts, dest, wp, &tbf->m_window, is_final);
+ /* -2 for last bit 0 mandatory and REL5 not supported */
+ unsigned bits_ack_nack = dest->data_len * 8 - wp - 2;
+ write_packet_ack_nack_desc_egprs(bts, dest, wp, &tbf->m_window, is_final, bits_ack_nack);
bitvec_write_field(dest, wp, 0, 1); // fixed 0
bitvec_write_field(dest, wp, 0, 1); // 0: don't have REL 5