forked from cellular-infrastructure/osmo-pcu
Add test case for decompression profiling
Add test case to collect the decompression profiling data and to compare tree based algorithm with existing algorithm. note:tbf test suite fails due to log comparison failure. For getting the profiling data gettimeofday is used and timing varies during each iterations.
This commit is contained in:
parent
624471e672
commit
0a918983f3
|
@ -26,22 +26,41 @@
|
|||
#include "pcu_utils.h"
|
||||
#include "gprs_bssgp_pcu.h"
|
||||
#include "pcu_l1_if.h"
|
||||
|
||||
#include "egprs_rlc_compression.h"
|
||||
#include "decoding.h"
|
||||
extern "C" {
|
||||
#include "pcu_vty.h"
|
||||
|
||||
#include <osmocom/core/bitcomp.h>
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/vty/vty.h>
|
||||
}
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define NUMBER_OF_TEST_CASE 4
|
||||
#define NEW 1
|
||||
void *tall_pcu_ctx;
|
||||
int16_t spoof_mnc = 0, spoof_mcc = 0;
|
||||
|
||||
struct test_data {
|
||||
int8_t crbb_len;
|
||||
uint8_t cc ;
|
||||
uint8_t data[23];
|
||||
uint8_t exp_data[40];
|
||||
int exp_len;
|
||||
}test[4] = { { (int8_t)67, (uint8_t)1,{0x02, 0x0c, 0xa0, 0x30, 0xcb, 0x1a, 0x0c, 0xe3, 0x6c},
|
||||
{0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,
|
||||
0xdb}, (int)194},
|
||||
{ (int8_t)40, (uint8_t)1,{0x53, 0x06, 0xc5, 0x40, 0x6d}, { 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf8, 0x00, 0x00, 0x00, 0x00, 0x03}, (int)182},
|
||||
{ (int8_t)6, (uint8_t)1, {0x1c}, {0x80}, (int)1},
|
||||
{ (int8_t)103,(uint8_t)1, {0x02, 0x0c, 0xe0, 0x41, 0xa0, 0x0c, 0x36, 0x0d, 0x03,
|
||||
0x71, 0xb0, 0x6e, 0x24}, {0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,
|
||||
0xe0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff} ,
|
||||
(int)288} };
|
||||
static void check_tbf(gprs_rlcmac_tbf *tbf)
|
||||
{
|
||||
OSMO_ASSERT(tbf);
|
||||
|
@ -50,32 +69,336 @@ static void check_tbf(gprs_rlcmac_tbf *tbf)
|
|||
if (tbf->state_is(GPRS_RLCMAC_RELEASING))
|
||||
OSMO_ASSERT(tbf->T != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
static unsigned inc_fn(fn)
|
||||
static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
|
||||
RlcMacUplink_t *ulreq, unsigned fn)
|
||||
{
|
||||
unsigned next_fn;
|
||||
|
||||
next_fn = fn + 4;
|
||||
if ((block_nr % 3) == 2)
|
||||
next_fn ++;
|
||||
next_fn = next_fn % 2715648;
|
||||
|
||||
return next_fn;
|
||||
bitvec *rlc_block;
|
||||
uint8_t buf[64];
|
||||
int num_bytes;
|
||||
struct gprs_rlcmac_pdch *pdch;
|
||||
struct pcu_l1_meas meas;
|
||||
meas.set_rssi(31);
|
||||
rlc_block = bitvec_alloc(23);
|
||||
encode_gsm_rlcmac_uplink(rlc_block, ulreq);
|
||||
num_bytes = bitvec_pack(rlc_block, &buf[0]);
|
||||
OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
|
||||
bitvec_free(rlc_block);
|
||||
the_bts->set_current_block_frame_number(fn, 0);
|
||||
pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
|
||||
pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
|
||||
}
|
||||
*/
|
||||
static void send_control_ack(gprs_rlcmac_tbf *tbf)
|
||||
{
|
||||
RlcMacUplink_t ulreq = {0};
|
||||
OSMO_ASSERT(tbf->poll_fn != 0);
|
||||
OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
|
||||
ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
|
||||
Packet_Control_Acknowledgement_t *ctrl_ack =
|
||||
&ulreq.u.Packet_Control_Acknowledgement;
|
||||
ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
|
||||
ctrl_ack->TLLI = tbf->tlli();
|
||||
send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
|
||||
&ulreq, tbf->poll_fn);
|
||||
}
|
||||
static unsigned fn2bn(unsigned fn)
|
||||
{
|
||||
return (fn % 52) / 4;
|
||||
}
|
||||
static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
|
||||
{
|
||||
unsigned bn = fn2bn(fn) + blocks;
|
||||
fn = fn - (fn % 52);
|
||||
fn += bn * 4 + bn / 3;
|
||||
return fn % 2715648;
|
||||
}
|
||||
static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
|
||||
{
|
||||
gprs_rlcmac_bts *bts;
|
||||
gprs_rlcmac_trx *trx;
|
||||
bts = the_bts->bts_data();
|
||||
bts->alloc_algorithm = alloc_algorithm_a;
|
||||
bts->initial_cs_dl = cs;
|
||||
bts->initial_cs_ul = cs;
|
||||
trx = &bts->trx[0];
|
||||
trx->pdch[ts_no].enable();
|
||||
}
|
||||
static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
|
||||
uint8_t trx_no, uint8_t ts_no, uint16_t arfcn,
|
||||
uint32_t *fn, uint8_t *block_nr = NULL)
|
||||
{
|
||||
uint8_t bn = fn2bn(*fn);
|
||||
gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, arfcn, *fn, bn);
|
||||
*fn = fn_add_blocks(*fn, 1);
|
||||
bn += 1;
|
||||
if (block_nr)
|
||||
*block_nr = bn;
|
||||
}
|
||||
static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
|
||||
uint32_t *fn, uint8_t *block_nr = NULL)
|
||||
{
|
||||
request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
|
||||
tbf->control_ts, tbf->trx->arfcn, fn, block_nr);
|
||||
}
|
||||
enum test_tbf_final_ack_mode {
|
||||
TEST_MODE_STANDARD,
|
||||
TEST_MODE_REVERSE_FREE
|
||||
};
|
||||
static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb_pdan(BTS *the_bts,
|
||||
uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
|
||||
uint8_t ms_class, uint8_t egprs_ms_class)
|
||||
{
|
||||
GprsMs *ms;
|
||||
uint32_t rach_fn = *fn - 51;
|
||||
uint32_t sba_fn = *fn + 52;
|
||||
uint8_t trx_no = 0;
|
||||
int tfi = 0;
|
||||
gprs_rlcmac_ul_tbf *ul_tbf;
|
||||
struct gprs_rlcmac_pdch *pdch;
|
||||
gprs_rlcmac_bts *bts;
|
||||
RlcMacUplink_t ulreq = {0};
|
||||
struct pcu_l1_meas meas;
|
||||
struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
|
||||
GprsCodingScheme cs;
|
||||
meas.set_rssi(31);
|
||||
bts = the_bts->bts_data();
|
||||
/* send fake data */
|
||||
uint8_t data_msg[23] = {
|
||||
0x40,0x20,0x0a,0x7f,0x79,0x61,0x00,0x49,0x2b,0x4c,0x00,0xe1,0xf2,0xe9,0xfe,0xae,0x7a,0x00,0xf0,0x30,0x3b,0x2b,0x2b};
|
||||
pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
|
||||
pdch->rcv_block(&data_msg[0], 23, *fn, &meas);
|
||||
}
|
||||
static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
|
||||
uint8_t egprs_ms_class, uint8_t *trx_no_)
|
||||
{
|
||||
gprs_rlcmac_bts *bts;
|
||||
int tfi;
|
||||
uint8_t trx_no;
|
||||
gprs_rlcmac_dl_tbf *dl_tbf;
|
||||
bts = the_bts->bts_data();
|
||||
tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
|
||||
OSMO_ASSERT(tfi >= 0);
|
||||
dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, 1);
|
||||
check_tbf(dl_tbf);
|
||||
/* "Establish" the DL TBF */
|
||||
dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
|
||||
dl_tbf->set_state(GPRS_RLCMAC_FLOW);
|
||||
dl_tbf->m_wait_confirm = 0;
|
||||
*trx_no_ = trx_no;
|
||||
return dl_tbf;
|
||||
}
|
||||
static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
|
||||
int mcs)
|
||||
{
|
||||
unsigned i;
|
||||
uint8_t ms_class = 11;
|
||||
uint8_t egprs_ms_class = 11;
|
||||
uint32_t fn = 0;
|
||||
uint8_t trx_no;
|
||||
uint32_t tlli = 0xffeeddcc;
|
||||
uint8_t test_data[512];
|
||||
uint8_t rbb[64/8];
|
||||
gprs_rlcmac_dl_tbf *dl_tbf;
|
||||
memset(test_data, 1, sizeof(test_data));
|
||||
the_bts->bts_data()->initial_mcs_dl = mcs;
|
||||
dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
|
||||
dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
|
||||
for (i = 0; i < sizeof(test_data); i++)
|
||||
test_data[i] = i%256;
|
||||
OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
|
||||
/* Schedule a LLC frame
|
||||
* passing only 100 bytes, since it is enough to construct
|
||||
* 2 RLC data blocks. Which are enough to test Header Type 1
|
||||
* cases
|
||||
*/
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 100);
|
||||
OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
|
||||
return dl_tbf;
|
||||
}
|
||||
static void establish_and_use_egprs_dl_tbf_pdan(BTS *the_bts,
|
||||
int mcs, int demanded_mcs)
|
||||
{
|
||||
uint32_t fn = 0;
|
||||
gprs_rlcmac_dl_tbf *dl_tbf;
|
||||
uint8_t block_nr = 0;
|
||||
int index1 = 0;
|
||||
int itr = 0 ;
|
||||
uint8_t bn;
|
||||
struct msgb *msg;
|
||||
struct gprs_rlc_dl_header_egprs_3 *egprs3;
|
||||
int ts_no = 4;
|
||||
uint32_t fn1 = 26;
|
||||
uint16_t qta = 31;
|
||||
uint32_t tlli = 0xf1223344;
|
||||
const char *imsi = "0011223344";
|
||||
uint8_t ms_class = 1;
|
||||
uint8_t egprs_ms_class = 1;
|
||||
gprs_rlcmac_ul_tbf *ul_tbf;
|
||||
GprsMs *ms;
|
||||
uint8_t test_data[1900] = { 0 };
|
||||
printf("Testing for pdan MCS %d to reseg_mcs %d\n", mcs, demanded_mcs);
|
||||
/* Table 10.4.8a.3.1 of 44.060 */
|
||||
dl_tbf = tbf_init(the_bts, mcs);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 1400);
|
||||
for (itr ; itr < 150; itr++) {
|
||||
fn = fn_add_blocks(fn, 1);
|
||||
/* Send first RLC data block BSN 0 */
|
||||
msg = dl_tbf->create_dl_acked_block(fn, dl_tbf->control_ts);
|
||||
}
|
||||
fn1 = dl_tbf->poll_fn;
|
||||
ul_tbf = establish_ul_tbf_two_phase_spb_pdan(the_bts, ts_no, tlli, &fn1, qta,
|
||||
ms_class, egprs_ms_class);
|
||||
}
|
||||
/* To verify the result with expected result */
|
||||
int check_result(bitvec bits, uint8_t *exp_data, int exp_len)
|
||||
{
|
||||
if (bits.cur_bit != exp_len)
|
||||
return 0;
|
||||
size_t n = (exp_len / 8);
|
||||
int rem = (exp_len % 8);
|
||||
if (memcmp (exp_data, bits.data, n) == 0) {
|
||||
if (rem == 0)
|
||||
return 1;
|
||||
int i = 0, bytes = 7;
|
||||
|
||||
for (i ; i < rem ; i++) {
|
||||
if (((((bits.data[n]))>>(bytes-i)) & 1) == ((((*(exp_data + n))>>(bytes-i)) & 1)))
|
||||
;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (i == rem) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* To check time taken to decode crbb by Existing method
|
||||
* and to verify the result with expected result */
|
||||
void test_EPDAN_time_osmot4(int test_run, int verify)
|
||||
{
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "\nMaster decoding osmo_t4");
|
||||
int itr = 0;
|
||||
long long int min_master = 0, max_master = 0, avg_master = 0 ;
|
||||
bitvec bits;
|
||||
struct bitvec data1;
|
||||
struct timeval t0, t1;
|
||||
data1.data = test[itr].data;
|
||||
uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
|
||||
|
||||
for (itr ; itr < NUMBER_OF_TEST_CASE ; itr++) {
|
||||
int loop = 0, init_flag = 1;
|
||||
avg_master = 0 ;
|
||||
while (loop++ < test_run) {
|
||||
data1.data_len = ((test[itr].crbb_len + 7)/8);
|
||||
data1.cur_bit = test[itr].crbb_len;
|
||||
|
||||
bits.data = bits_data;
|
||||
bits.data_len = sizeof(bits_data);
|
||||
bits.cur_bit = 0;
|
||||
bits.cur_bit = 0;
|
||||
|
||||
gettimeofday(&t0, 0);
|
||||
osmo_t4_decode(&data1, test[itr].cc, &bits);
|
||||
gettimeofday(&t1, 0);
|
||||
long long elapsed = (t1.tv_sec-t0.tv_sec)*1000000LL + t1.tv_usec-t0.tv_usec;
|
||||
if (init_flag) {
|
||||
min_master = elapsed;
|
||||
max_master = elapsed;
|
||||
init_flag = 0 ;
|
||||
}
|
||||
if (verify) {
|
||||
if (check_result (bits, test[itr].exp_data, test[itr].exp_len) == 0) {
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "Master decoding :Error\n");
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
}
|
||||
if (min_master >= elapsed) {
|
||||
min_master = elapsed;
|
||||
} else {
|
||||
max_master = elapsed;
|
||||
}
|
||||
avg_master = avg_master + elapsed;
|
||||
}
|
||||
avg_master = (avg_master / test_run);
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG,
|
||||
"\nTest case number :%d \nTime elapsed:\nmin = %Ld\n"
|
||||
"max = %Ld\navg = %Ld\n", itr+1, min_master, max_master, avg_master) ;
|
||||
}
|
||||
}
|
||||
/* To check time taken to decode crbb by Tree based method
|
||||
* and to verify the result with expected result */
|
||||
void test_EPDAN_time_tree(int test_run, int verify)
|
||||
{
|
||||
LOGP (DRLCMACDL, LOGL_DEBUG, "Tree based decoding");
|
||||
int itr = 0;
|
||||
long long int min_tree = 0, max_tree = 0, avg_tree = 0;
|
||||
bitvec bits;
|
||||
struct bitvec data1;
|
||||
|
||||
for (itr ; itr < NUMBER_OF_TEST_CASE ; itr++) {
|
||||
int loop = 0, init_flag = 1;
|
||||
avg_tree = 0;
|
||||
|
||||
while (loop++ < test_run) {
|
||||
data1.data_len = ((test[itr].crbb_len + 7)/8);
|
||||
data1.cur_bit = test[itr].crbb_len;
|
||||
|
||||
struct timeval t0, t1;
|
||||
|
||||
data1.data = test[itr].data;
|
||||
uint8_t bits_data[RLC_EGPRS_MAX_WS/8];
|
||||
|
||||
bits.data = bits_data;
|
||||
bits.data_len = sizeof(bits_data);
|
||||
bits.cur_bit = 0;
|
||||
gettimeofday(&t0, 0);
|
||||
Decoding::decompress_crbb(test[itr].crbb_len, test[itr].cc, test[itr].data, &bits);
|
||||
gettimeofday(&t1, 0);
|
||||
|
||||
long long elapsed = (t1.tv_sec-t0.tv_sec)*1000000LL + t1.tv_usec-t0.tv_usec;
|
||||
|
||||
if (init_flag) {
|
||||
min_tree = elapsed;
|
||||
max_tree = elapsed;
|
||||
init_flag = 0;
|
||||
}
|
||||
if (verify) {
|
||||
if (check_result(bits, test[itr].exp_data, test[itr].exp_len) == 0) {
|
||||
LOGP (DRLCMACDL, LOGL_DEBUG, "Tree based decoding :Error\n");
|
||||
OSMO_ASSERT(0) ;
|
||||
}
|
||||
}
|
||||
if (min_tree >= elapsed) {
|
||||
min_tree = elapsed;
|
||||
}else {
|
||||
max_tree = elapsed;
|
||||
}
|
||||
avg_tree = avg_tree + elapsed;
|
||||
}
|
||||
avg_tree = (avg_tree / test_run);
|
||||
LOGP(DRLCMACDL, LOGL_DEBUG, "\nTest case number :%d\nTime elapsed:\n"
|
||||
"min = %Ld\nmax = %Ld\navg = %Ld\n", itr+1, min_tree, max_tree, avg_tree);
|
||||
}
|
||||
}
|
||||
static void test_tbf_base()
|
||||
{
|
||||
|
||||
printf("=== start %s ===\n", __func__);
|
||||
|
||||
OSMO_ASSERT(GPRS_RLCMAC_DL_TBF == reverse(GPRS_RLCMAC_UL_TBF));
|
||||
OSMO_ASSERT(GPRS_RLCMAC_UL_TBF == reverse(GPRS_RLCMAC_DL_TBF));
|
||||
|
||||
printf("=== end %s ===\n", __func__);
|
||||
}
|
||||
|
||||
static void test_tbf_tlli_update()
|
||||
{
|
||||
BTS the_bts;
|
||||
|
@ -132,103 +455,18 @@ static void test_tbf_tlli_update()
|
|||
ms_new = the_bts.ms_by_tlli(0x4232);
|
||||
OSMO_ASSERT(ms_new != NULL);
|
||||
OSMO_ASSERT(ms_new->ta() == 4);
|
||||
|
||||
OSMO_ASSERT(ul_tbf->ta() == 4);
|
||||
OSMO_ASSERT(dl_tbf->ta() == 4);
|
||||
|
||||
ul_tbf->set_ta(6);
|
||||
|
||||
OSMO_ASSERT(ul_tbf->ta() == 6);
|
||||
OSMO_ASSERT(dl_tbf->ta() == 6);
|
||||
|
||||
printf("=== end %s ===\n", __func__);
|
||||
}
|
||||
|
||||
static uint8_t llc_data[200];
|
||||
|
||||
int pcu_sock_send(struct msgb *msg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_bts(BTS *the_bts, uint8_t ts_no, uint8_t cs = 1)
|
||||
{
|
||||
gprs_rlcmac_bts *bts;
|
||||
gprs_rlcmac_trx *trx;
|
||||
|
||||
bts = the_bts->bts_data();
|
||||
bts->alloc_algorithm = alloc_algorithm_a;
|
||||
bts->initial_cs_dl = cs;
|
||||
bts->initial_cs_ul = cs;
|
||||
trx = &bts->trx[0];
|
||||
|
||||
trx->pdch[ts_no].enable();
|
||||
}
|
||||
|
||||
static gprs_rlcmac_dl_tbf *create_dl_tbf(BTS *the_bts, uint8_t ms_class,
|
||||
uint8_t egprs_ms_class, uint8_t *trx_no_)
|
||||
{
|
||||
gprs_rlcmac_bts *bts;
|
||||
int tfi;
|
||||
uint8_t trx_no;
|
||||
|
||||
gprs_rlcmac_dl_tbf *dl_tbf;
|
||||
|
||||
bts = the_bts->bts_data();
|
||||
|
||||
tfi = the_bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx_no, -1);
|
||||
OSMO_ASSERT(tfi >= 0);
|
||||
dl_tbf = tbf_alloc_dl_tbf(bts, NULL, trx_no, ms_class, egprs_ms_class, 1);
|
||||
check_tbf(dl_tbf);
|
||||
|
||||
/* "Establish" the DL TBF */
|
||||
dl_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
|
||||
dl_tbf->set_state(GPRS_RLCMAC_FLOW);
|
||||
dl_tbf->m_wait_confirm = 0;
|
||||
check_tbf(dl_tbf);
|
||||
|
||||
*trx_no_ = trx_no;
|
||||
|
||||
return dl_tbf;
|
||||
}
|
||||
|
||||
static unsigned fn2bn(unsigned fn)
|
||||
{
|
||||
return (fn % 52) / 4;
|
||||
}
|
||||
|
||||
static unsigned fn_add_blocks(unsigned fn, unsigned blocks)
|
||||
{
|
||||
unsigned bn = fn2bn(fn) + blocks;
|
||||
fn = fn - (fn % 52);
|
||||
fn += bn * 4 + bn / 3;
|
||||
return fn % 2715648;
|
||||
}
|
||||
|
||||
static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts,
|
||||
uint8_t trx_no, uint8_t ts_no, uint16_t arfcn,
|
||||
uint32_t *fn, uint8_t *block_nr = NULL)
|
||||
{
|
||||
uint8_t bn = fn2bn(*fn);
|
||||
gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, arfcn, *fn, bn);
|
||||
*fn = fn_add_blocks(*fn, 1);
|
||||
bn += 1;
|
||||
if (block_nr)
|
||||
*block_nr = bn;
|
||||
}
|
||||
|
||||
static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf,
|
||||
uint32_t *fn, uint8_t *block_nr = NULL)
|
||||
{
|
||||
request_dl_rlc_block(tbf->bts->bts_data(), tbf->trx->trx_no,
|
||||
tbf->control_ts, tbf->trx->arfcn, fn, block_nr);
|
||||
}
|
||||
|
||||
enum test_tbf_final_ack_mode {
|
||||
TEST_MODE_STANDARD,
|
||||
TEST_MODE_REVERSE_FREE
|
||||
};
|
||||
|
||||
static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
|
||||
{
|
||||
BTS the_bts;
|
||||
|
@ -240,14 +478,10 @@ static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode)
|
|||
uint8_t trx_no;
|
||||
GprsMs *ms;
|
||||
uint32_t tlli = 0xffeeddcc;
|
||||
|
||||
uint8_t rbb[64/8];
|
||||
|
||||
printf("=== start %s ===\n", __func__);
|
||||
|
||||
gprs_rlcmac_dl_tbf *dl_tbf;
|
||||
gprs_rlcmac_tbf *new_tbf;
|
||||
|
||||
setup_bts(&the_bts, ts_no);
|
||||
dl_tbf = create_dl_tbf(&the_bts, ms_class, 0, &trx_no);
|
||||
dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
|
||||
|
@ -566,57 +800,12 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(BTS *the_bts,
|
|||
uint8_t(tlli >> 24), uint8_t(tlli >> 16),
|
||||
uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */
|
||||
};
|
||||
|
||||
pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
|
||||
pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas);
|
||||
|
||||
ms = the_bts->ms_by_tlli(tlli);
|
||||
OSMO_ASSERT(ms != NULL);
|
||||
|
||||
return ul_tbf;
|
||||
}
|
||||
|
||||
static void send_ul_mac_block(BTS *the_bts, unsigned trx_no, unsigned ts_no,
|
||||
RlcMacUplink_t *ulreq, unsigned fn)
|
||||
{
|
||||
bitvec *rlc_block;
|
||||
uint8_t buf[64];
|
||||
int num_bytes;
|
||||
struct gprs_rlcmac_pdch *pdch;
|
||||
struct pcu_l1_meas meas;
|
||||
|
||||
meas.set_rssi(31);
|
||||
|
||||
rlc_block = bitvec_alloc(23);
|
||||
|
||||
encode_gsm_rlcmac_uplink(rlc_block, ulreq);
|
||||
num_bytes = bitvec_pack(rlc_block, &buf[0]);
|
||||
OSMO_ASSERT(size_t(num_bytes) < sizeof(buf));
|
||||
bitvec_free(rlc_block);
|
||||
|
||||
the_bts->set_current_block_frame_number(fn, 0);
|
||||
|
||||
pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no];
|
||||
pdch->rcv_block(&buf[0], num_bytes, fn, &meas);
|
||||
}
|
||||
|
||||
static void send_control_ack(gprs_rlcmac_tbf *tbf)
|
||||
{
|
||||
RlcMacUplink_t ulreq = {0};
|
||||
|
||||
OSMO_ASSERT(tbf->poll_fn != 0);
|
||||
OSMO_ASSERT(tbf->is_control_ts(tbf->poll_ts));
|
||||
|
||||
ulreq.u.MESSAGE_TYPE = MT_PACKET_CONTROL_ACK;
|
||||
Packet_Control_Acknowledgement_t *ctrl_ack =
|
||||
&ulreq.u.Packet_Control_Acknowledgement;
|
||||
|
||||
ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK;
|
||||
ctrl_ack->TLLI = tbf->tlli();
|
||||
send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->poll_ts,
|
||||
&ulreq, tbf->poll_fn);
|
||||
}
|
||||
|
||||
static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
|
||||
uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta,
|
||||
uint8_t ms_class, uint8_t egprs_ms_class)
|
||||
|
@ -1488,46 +1677,6 @@ static void establish_and_use_egprs_dl_tbf(BTS *the_bts, int mcs)
|
|||
check_tbf(dl_tbf);
|
||||
tbf_free(dl_tbf);
|
||||
}
|
||||
|
||||
static gprs_rlcmac_dl_tbf *tbf_init(BTS *the_bts,
|
||||
int mcs)
|
||||
{
|
||||
unsigned i;
|
||||
uint8_t ms_class = 11;
|
||||
uint8_t egprs_ms_class = 11;
|
||||
uint32_t fn = 0;
|
||||
uint8_t trx_no;
|
||||
uint32_t tlli = 0xffeeddcc;
|
||||
uint8_t test_data[512];
|
||||
|
||||
uint8_t rbb[64/8];
|
||||
|
||||
gprs_rlcmac_dl_tbf *dl_tbf;
|
||||
|
||||
memset(test_data, 1, sizeof(test_data));
|
||||
the_bts->bts_data()->initial_mcs_dl = mcs;
|
||||
|
||||
dl_tbf = create_dl_tbf(the_bts, ms_class, egprs_ms_class, &trx_no);
|
||||
dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF);
|
||||
|
||||
for (i = 0; i < sizeof(test_data); i++)
|
||||
test_data[i] = i%256;
|
||||
|
||||
OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
|
||||
|
||||
/* Schedule a LLC frame
|
||||
* passing only 100 bytes, since it is enough to construct
|
||||
* 2 RLC data blocks. Which are enough to test Header Type 1
|
||||
* cases
|
||||
*/
|
||||
dl_tbf->append_data(ms_class, 1000, test_data, 100);
|
||||
|
||||
OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW));
|
||||
|
||||
return dl_tbf;
|
||||
|
||||
}
|
||||
|
||||
static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf)
|
||||
{
|
||||
uint32_t fn = 0;
|
||||
|
@ -1635,7 +1784,6 @@ static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
|
|||
tbf_cleanup(dl_tbf);
|
||||
}
|
||||
}
|
||||
|
||||
static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
|
||||
int mcs, int demanded_mcs)
|
||||
{
|
||||
|
@ -1899,10 +2047,10 @@ int main(int argc, char **argv)
|
|||
log_set_use_color(osmo_stderr_target, 0);
|
||||
log_set_print_filename(osmo_stderr_target, 0);
|
||||
bssgp_set_log_ss(DBSSGP);
|
||||
|
||||
vty_init(&pcu_vty_info);
|
||||
pcu_vty_init(&debug_log_info);
|
||||
|
||||
/*initialization_of_tree*/
|
||||
egprs_compress::instance()->decode_tree_init();
|
||||
test_tbf_base();
|
||||
test_tbf_tlli_update();
|
||||
test_tbf_final_ack(TEST_MODE_STANDARD);
|
||||
|
@ -1920,19 +2068,17 @@ int main(int argc, char **argv)
|
|||
test_tbf_gprs_egprs();
|
||||
test_tbf_ws();
|
||||
test_tbf_egprs_two_phase();
|
||||
test_tbf_egprs_two_phase_spb();
|
||||
test_tbf_egprs_dl();
|
||||
test_tbf_egprs_retx_dl();
|
||||
test_tbf_egprs_spb_dl();
|
||||
|
||||
test_EPDAN_time_tree(10000, 0);
|
||||
test_EPDAN_time_osmot4(10000, 0);
|
||||
if (getenv("TALLOC_REPORT_FULL"))
|
||||
talloc_report_full(tall_pcu_ctx, stderr);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* stubs that should not be reached
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
void l1if_pdch_req() { abort(); }
|
||||
void l1if_connect_pdch() { abort(); }
|
||||
|
|
Loading…
Reference in New Issue