Files
openairinterface5g/targets/TEST/PACKET_TRACER/pt.c
T
2013-06-25 09:05:02 +00:00

667 lines
18 KiB
C

#include <string.h>
#include <math.h>
#include <execinfo.h>
#include <signal.h>
#include <unistd.h>
#include <getopt.h>
//#include "SIMULATION/TOOLS/defs.h"
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h"
#include "SCHED/defs.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
#include "RRC/LITE/vars.h"
#include "PHY_INTERFACE/vars.h"
#include "UTIL/LOG/log.h"
#include "OCG_vars.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_vars.h"
char binary_table[16][5] = {{"0000\0"},{"0001\0"},{"0010\0"},{"0011\0"},{"0100\0"},{"0101\0"},{"0110\0"},{"0111\0"},{"1000\0"},{"1001\0"},{"1010\0"},{"1011\0"},{"1100\0"},{"1101\0"},{"1110\0"},{"1111\0"}};
typedef enum {
RRCConnectionRequest=0,
RRCConnectionSetup,
RRCConnectionSetupComplete,
RRCConnectionReconfiguration,
RRCConnectionReconfigurationComplete,
RRCSIB1,
RRCSIB2_3
} RRC_MESSAGES_t;
typedef enum {
eNB_RRC=0,
eNB_S1U,
eNB_PDCP,
eNB_RLC_UM,
eNB_RLC_AM,
eNB_RLC_TM,
eNB_MAC,
UE_RRC,
UE_S1U,
UE_PDCP,
UE_RLC_UM,
UE_RLC_AM,
UE_RLC_TM,
eNB_SI
} SDUsource_t;
typedef struct {
int verbose;
int RRCmessage;
int lcid;
int rbid;
int SDUsize;
int TBsize;
SDUsource_t SDUsource;
char input1_file[128];
char input2_file[128];
char output_file[128];
unsigned char input1_sdu[1024];
unsigned char input2_sdu[1024];
int input1_sdu_flag;
unsigned short input1_sdu_len;
int input2_sdu_flag;
unsigned short input2_sdu_len;
int frame;
int input_sib;
int input_eNB_MAC;
} args_t;
int input_text(char *file,char *sdu) {
FILE *fd;
int i,b_ind=0;
char c,c0,c1;
unsigned char byte;
fd = fopen(file,"r");
while (!feof(fd)) {
c0 = fgetc(fd);
if (!feof(fd))
c1 = fgetc(fd);
else
return(-1);
byte = 0;
for (i=0,c=c0;i<2;i++,c=c1)
switch(c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
byte += (c-'0')<<(4*(1-i));
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
byte += (10+c-'A')<<(4*(1-i));
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
byte += (10+c-'a')<<(4*(1-i));
break;
case '\n':
case '\0':
return(b_ind);
break;
default:
printf("Unknown hex character %c in file\n",c);
return(-1);
break;
}
sdu[b_ind]=byte;
printf("byte %d: %x (%s%s)\n",b_ind,byte,binary_table[byte>>4],binary_table[byte&0xf]);
b_ind++;
}
return(b_ind);
}
int parse_args(int argc, char** argv, args_t* args)
{
int c;
int k;
const struct option long_options[] = {
{"lcid", required_argument, NULL, 256},
{"rbid", required_argument, NULL, 257},
{"TBsize", required_argument, NULL, 258},
{"SDUsize", required_argument, NULL, 259},
{"eNB_RRC", no_argument, NULL, 260},
{"eNB_S1U", no_argument, NULL, 261},
{"eNB_PDCP", no_argument, NULL, 262},
{"eNB_RLC_UM", no_argument, NULL, 263},
{"eNB_RLC_AM", no_argument, NULL, 264},
{"eNB_RLC_TM", no_argument, NULL, 265},
{"eNB_MAC" , no_argument, NULL, 266},
{"UE_RRC", no_argument, NULL, 267},
{"UE_S1U", no_argument, NULL, 268},
{"UE_PDCP", no_argument, NULL, 269},
{"UE_RLC_UM", no_argument, NULL, 270},
{"UE_RLC_AM", no_argument, NULL, 271},
{"UE_RLC_TM", no_argument, NULL, 272},
{"RRCConnectionRequest", no_argument, NULL, 273},
{"RRCConnectionSetup", no_argument, NULL, 274},
{"RRCConnectionSetupComplete", no_argument, NULL, 275},
{"RRCConnectionReconfiguration", no_argument, NULL, 276},
{"RRCConnectionReconfigurationComplete", no_argument, NULL, 277},
{"RRCSIB1", no_argument, NULL, 278},
{"RRCSIB2_3", no_argument, NULL, 279},
{NULL, 0, NULL, 0}};
args->frame = 0;
while((c = getopt_long(argc, argv, "ho:I:J:v", long_options, NULL)) != -1) {
switch(c) {
case 'h':
return 1;
case 'o':
strcpy(args->output_file,optarg);
break;
case 'f':
args->frame = atoi(optarg);
break;
case 'I':
strcpy(args->input1_file,optarg);
args->input1_sdu_len = input_text(args->input1_file,args->input1_sdu);
printf("Got sdu1 of length %d bytes\n",args->input1_sdu_len);
args->input1_sdu_flag=1;
break;
case 'J':
strcpy(args->input2_file,optarg);
args->input2_sdu_len = input_text(args->input2_file,args->input2_sdu);
printf("Got sdu2 of length %d bytes\n",args->input2_sdu_len);
args->input2_sdu_flag=1;
break;
case 'v':
args->verbose++;
break;
case 256: // lchan
args->lcid = atoi(optarg);
break;
case 257: //
args->rbid = atoi(optarg);
break;
case 258:
args->TBsize = atoi(optarg);
break;
case 259:
args->SDUsize = atoi(optarg);
break;
case 260: //eNB_RRC
case 261: //eNB_S1U
case 262: //eNB_PDCP
case 263: //eNB_RLC_UM
case 264: //eNB_RLC_AM
case 265: //eNB_RLC_TM
case 266: //eNB_MAC
case 267: //UE_RRC
case 268: //UE_S1U
case 269: //UE_PDCP
case 270: //UE_RLC_UM
case 271: //UE_RLC_AM
case 272: //UE_RLC_TM
args->SDUsource = c-260;
break;
case 273: //RRCConnectionRequest
case 274: //RRCConnectionSetup
case 275: //RRCConnectionSetupComplete
case 276: //RRCConnectionReconfiguration
case 277: //RRCConnectionReconfigurationComplete
case 278: //RRCSIB1
case 279: //RRCSIB2_3
args->RRCmessage = c-273;
break;
default:
return 1;
}
}
return 0;
}
void print_usage(const char* prog)
{
printf("Usage: %s [options]\n", prog);
printf("\n");
printf(" General options:\n");
printf(" -h : print usage\n");
printf(" -v : increase verbosity level [0]\n");
printf(" -o : output .dat file (binary packet data)\n");
printf(" -i : input .dat file (binary packet data)\n");
printf(" -I : input .txt file (ASCII packet data)\n");
printf("\n");
printf(" Packet options:\n");
printf(" --eNB_RRC : set source of packet to eNB_RRC\n");
printf(" --eNB_S1U : set source of packet to eNB_S1U (e.g. IP)\n");
printf(" --eNB_PDCP : set source of packet to eNB_PDCP\n");
printf(" --eNB_RLC_UM : set source of packet to eNB_RLC_UM\n");
printf(" --eNB_RLC_AM : set source of packet to eNB_RLC_AM\n");
printf(" --eNB_RLC_TM : set source of packet to eNB_RLC_TM\n");
printf(" --eNB_MAC : set source of packet to eNB_MAC\n");
printf(" --UE_RRC : set source of packet to UE_RRC\n");
printf(" --UE_S1U : set source of packet to UE_S1U (e.g. IP)\n");
printf(" --UE_PDCP : set source of packet to UE_PDCP\n");
printf(" --UE_RLC_UM : set source of packet to UE_RLC_UM\n");
printf(" --UE_RLC_AM : set source of packet to UE RLC_AM\n");
printf(" --UE_RLC_TM : set source of packet to UE RLC_TM\n");
printf(" --lchan : set logical channel id\n");
printf(" --rbid : set radio bearer id\n");
printf(" --TBsize : set Transport Block Size at MAC layer\n");
printf(" --SDUsize : set the SDU size used by the originating entity (except RRC)\n");
printf(" --RRCConnectionSetup : set the SDU to be an RRCConnectionSetup\n");
printf(" --RRCConnectionSetupComplete : set the SDU to be an RRCConnectionSetupComplete\n");
printf(" --RRCConnectionRequest : set the SDU to be an RRCConnectionRequest\n");
printf(" --RRCConnectionReconfiguration : set the SDU to be an RRCConnectionReconfiguration\n");
printf(" --RRCConnectionReconfigurationComplete : set the SDU to be an RRCConnectionReconfigurationComplete\n");
printf(" --RRCSIB1 : set the SDU to be an RRCSIB1\n");
printf(" --RRCSIB2_3 : set the SDU to be an RRCSIB2_3\n");
}
u8 attach_ue0(char *sdu) {
u8 Size;
u16 Size16;
u8 lcid=0;
UE_rrc_inst[0].Info[0].State = RRC_SI_RECEIVED;
rrc_ue_generate_RRCConnectionRequest(0,131,0);
Size = mac_rrc_data_req(0,
131,
CCCH,1,
&sdu[sizeof(SCH_SUBHEADER_FIXED)],0,
0);
Size16 = (u16)Size;
generate_ulsch_header((u8 *)sdu, // mac header
1, // num sdus
0, // short padding
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
NULL, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL,
0); // post padding
return(Size+sizeof(SCH_SUBHEADER_FIXED));
}
// This retrieves the RRCConnectionSetup RRC SDU
u8 attach_ue1(char *sdu) {
// simulate reception of CCCH at eNB(RRCConnectionRequest)
mac_rrc_lite_data_ind(0,131,0,UE_rrc_inst[0].Srb0[0].Tx_buffer.Payload,
UE_rrc_inst[0].Srb0[0].Tx_buffer.payload_size,1,0);
return(mac_rrc_data_req(0,
132,
0,1,
sdu,
1,
0));
}
// This retrieves the RRCConnectionSetupComplete RRC SDU
u16 attach_ue2(char *dcch_sdu_eNB, char dcch_sdu_eNB_len, char *dcch_sdu) {
mac_rlc_status_resp_t rlc_status;
u16 sdu_len;
printf("************* attach_ue2 (CCCH payload %d)\n",
eNB_rrc_inst[0].Srb0.Tx_buffer.payload_size);
// simulate reception of CCCH at UE (RRCConnectionSetup)
mac_rrc_lite_data_ind(0,132,0,dcch_sdu_eNB,dcch_sdu_eNB_len,0,0);
// simulate transmission of RRCConnectionSetupComplete
rlc_status = mac_rlc_status_ind(1,134,0,
DCCH,
100);
sdu_len = mac_rlc_data_req(1,133,
DCCH,
dcch_sdu);
return(sdu_len);
}
// This retrieves the RRCConnectionReconfiguration RRC SDU
u16 attach_ue3(char *dcch_sdu_ue, char dcch_sdu_ue_len, char *dcch_sdu_eNB) {
mac_rlc_status_resp_t rlc_status;
u16 sdu_len;
// simulation reception of RRCConnectionSetupComplete
mac_rlc_data_ind(0,134,1,
DCCH,
dcch_sdu_ue,
dcch_sdu_ue_len,
1,
NULL);
/// ... and generation of RRCConnectionReconfiguration
/// First RLC-AM Control SDU (ACK)
rlc_status = mac_rlc_status_ind(0,135,1,
DCCH,
100);
sdu_len = mac_rlc_data_req(0,135,
DCCH,
dcch_sdu_eNB);
mac_rlc_data_ind(1,135,1,
DCCH,
dcch_sdu_eNB,
sdu_len,
1,
NULL);
// now RRC message
rlc_status = mac_rlc_status_ind(0,136,1,
DCCH,
100);
sdu_len = mac_rlc_data_req(0,136,
DCCH,
dcch_sdu_eNB);
return(sdu_len);
}
// This retrieves the RRCConnectionReconfigurationComplete RRC SDU
u16 attach_ue4(char *dcch_sdu_eNB, char dcch_sdu_eNB_len, char *dcch_sdu_ue) {
mac_rlc_status_resp_t rlc_status;
u16 sdu_len;
// simulation UE reception of RRCConnectionReconfiguration ....
mac_rlc_data_ind(1,135,0,
DCCH,
dcch_sdu_eNB,
dcch_sdu_eNB_len,
1,
NULL);
// ... and generation of RRCConnectionReconfigurationComplete
rlc_status = mac_rlc_status_ind(1,135,0,
DCCH,
100);
sdu_len = mac_rlc_data_req(1,135,
DCCH,
dcch_sdu_ue);
rlc_status = mac_rlc_status_ind(1,136,0,
DCCH,
100);
sdu_len = mac_rlc_data_req(1,136,
DCCH,
dcch_sdu_ue);
return(sdu_len);
}
//u8 NB_INST=2;
int main (int argc, char **argv) {
args_t args;
LTE_DL_FRAME_PARMS frame_parms0;
LTE_DL_FRAME_PARMS *frame_parms=&frame_parms;
char sdu0[16],sdu1[64],sdu2[1024],sdu3[1024],sdu4[1024];
unsigned short sdu_len0,sdu_len1,sdu_len2,sdu_len3,sdu_len4;
char ulsch_buffer[1024],dlsch_buffer[1024];
u8 lcid;
u8 payload_offset;
int i,comp;
logInit();
NB_UE_INST = 1;
NB_eNB_INST = 1;
NB_INST=2;
// Parse arguments
if(parse_args(argc, argv, &args) > 0) {
print_usage(argv[0]);
exit(1);
}
set_taus_seed(0);
logInit();
set_glog(LOG_TRACE, 1);
for (comp = PHY; comp < MAX_LOG_COMPONENTS ; comp++)
set_comp_log(comp,
LOG_TRACE,
LOG_NONE,
1);
/*
set_log(OMG, LOG_INFO, 20);
set_log(EMU, LOG_INFO, 10);
set_log(OCG, LOG_INFO, 1);
set_log(MAC, LOG_TRACE, 1);
set_log(RLC, LOG_TRACE, 1);
set_log(PHY, LOG_DEBUG, 1);
set_log(PDCP, LOG_TRACE, 1);
set_log(RRC, LOG_TRACE, 1);
*/
mac_xface = (MAC_xface *)malloc(sizeof(MAC_xface));
init_lte_vars (&frame_parms, 0, 1, 0, 0, 25, 0, 0, 1, 1);
l2_init(frame_parms);
// Generate eNB SI
if (args.input_sib == 0) {
openair_rrc_lite_eNB_init(0);
}
else {
printf("Got SI from files (%d,%d,%d,%d,%d)\n",args.input_sib,args.input1_sdu_flag,args.input2_sdu_flag);
}
openair_rrc_on(0,0);
openair_rrc_lite_ue_init(0,0);
switch (args.SDUsource) {
case eNB_RRC:
if (args.RRCmessage == RRCSIB1) {
if (args.input1_sdu_flag == 1) {
for (i=0;i<args.input1_sdu_len;i++)
printf("%02x",args.input1_sdu[i]);
printf("\n");
ue_decode_si(0,142,0,args.input1_sdu,args.input1_sdu_len);
}
else {
printf("\n\nSIB1\n\n");
for (i=0;i<eNB_rrc_inst[0].sizeof_SIB1;i++)
printf("%02x",eNB_rrc_inst[0].SIB1[i]);
printf("\n");
}
}
else if (args.RRCmessage == RRCSIB2_3) {
if (args.input1_sdu_flag == 1) {
for (i=0;i<args.input2_sdu_len;i++)
printf("%02x",args.input2_sdu[i]);
printf("\n");
ue_decode_si(0,149,0,args.input1_sdu,args.input1_sdu_len);
}
else {
printf("\n\nSIB2_3\n\n");
for (i=0;i<eNB_rrc_inst[0].sizeof_SIB23;i++)
printf("%02x",eNB_rrc_inst[0].SIB23[i]);
printf("\n");
}
}
else if ((args.input1_sdu_flag == 1)&&
((args.RRCmessage == RRCConnectionSetup) ||
(args.RRCmessage == RRCConnectionReconfiguration))){
sdu_len0 = attach_ue0(sdu0);
ue_send_sdu(0,143,args.input1_sdu,args.input1_sdu_len,0);
if (args.RRCmessage == RRCConnectionReconfiguration)
ue_send_sdu(0,144,args.input2_sdu,args.input2_sdu_len,0);
}
else {
switch (args.RRCmessage) {
case RRCConnectionSetup:
printf("Doing eNB RRCConnectionSetup\n");
sdu_len0 = attach_ue0(sdu0);
sdu_len1 = attach_ue1(sdu1);
lcid = 0;
payload_offset = generate_dlsch_header(dlsch_buffer,
1, //num_sdus
&sdu_len1, //
&lcid, // sdu_lcid
255, // no drx
0, // no timing advance
sdu0, // contention res id
0,0);
memcpy(&dlsch_buffer[payload_offset],sdu1,sdu_len1);
printf("\nRRCConnectionSetup (DLSCH input / MAC output)\n\n");
for (i=0;i<sdu_len1+payload_offset;i++)
printf("%02x ",(unsigned char)sdu1[i]);
printf("\n");
break;
case RRCConnectionReconfiguration:
printf("Doing eNB RRCConnectionReconfiguration\n");
sdu_len0 = attach_ue0(sdu0);
sdu_len1 = attach_ue1(sdu1);
sdu_len2 = attach_ue2(sdu1,sdu_len1,sdu2);
sdu_len3 = attach_ue3(sdu2,sdu_len2,sdu3);
lcid=1;
payload_offset = generate_dlsch_header(dlsch_buffer,
// offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0],
1, //num_sdus
&sdu_len3, //
&lcid,
255, // no drx
1, // timing advance
NULL, // contention res idk
0,0);
memcpy(&dlsch_buffer[payload_offset],sdu3,sdu_len3);
printf("\nRRCConnectionReconfiguration (DLSCH input / MAC output)\n\n");
for (i=0;i<sdu_len3+payload_offset;i++)
printf("%02x ",(unsigned char)dlsch_buffer[i]);
printf("\n");
break;
default:
printf("Unknown eNB_RRC SDU (%d), exiting\n",args.RRCmessage);
break;
}
break;
}
break;
case eNB_MAC:
sdu_len0 = attach_ue0(sdu0);
ue_send_sdu(0,143,args.input1_sdu,args.input1_sdu_len,0);
break;
case UE_RRC:
switch (args.RRCmessage) {
case RRCConnectionRequest:
sdu_len0 = attach_ue0(sdu0);
printf("\n\nRRCConnectionRequest\n\n");
for (i=0;i<sdu_len0;i++)
printf("%02x ",(unsigned char)sdu0[i]);
printf("\n");
break;
case RRCConnectionSetupComplete:
sdu_len0=attach_ue0(sdu0);
sdu_len1 = attach_ue1(sdu1);
sdu_len2 = attach_ue2(sdu1,sdu_len1,sdu2);
lcid=1;
printf("Got sdu of length %d\n",sdu_len2);
payload_offset = generate_ulsch_header((u8*)ulsch_buffer, // mac header
1, // num sdus
0, // short pading
&sdu_len2, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
NULL, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
0);
printf("Got MAC header of length %d\n",payload_offset);
memcpy(&ulsch_buffer[payload_offset],sdu2,sdu_len2);
printf("\n\nRRCConnectionSetupComplete (ULSCH input / MAC output)\n\n");
for (i=0;i<sdu_len2+payload_offset;i++)
printf("%02x ",(unsigned char)ulsch_buffer[i]);
printf("\n");
break;
case RRCConnectionReconfigurationComplete:
sdu_len0=attach_ue0(sdu0);
sdu_len1=attach_ue1(sdu1);
sdu_len2 = attach_ue2(sdu1,sdu_len1,sdu2);
sdu_len3 = attach_ue3(sdu2,sdu_len2,sdu3);
sdu_len4 = attach_ue4(sdu3,sdu_len3,sdu4);
lcid=1;
printf("Got sdu of length %d\n",sdu_len4);
payload_offset = generate_ulsch_header((u8*)ulsch_buffer, // mac header
1, // num sdus
0, // short pading
&sdu_len4, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
NULL, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
0);
printf("Got MAC header of length %d\n",payload_offset);
memcpy(&ulsch_buffer[payload_offset],sdu4,sdu_len4);
printf("\n\nRRCConnectionReconfigurationComplete (ULSCH input / MAC output)\n\n");
for (i=0;i<sdu_len4+payload_offset;i++)
printf("%02x ",(unsigned char)ulsch_buffer[i]);
printf("\n");
break;
default:
printf("Unknown UE_RRC SDU (%d), exiting\n",args.RRCmessage);
break;
}
break;
}
free(mac_xface);
return(0);
}