aboutsummaryrefslogtreecommitdiffstats
path: root/src/encoding.cpp
diff options
context:
space:
mode:
authorsivasankari <Sivasankari.Theerthagiri@radisys.com>2017-01-16 15:41:21 +0530
committerHarald Welte <laforge@gnumonks.org>2017-01-23 12:26:09 +0000
commit8adfcd06a1db8033467d30b21ad7f6f35d6bf919 (patch)
tree8682b76a777bb0924f7f70606c3dfbca61460cf7 /src/encoding.cpp
parent127a1e07504e555a53072d34e65ca7838c905edb (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. Change-Id: Id2eec4b5eb6da0ebd24054b541b09b700b9b40ba
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 8fa4bf60..ea38b77f 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