Patch Set 3:

> > I wrote a small test program to encode IA octets in DL IMM ASS
 > 
 > Sounds like a good candidate for bitvec_write_field() test which we
 > don't have yet. Could you please share it?

Here it is. 

#include <stdint.h>

extern "C" {
#include <osmocom/core/bitvec.h>
#include <osmocom/core/utils.h>
}

void *tall_pcu_ctx;
uint8_t tfi = 0;
uint32_t ttli = 0xdeadbeef;
uint8_t gamma = 0;
uint8_t ta_valid = 1;
uint8_t ws_enc = 3;
uint8_t usf = 1;
uint32_t fn = 1234;

/* This function is based implementation of bitvec_write_field_lh in old PCU 
code */
static int bitvec_write_field_lh(struct bitvec *bv, unsigned *write_index, 
uint64_t val, unsigned len)
{
        unsigned int i;
        int rc;
        bv->cur_bit = *write_index;
        for (i = 0; i < len; i++) {
                bit_value bit = L;
                if (val & ((uint64_t)1 << (len - i - 1)))
                        bit = H;
                rc = bitvec_set_bit(bv, bit);
                if (rc)
                        return rc;
        }
        *write_index += len;
        return 0;
}

static void test_bitvec_ia_octet_encode_pkt_dl_ass(bitvec *dest)
{
        unsigned wp = 0;
        printf("=== start %s ===\n", __func__);

        // GSM 04.08 10.5.2.16 IA Rest Octets
        bitvec_write_field(dest, &wp, 3, 2);            // "HH"
        bitvec_write_field(dest, &wp, 1, 2);            // "01" Packet Downlink 
Assignment
        bitvec_write_field(dest, &wp, ttli, 32);        // TLLI
        bitvec_write_field(dest, &wp, 1, 1);            // switch TFI   : on
        bitvec_write_field(dest, &wp, tfi, 5);          // TFI
        bitvec_write_field(dest, &wp, 0x0, 1);          // RLC acknowledged mode
        bitvec_write_field(dest, &wp, 0x0, 1);          // ALPHA = not present
        bitvec_write_field(dest, &wp, gamma, 5);        // GAMMA power control 
parameter
        bitvec_write_field(dest, &wp, 0,1);                     // Polling Bit: 
off
        bitvec_write_field(dest, &wp, ta_valid, 1);     // N. B: NOT related to 
TAI!
        bitvec_write_field(dest, &wp, 0, 1);            // No 
TIMING_ADVANCE_INDEX: */
        bitvec_write_field(dest, &wp, 0, 1);            // TBF Starting TIME 
present
        bitvec_write_field(dest, &wp, 0, 1);            // P0 not present
        bitvec_write_field(dest, &wp, 1, 1);            // "H" - additional for 
R99 -> MS failed to decode following bits
        bitvec_write_field(dest, &wp, ws_enc, 5);       // EGPRS Window Size
        bitvec_write_field(dest, &wp, 0, 2);            // 
LINK_QUALITY_MEASUREMENT_MODE
        bitvec_write_field(dest, &wp, 0, 1);            // BEP_PERIOD2 not 
present

        printf("Encoded PKT DL ASS IA Rest Octets: %s\n", 
osmo_hexdump(dest->data, dest->data_len));

        printf("=== end %s ===\n", __func__);
}

static void test_bitvec_lh_ia_octet_encode_pkt_dl_ass(bitvec *dest)
{
        unsigned wp = 0;
        printf("=== start %s ===\n", __func__);

        // GSM 04.08 10.5.2.16 IA Rest Octets
        bitvec_write_field_lh(dest, &wp, 3, 2);         // "HH"
        bitvec_write_field(dest, &wp, 1, 2);            // "01" Packet Downlink 
Assignment
        bitvec_write_field(dest, &wp, ttli, 32);        // TLLI
        bitvec_write_field(dest, &wp, 1, 1);            // switch TFI   : on
        bitvec_write_field(dest, &wp, tfi, 5);          // TFI
        bitvec_write_field(dest, &wp, 0, 1);            // RLC acknowledged mode
        bitvec_write_field(dest, &wp, 0, 1);            // ALPHA = not present
        bitvec_write_field(dest, &wp, gamma, 5);        // GAMMA power control 
parameter
        bitvec_write_field(dest, &wp, 0,1);                     // Polling Bit: 
off
        bitvec_write_field(dest, &wp, ta_valid, 1);     // N. B: NOT related to 
TAI!
        bitvec_write_field(dest, &wp, 0, 1);            // No 
TIMING_ADVANCE_INDEX: */
        bitvec_write_field(dest, &wp, 0, 1);            // TBF Starting TIME 
present
        bitvec_write_field(dest, &wp, 0, 1);            // P0 not present
        bitvec_write_field_lh(dest, &wp, 3, 1);         // "H" - additional for 
R99 -> MS is happy to decode following bits
        bitvec_write_field(dest, &wp, ws_enc, 5);       // EGPRS Window Size
        bitvec_write_field(dest, &wp, 0, 2);            // 
LINK_QUALITY_MEASUREMENT_MODE
        bitvec_write_field(dest, &wp, 0, 1);            // BEP_PERIOD2 not 
present
        printf("Encoded PKT DL ASS IA Rest Octets: %s\n", 
osmo_hexdump(dest->data, dest->data_len));

        printf("=== end %s ===\n", __func__);
}

static void test_bitvec_ia_octet_encode_pkt_ul_ass(bitvec *dest, bool tbf)
{
        unsigned wp = 0;
        printf("=== start %s ===\n", __func__);

        // 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) {
                bitvec_write_field(dest, &wp, 0, 1);                            
                // Block Allocation : Single Block Allocation
                bitvec_write_field(dest, &wp, 0, 1);                            
                // ALPHA = not present
                bitvec_write_field(dest, &wp, gamma,5);                         
                // GAMMA power control parameter
                bitvec_write_field(dest, &wp, 0, 1);                            
                // No TIMING_ADVANCE_INDEX: */
                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, tfi, 5);                          
                // TFI_ASSIGNMENT Temporary Flow Identity
                bitvec_write_field(dest, &wp, 0, 1);                            
                // POLLING = none
                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, 0, 2);                            
                // CHANNEL_CODING_COMMAND
                bitvec_write_field(dest, &wp, 1, 1);                            
                // TLLI_BLOCK_CHANNEL_CODING
                bitvec_write_field(dest, &wp, 0, 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
        }

        printf("Encoded PKT UL ASS IA Rest Octets: %s\n", 
osmo_hexdump(dest->data, dest->data_len));

        printf("=== end %s ===\n", __func__);
}

static void test_bitvec_lh_ia_octet_encode_pkt_ul_ass(bitvec *dest, bool tbf)
{
        unsigned wp = 0;
        printf("=== start %s ===\n", __func__);

        // GMS 04.08 10.5.2.37b 10.5.2.16
        bitvec_write_field_lh(dest, &wp, 3, 2);                                 
        // "HH"
        bitvec_write_field(dest, &wp, 0, 2);                                    
        // "0" Packet Uplink Assignment
        if (!tbf) {
                bitvec_write_field(dest, &wp, 0, 1);                            
                // Block Allocation : Single Block Allocation
                bitvec_write_field(dest, &wp, 0, 1);                            
                // ALPHA = not present
                bitvec_write_field(dest, &wp, gamma,5);                         
                // GAMMA power control parameter
                bitvec_write_field(dest, &wp, 0, 1);                            
                // No TIMING_ADVANCE_INDEX: */
                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, tfi, 5);                          
                // TFI_ASSIGNMENT Temporary Flow Identity
                bitvec_write_field(dest, &wp, 0, 1);                            
                // POLLING = none
                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, 0, 2);                            
                // CHANNEL_CODING_COMMAND CS 1
                bitvec_write_field(dest, &wp, 1, 1);                            
                // TLLI_BLOCK_CHANNEL_CODING
                bitvec_write_field(dest, &wp, 0, 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
        }

        printf("Encoded PKT UL ASS IA Rest Octets: %s\n", 
osmo_hexdump(dest->data, dest->data_len));

        printf("=== end %s ===\n", __func__);
}

static void test_bitcomp(bitvec *src1, bitvec *src2, int len)
{       int i, j;
        unsigned int bit_err = 0;
        uint8_t byte_err = 0;

        printf("=== start %s ===\n", __func__);

        for (i = 0; i < len; i++) {
                /* byte compare */
                byte_err = src1->data[i] ^ src2->data[i];
                if (byte_err)
                        for (j = 0; j < 8; j++)
                                /* count error bits */
                                bit_err += (byte_err >> j) & 0x01;
        }


        printf("=== total error bits %u ===\n", bit_err);

        printf("=== end %s ===\n", __func__);

}

int main(int argc, char **argv)
{
        bitvec *dest;
        bitvec *dest_lh;

        tall_pcu_ctx = talloc_named_const(NULL, 1, "bitvecTest context");
        if (!tall_pcu_ctx)
                abort();

        dest = bitvec_alloc(22, tall_pcu_ctx);
        dest_lh = bitvec_alloc(22, tall_pcu_ctx);

        /* initialize buffer */
        bitvec_unhex(dest, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
        bitvec_unhex(dest_lh, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");

        test_bitvec_ia_octet_encode_pkt_dl_ass(dest);

        printf("\n\n");

        test_bitvec_lh_ia_octet_encode_pkt_dl_ass(dest_lh);

        printf("\n\n");

        test_bitcomp(dest, dest_lh, 22);

        printf("\n\n");

        /* initialize buffer */
        bitvec_unhex(dest, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
        bitvec_unhex(dest_lh, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");

        test_bitvec_ia_octet_encode_pkt_ul_ass(dest, false);

        printf("\n\n");

        test_bitvec_lh_ia_octet_encode_pkt_ul_ass(dest_lh, false);

        printf("\n\n");

        test_bitcomp(dest, dest_lh, 22);

        printf("\n\n");

        /* initialize buffer */
        bitvec_unhex(dest, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
        bitvec_unhex(dest_lh, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");

        test_bitvec_ia_octet_encode_pkt_ul_ass(dest, true);

        printf("\n\n");

        test_bitvec_lh_ia_octet_encode_pkt_ul_ass(dest_lh, true);

        printf("\n\n");

        test_bitcomp(dest, dest_lh, 22);

        bitvec_free(dest);
        bitvec_free(dest_lh);

        talloc_free(tall_pcu_ctx);
        return EXIT_SUCCESS;
}

-- 
To view, visit https://gerrit.osmocom.org/3991
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I75dd5bebc74eea85edf9582607c774d0bba0d2a6
Gerrit-PatchSet: 3
Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Owner: Minh-Quang Nguyen <[email protected]>
Gerrit-Reviewer: Harald Welte <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Max <[email protected]>
Gerrit-Reviewer: Minh-Quang Nguyen <[email protected]>
Gerrit-HasComments: No

Reply via email to