added stats for PDSCH for MAC-PHY interface, removed some duplicate stats git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4113 818b1a75-f10b-46b9-bf7c-635c3b92a50f
930 lines
34 KiB
C
930 lines
34 KiB
C
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <signal.h>
|
|
#include <execinfo.h>
|
|
#include <time.h>
|
|
|
|
#include <sys/timerfd.h>
|
|
|
|
#include "oaisim_functions.h"
|
|
|
|
#include "PHY/extern.h"
|
|
#include "MAC_INTERFACE/extern.h"
|
|
#include "LAYER2/MAC/extern.h"
|
|
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
|
|
#include "LAYER2/PDCP_v10.1.0/pdcp_primitives.h"
|
|
#include "RRC/LITE/extern.h"
|
|
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
|
#include "PHY_INTERFACE/extern.h"
|
|
#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
|
|
#include "SCHED/extern.h"
|
|
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
|
#include "UTIL/OCG/OCG_extern.h"
|
|
#include "UTIL/LOG/vcd_signal_dumper.h"
|
|
#include "UTIL/OPT/opt.h"
|
|
|
|
#include "cor_SF_sim.h"
|
|
|
|
#ifdef SMBV
|
|
extern u8 config_smbv;
|
|
extern char smbv_ip[16];
|
|
#endif
|
|
|
|
//constant for OAISIM soft realtime calibration
|
|
#define SF_DEVIATION_OFFSET_NS 100000 //= 0.1ms : should be as a number of UE
|
|
#define SLEEP_STEP_US 100 // = 0.01ms could be adaptive, should be as a number of UE
|
|
#define K 2 // averaging coefficient
|
|
#define TARGET_SF_TIME_NS 1000000 // 1ms = 1000000 ns
|
|
|
|
int otg_times = 0;
|
|
int if_times = 0;
|
|
int for_times = 0;
|
|
|
|
u16 Nid_cell = 0; //needed by init_lte_vars
|
|
int nb_antennas_rx=2; // //
|
|
u8 target_dl_mcs = 0;
|
|
u8 rate_adaptation_flag = 0;
|
|
u8 set_sinr=0;
|
|
double snr_dB, sinr_dB;
|
|
u8 set_seed=0;
|
|
u8 cooperation_flag; // for cooperative communication
|
|
u8 abstraction_flag = 0, ethernet_flag = 0;
|
|
double snr_step=1.0;
|
|
u8 ue_connection_test=0;
|
|
double forgetting_factor=0.0;
|
|
u8 beta_ACK=0,beta_RI=0,beta_CQI=2;
|
|
u8 target_ul_mcs = 2;
|
|
LTE_DL_FRAME_PARMS *frame_parms;
|
|
int map1,map2;
|
|
double **ShaF= NULL;
|
|
// pointers signal buffers (s = transmit, r,r0 = receive)
|
|
double **s_re, **s_im, **r_re, **r_im, **r_re0, **r_im0;
|
|
Node_list ue_node_list = NULL;
|
|
Node_list enb_node_list = NULL;
|
|
int pdcp_period, omg_period;
|
|
|
|
// time calibration for soft realtime mode
|
|
struct timespec time_spec;
|
|
unsigned long time_last, time_now;
|
|
int td, td_avg, sleep_time_us;
|
|
|
|
#ifdef OPENAIR2
|
|
// omv related info
|
|
//pid_t omv_pid;
|
|
char full_name[200];
|
|
int pfd[2]; // fd for omv : fixme: this could be a local var
|
|
char fdstr[10];
|
|
char frames[10];
|
|
char num_enb[10];
|
|
char num_ue[10];
|
|
//area_x, area_y and area_z for omv
|
|
char x_area[20];
|
|
char y_area[20];
|
|
char z_area[20];
|
|
char nb_antenna[20];
|
|
char frame_type[10];
|
|
char tdd_config[10];
|
|
#endif
|
|
|
|
Packet_OTG_List *otg_pdcp_buffer;
|
|
|
|
extern node_desc_t *enb_data[NUMBER_OF_eNB_MAX];
|
|
extern node_desc_t *ue_data[NUMBER_OF_UE_MAX];
|
|
extern channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
|
|
extern channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX];
|
|
|
|
extern mapping small_scale_names[];
|
|
extern pdcp_mbms_t pdcp_mbms_array[MAX_MODULES][16*29];
|
|
extern int eMBMS_active;
|
|
|
|
extern void help (void);
|
|
|
|
void get_simulation_options(int argc, char *argv[]) {
|
|
char c;
|
|
int option_index;
|
|
static struct option long_options[] = {
|
|
{"pdcp_period", 1, 0, 0},
|
|
{"omg_period", 1, 0, 0},
|
|
{NULL, 0, NULL, 0}
|
|
};
|
|
|
|
while ((c = getopt_long (argc, argv, "aA:b:B:c:C:D:d:eE:f:FGg:hi:IJ:k:l:m:M:n:N:oO:p:P:rR:s:S:t:T:u:U:vVx:y:w:W:X:z:Z:", long_options, &option_index)) != -1) {
|
|
|
|
switch (c) {
|
|
case 0:
|
|
if (! strcmp(long_options[option_index].name, "pdcp_period")) {
|
|
if (optarg) {
|
|
pdcp_period = atoi(optarg);
|
|
printf("PDCP period is %d\n", pdcp_period);
|
|
}
|
|
} else if (! strcmp(long_options[option_index].name, "omg_period")) {
|
|
if (optarg) {
|
|
omg_period = atoi(optarg);
|
|
printf("OMG period is %d\n", omg_period);
|
|
}
|
|
}
|
|
break;
|
|
case 'L': // set FDD
|
|
flag_LA = atoi(optarg);
|
|
break;
|
|
case 'F': // set FDD
|
|
printf("Setting Frame to FDD\n");
|
|
oai_emulation.info.frame_type = 0;
|
|
break;
|
|
case 'C':
|
|
oai_emulation.info.tdd_config = atoi (optarg);
|
|
if (oai_emulation.info.tdd_config > 6) {
|
|
LOG_E(EMU,"Illegal tdd_config %d (should be 0-6)\n", oai_emulation.info.tdd_config);
|
|
exit (-1);
|
|
}
|
|
break;
|
|
case 'Q':
|
|
eMBMS_active=1;
|
|
break;
|
|
case 'R':
|
|
oai_emulation.info.N_RB_DL = atoi (optarg);
|
|
if ((oai_emulation.info.N_RB_DL != 6) && (oai_emulation.info.N_RB_DL != 15) && (oai_emulation.info.N_RB_DL != 25)
|
|
&& (oai_emulation.info.N_RB_DL != 50) && (oai_emulation.info.N_RB_DL != 75) && (oai_emulation.info.N_RB_DL != 100)) {
|
|
LOG_E(EMU,"Illegal N_RB_DL %d (should be one of 6,15,25,50,75,100)\n", oai_emulation.info.N_RB_DL);
|
|
exit (-1);
|
|
}
|
|
case 'N':
|
|
Nid_cell = atoi (optarg);
|
|
if (Nid_cell > 503) {
|
|
LOG_E(EMU,"Illegal Nid_cell %d (should be 0 ... 503)\n", Nid_cell);
|
|
exit(-1);
|
|
}
|
|
break;
|
|
case 'h':
|
|
help ();
|
|
exit (1);
|
|
case 'x':
|
|
oai_emulation.info.transmission_mode = atoi (optarg);
|
|
if ((oai_emulation.info.transmission_mode != 1) && (oai_emulation.info.transmission_mode != 2) && (oai_emulation.info.transmission_mode != 5) && (oai_emulation.info.transmission_mode != 6)) {
|
|
LOG_E(EMU, "Unsupported transmission mode %d\n",oai_emulation.info.transmission_mode);
|
|
exit(-1);
|
|
}
|
|
break;
|
|
case 'y':
|
|
nb_antennas_rx=atoi(optarg);
|
|
if (nb_antennas_rx>4) {
|
|
printf("Cannot have more than 4 antennas\n");
|
|
exit(-1);
|
|
}
|
|
break;
|
|
case 'm':
|
|
target_dl_mcs = atoi (optarg);
|
|
break;
|
|
case 'r':
|
|
rate_adaptation_flag = 1;
|
|
break;
|
|
case 'n':
|
|
oai_emulation.info.n_frames = atoi (optarg);
|
|
//n_frames = (n_frames >1024) ? 1024: n_frames; // adjust the n_frames if higher that 1024
|
|
oai_emulation.info.n_frames_flag = 1;
|
|
break;
|
|
case 's':
|
|
snr_dB = atoi (optarg);
|
|
// set_snr = 1;
|
|
oai_emulation.info.ocm_enabled=0;
|
|
break;
|
|
case 'S':
|
|
sinr_dB = atoi (optarg);
|
|
set_sinr = 1;
|
|
oai_emulation.info.ocm_enabled=0;
|
|
break;
|
|
case 'J':
|
|
ue_connection_test=1;
|
|
oai_emulation.info.ocm_enabled=0;
|
|
snr_step = atof(optarg);
|
|
break;
|
|
case 'k':
|
|
//ricean_factor = atof (optarg);
|
|
LOG_E(EMU,"[SIM] Option k is no longer supported on the command line. Please specify your channel model in the xml template\n");
|
|
exit(-1);
|
|
break;
|
|
case 't':
|
|
//Td = atof (optarg);
|
|
LOG_E(EMU,"[SIM] Option t is no longer supported on the command line. Please specify your channel model in the xml template\n");
|
|
exit(-1);
|
|
break;
|
|
case 'f':
|
|
forgetting_factor = atof (optarg);
|
|
break;
|
|
case 'z':
|
|
cooperation_flag = atoi (optarg);
|
|
break;
|
|
case 'u':
|
|
oai_emulation.info.nb_ue_local = atoi (optarg);
|
|
break;
|
|
case 'b':
|
|
oai_emulation.info.nb_enb_local = atoi (optarg);
|
|
break;
|
|
case 'a':
|
|
abstraction_flag = 1;
|
|
break;
|
|
case 'A':
|
|
//oai_emulation.info.ocm_enabled=1;
|
|
if (optarg == NULL)
|
|
oai_emulation.environment_system_config.fading.small_scale.selected_option="AWGN";
|
|
else
|
|
oai_emulation.environment_system_config.fading.small_scale.selected_option= optarg;
|
|
//awgn_flag = 1;
|
|
break;
|
|
case 'p':
|
|
oai_emulation.info.nb_master = atoi (optarg);
|
|
break;
|
|
case 'M':
|
|
abstraction_flag = 1;
|
|
ethernet_flag = 1;
|
|
oai_emulation.info.ethernet_id = atoi (optarg);
|
|
oai_emulation.info.master_id = oai_emulation.info.ethernet_id;
|
|
oai_emulation.info.ethernet_flag = 1;
|
|
break;
|
|
case 'e':
|
|
oai_emulation.info.extended_prefix_flag = 1;
|
|
break;
|
|
case 'l':
|
|
oai_emulation.info.g_log_level = atoi(optarg);
|
|
break;
|
|
case 'Y':
|
|
oai_emulation.info.g_log_verbosity = optarg;
|
|
break;
|
|
case 'c':
|
|
strcpy(oai_emulation.info.local_server, optarg);
|
|
oai_emulation.info.ocg_enabled=1;
|
|
break;
|
|
case 'g':
|
|
oai_emulation.info.multicast_group = atoi (optarg);
|
|
break;
|
|
case 'D':
|
|
oai_emulation.info.multicast_ifname = strdup(optarg);
|
|
break;
|
|
case 'B':
|
|
oai_emulation.topology_config.mobility.eNB_mobility.eNB_mobility_type.selected_option = optarg;
|
|
//oai_emulation.info.omg_model_enb = atoi (optarg);
|
|
break;
|
|
case 'U':
|
|
oai_emulation.topology_config.mobility.UE_mobility.UE_mobility_type.selected_option = optarg;
|
|
break;
|
|
case 'T':
|
|
oai_emulation.info.otg_enabled = 1;
|
|
oai_emulation.info.otg_traffic = optarg;
|
|
break;
|
|
case 'P':
|
|
oai_emulation.info.opt_enabled = 1;
|
|
|
|
if (strcmp(optarg, "wireshark") == 0) {
|
|
opt_type = OPT_WIRESHARK;
|
|
printf("Enabling OPT for wireshark\n");
|
|
} else if (strcmp(optarg, "pcap") == 0) {
|
|
opt_type = OPT_PCAP;
|
|
printf("Enabling OPT for pcap\n");
|
|
} else {
|
|
printf("Unrecognized option for OPT module. -> Disabling it\n");
|
|
printf("Possible values are either wireshark or pcap\n");
|
|
opt_type = OPT_NONE;
|
|
oai_emulation.info.opt_enabled = 0;
|
|
}
|
|
oai_emulation.info.opt_mode = opt_type;
|
|
break;
|
|
case 'E':
|
|
set_seed = 1;
|
|
oai_emulation.info.seed = atoi (optarg);
|
|
break;
|
|
case 'I':
|
|
oai_emulation.info.cli_enabled = 1;
|
|
break;
|
|
case 'X':
|
|
#ifdef PROC
|
|
temp=atoi(optarg);
|
|
if(temp==0){
|
|
port=CHANNEL_PORT; Channel_Flag=1; Process_Flag=0; wgt=0;
|
|
}
|
|
else if(temp==1){
|
|
port=eNB_PORT; wgt=0;
|
|
}
|
|
else {
|
|
port=UE_PORT; wgt=MAX_eNB;
|
|
}
|
|
#endif
|
|
break;
|
|
case 'i':
|
|
#ifdef PROC
|
|
Process_Flag=1;
|
|
node_id = wgt+atoi(optarg);
|
|
port+=atoi(optarg);
|
|
#endif
|
|
break;
|
|
case 'v':
|
|
oai_emulation.info.omv_enabled = 1;
|
|
break;
|
|
case 'V':
|
|
ouput_vcd = 1;
|
|
oai_emulation.info.vcd_enabled = 1;
|
|
break;
|
|
case 'w':
|
|
oai_emulation.info.cba_group_active = atoi (optarg);
|
|
break;
|
|
case 'W':
|
|
#ifdef SMBV
|
|
config_smbv = 1;
|
|
if(atoi(optarg)!=0)
|
|
strcpy(smbv_ip,optarg);
|
|
#endif
|
|
break;
|
|
case 'G' :
|
|
oai_emulation.info.otg_bg_traffic_enabled = 1;
|
|
break;
|
|
case 'Z':
|
|
/* Sebastien ROUX: Reserved for future use (currently used in ltenow branch) */
|
|
break;
|
|
case 'O':
|
|
#if defined(ENABLE_USE_MME)
|
|
oai_emulation.info.mme_enabled = 1;
|
|
if (optarg == NULL) /* No IP address provided: use localhost */
|
|
{
|
|
memcpy(&oai_emulation.info.mme_ip_address[0], "127.0.0.1", 10);
|
|
} else {
|
|
u8 ip_length = strlen(optarg) + 1;
|
|
memcpy(&oai_emulation.info.mme_ip_address[0], optarg, ip_length > 16 ? 16 : ip_length);
|
|
}
|
|
#else
|
|
printf("You enabled MME mode without MME support...\n");
|
|
#endif
|
|
break;
|
|
case 'o':
|
|
oai_emulation.info.slot_isr = 1;
|
|
break;
|
|
default:
|
|
help ();
|
|
exit (-1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void check_and_adjust_params() {
|
|
|
|
s32 ret;
|
|
int i,j;
|
|
|
|
if (oai_emulation.info.nb_ue_local > NUMBER_OF_UE_MAX) {
|
|
LOG_E(EMU,"Enter fewer than %d UEs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_UE_MAX);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (oai_emulation.info.nb_enb_local > NUMBER_OF_eNB_MAX) {
|
|
LOG_E(EMU,"Enter fewer than %d eNBs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_eNB_MAX);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// fix ethernet and abstraction with RRC_CELLULAR Flag
|
|
#ifdef RRC_CELLULAR
|
|
abstraction_flag = 1;
|
|
ethernet_flag = 1;
|
|
#endif
|
|
|
|
if (set_sinr == 0)
|
|
sinr_dB = snr_dB - 20;
|
|
|
|
// setup netdevice interface (netlink socket)
|
|
LOG_I(EMU,"[INIT] Starting NAS netlink interface\n");
|
|
ret = netlink_init();
|
|
if (ret < 0)
|
|
LOG_E(EMU,"[INIT] Netlink not available, careful ...\n");
|
|
|
|
|
|
if (ethernet_flag == 1) {
|
|
oai_emulation.info.master[oai_emulation.info.master_id].nb_ue = oai_emulation.info.nb_ue_local;
|
|
oai_emulation.info.master[oai_emulation.info.master_id].nb_enb = oai_emulation.info.nb_enb_local;
|
|
|
|
if (!oai_emulation.info.master_id)
|
|
oai_emulation.info.is_primary_master = 1;
|
|
j = 1;
|
|
for (i = 0; i < oai_emulation.info.nb_master; i++) {
|
|
if (i != oai_emulation.info.master_id)
|
|
oai_emulation.info.master_list = oai_emulation.info.master_list + j;
|
|
LOG_I (EMU, "Index of master id i=%d MASTER_LIST %d\n", i, oai_emulation.info.master_list);
|
|
j *= 2;
|
|
}
|
|
LOG_I (EMU, " Total number of master %d my master id %d\n", oai_emulation.info.nb_master, oai_emulation.info.master_id);
|
|
init_bypass ();
|
|
|
|
while (emu_tx_status != SYNCED_TRANSPORT) {
|
|
LOG_I (EMU, " Waiting for EMU Transport to be synced\n");
|
|
emu_transport_sync (); //emulation_tx_rx();
|
|
}
|
|
} // ethernet flag
|
|
|
|
|
|
NB_UE_INST = oai_emulation.info.nb_ue_local + oai_emulation.info.nb_ue_remote;
|
|
NB_eNB_INST = oai_emulation.info.nb_enb_local + oai_emulation.info.nb_enb_remote;
|
|
}
|
|
|
|
void init_omv() {
|
|
if (oai_emulation.info.omv_enabled == 1) {
|
|
|
|
if(pipe(pfd) == -1)
|
|
perror("pipe error \n");
|
|
|
|
sprintf(full_name, "%s/UTIL/OMV/OMV",getenv("OPENAIR2_DIR"));
|
|
LOG_I(EMU,"Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, pfd[0],pfd[1]);
|
|
|
|
switch(fork()) {
|
|
case -1 :
|
|
perror("fork failed \n");
|
|
break;
|
|
case 0 : /* child is going to be the omv, it is the reader */
|
|
if(close(pfd[1]) == -1 ) /* we close the write desc. */
|
|
perror("close on write\n" );
|
|
sprintf(fdstr, "%d", pfd[0] );
|
|
sprintf(num_enb, "%d", NB_eNB_INST);
|
|
sprintf(num_ue, "%d", NB_UE_INST);
|
|
sprintf(x_area, "%f", oai_emulation.topology_config.area.x_m );
|
|
sprintf(y_area, "%f", oai_emulation.topology_config.area.y_m );
|
|
sprintf(z_area, "%f", 200.0 );
|
|
sprintf(frames, "%d", oai_emulation.info.n_frames);
|
|
sprintf(nb_antenna, "%d", 4);
|
|
sprintf(frame_type, "%s", (oai_emulation.info.frame_type == 0) ? "FDD" : "TDD");
|
|
sprintf(tdd_config, "%d", oai_emulation.info.tdd_config);
|
|
/* execl is used to launch the visualisor */
|
|
execl(full_name,"OMV", fdstr, frames, num_enb, num_ue, x_area, y_area, z_area, nb_antenna, frame_type, tdd_config,NULL );
|
|
perror( "error in execl the OMV" );
|
|
}
|
|
//parent
|
|
if(close( pfd[0] ) == -1 ) /* we close the write desc. */
|
|
perror("close on read\n" );
|
|
}
|
|
}
|
|
|
|
void init_seed(u8 set_seed) {
|
|
|
|
if(set_seed) {
|
|
|
|
randominit (oai_emulation.info.seed);
|
|
set_taus_seed (oai_emulation.info.seed);
|
|
|
|
} else {
|
|
randominit (0);
|
|
set_taus_seed (0);
|
|
}
|
|
}
|
|
|
|
void init_openair1() {
|
|
s32 UE_id, eNB_id;
|
|
|
|
// change the nb_connected_eNB
|
|
init_lte_vars (&frame_parms, oai_emulation.info.frame_type, oai_emulation.info.tdd_config, oai_emulation.info.tdd_config_S,oai_emulation.info.extended_prefix_flag,oai_emulation.info.N_RB_DL, Nid_cell, cooperation_flag, oai_emulation.info.transmission_mode, abstraction_flag,nb_antennas_rx);
|
|
|
|
for (eNB_id=0; eNB_id<NB_eNB_INST;eNB_id++){
|
|
for (UE_id=0; UE_id<NB_UE_INST;UE_id++){
|
|
PHY_vars_eNB_g[eNB_id]->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK;
|
|
PHY_vars_eNB_g[eNB_id]->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI;
|
|
PHY_vars_eNB_g[eNB_id]->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI;
|
|
PHY_vars_UE_g[UE_id]->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK;
|
|
PHY_vars_UE_g[UE_id]->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = beta_RI;
|
|
PHY_vars_UE_g[UE_id]->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI;
|
|
((PHY_vars_UE_g[UE_id]->lte_frame_parms).pdsch_config_common).p_b = (frame_parms->nb_antennas_tx_eNB>1) ? 1 : 0; // rho_a = rhob
|
|
((PHY_vars_eNB_g[eNB_id]->lte_frame_parms).pdsch_config_common).p_b = (frame_parms->nb_antennas_tx_eNB>1) ? 1 : 0; // rho_a = rhob
|
|
|
|
}
|
|
}
|
|
|
|
printf ("AFTER init: Nid_cell %d\n", PHY_vars_eNB_g[0]->lte_frame_parms.Nid_cell);
|
|
printf ("AFTER init: frame_type %d,tdd_config %d\n",
|
|
PHY_vars_eNB_g[0]->lte_frame_parms.frame_type,
|
|
PHY_vars_eNB_g[0]->lte_frame_parms.tdd_config);
|
|
|
|
number_of_cards = 1;
|
|
|
|
openair_daq_vars.rx_rf_mode = 1;
|
|
openair_daq_vars.tdd = 1;
|
|
openair_daq_vars.rx_gain_mode = DAQ_AGC_ON;
|
|
|
|
openair_daq_vars.dlsch_transmission_mode = oai_emulation.info.transmission_mode;
|
|
|
|
openair_daq_vars.target_ue_dl_mcs = target_dl_mcs;
|
|
openair_daq_vars.target_ue_ul_mcs = target_ul_mcs;
|
|
openair_daq_vars.ue_dl_rb_alloc=0x1fff;
|
|
openair_daq_vars.ue_ul_nb_rb=6;
|
|
openair_daq_vars.dlsch_rate_adaptation = rate_adaptation_flag;
|
|
openair_daq_vars.use_ia_receiver = 0;
|
|
|
|
// init_ue_status();
|
|
for (UE_id=0; UE_id<NB_UE_INST;UE_id++) {
|
|
PHY_vars_UE_g[UE_id]->rx_total_gain_dB=130;
|
|
// update UE_mode for each eNB_id not just 0
|
|
if (abstraction_flag == 0)
|
|
PHY_vars_UE_g[UE_id]->UE_mode[0] = NOT_SYNCHED;
|
|
else {
|
|
// 0 is the index of the connected eNB
|
|
PHY_vars_UE_g[UE_id]->UE_mode[0] = PRACH;
|
|
}
|
|
PHY_vars_UE_g[UE_id]->lte_ue_pdcch_vars[0]->crnti = 0x1235 + UE_id;
|
|
PHY_vars_UE_g[UE_id]->current_dlsch_cqi[0] = 10;
|
|
|
|
LOG_I(EMU, "UE %d mode is initialized to %d\n", UE_id, PHY_vars_UE_g[UE_id]->UE_mode[0] );
|
|
}
|
|
}
|
|
|
|
void init_openair2() {
|
|
#ifdef OPENAIR2
|
|
s32 i;
|
|
s32 UE_id;
|
|
l2_init (&PHY_vars_eNB_g[0]->lte_frame_parms,eMBMS_active, oai_emulation.info.cba_group_active);
|
|
printf ("after L2 init: Nid_cell %d\n", PHY_vars_eNB_g[0]->lte_frame_parms.Nid_cell);
|
|
printf ("after L2 init: frame_type %d,tdd_config %d\n",
|
|
PHY_vars_eNB_g[0]->lte_frame_parms.frame_type,
|
|
PHY_vars_eNB_g[0]->lte_frame_parms.tdd_config);
|
|
|
|
for (i = 0; i < NB_eNB_INST; i++)
|
|
mac_xface->mrbch_phy_sync_failure (i, 0, i);
|
|
|
|
if (abstraction_flag == 1) {
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++)
|
|
mac_xface->dl_phy_sync_success (UE_id, 0, 0,1); //UE_id%NB_eNB_INST);
|
|
}
|
|
|
|
mac_xface->macphy_exit = exit_fun;
|
|
#endif
|
|
}
|
|
|
|
void init_ocm() {
|
|
s32 UE_id, eNB_id;
|
|
/* Added for PHY abstraction */
|
|
if (abstraction_flag) {
|
|
if (0) { //the values of beta and awgn tables are hard coded in PHY/vars.h
|
|
get_beta_map();
|
|
#ifdef PHY_ABSTRACTION_UL
|
|
get_beta_map_up();
|
|
#endif
|
|
get_MIESM_param();
|
|
}
|
|
}
|
|
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
enb_data[eNB_id] = (node_desc_t *)malloc(sizeof(node_desc_t));
|
|
init_enb(enb_data[eNB_id],oai_emulation.environment_system_config.antenna.eNB_antenna);
|
|
}
|
|
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
ue_data[UE_id] = (node_desc_t *)malloc(sizeof(node_desc_t));
|
|
init_ue(ue_data[UE_id],oai_emulation.environment_system_config.antenna.UE_antenna);
|
|
}
|
|
|
|
if ((oai_emulation.info.ocm_enabled == 1)&& (ethernet_flag == 0 ) &&
|
|
(oai_emulation.environment_system_config.fading.shadowing.decorrelation_distance_m>0) &&
|
|
(oai_emulation.environment_system_config.fading.shadowing.variance_dB>0)) {
|
|
|
|
// init SF map here!!!
|
|
map1 =(int)oai_emulation.topology_config.area.x_m;
|
|
map2 =(int)oai_emulation.topology_config.area.y_m;
|
|
ShaF = init_SF(map1,map2,oai_emulation.environment_system_config.fading.shadowing.decorrelation_distance_m,oai_emulation.environment_system_config.fading.shadowing.variance_dB);
|
|
|
|
// size of area to generate shadow fading map
|
|
LOG_D(EMU,"Simulation area x=%f, y=%f\n",
|
|
oai_emulation.topology_config.area.x_m,
|
|
oai_emulation.topology_config.area.y_m);
|
|
}
|
|
|
|
if (abstraction_flag == 0)
|
|
init_channel_vars (frame_parms, &s_re, &s_im, &r_re, &r_im, &r_re0, &r_im0);
|
|
|
|
// initialize channel descriptors
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
|
|
LOG_D(OCM,"Initializing channel (%s, %d) from eNB %d to UE %d\n", oai_emulation.environment_system_config.fading.small_scale.selected_option,
|
|
map_str_to_int(small_scale_names,oai_emulation.environment_system_config.fading.small_scale.selected_option), eNB_id, UE_id);
|
|
|
|
/* if (oai_emulation.info.transmission_mode == 5)
|
|
eNB2UE[eNB_id][UE_id] = new_channel_desc_scm(PHY_vars_eNB_g[eNB_id]->lte_frame_parms.nb_antennas_tx,
|
|
PHY_vars_UE_g[UE_id]->lte_frame_parms.nb_antennas_rx,
|
|
(UE_id == 0)? Rice1_corr : Rice1_anticorr,
|
|
oai_emulation.environment_system_config.system_bandwidth_MB,
|
|
forgetting_factor,
|
|
0,
|
|
0);
|
|
|
|
else
|
|
*/
|
|
|
|
eNB2UE[eNB_id][UE_id] = new_channel_desc_scm(PHY_vars_eNB_g[eNB_id]->lte_frame_parms.nb_antennas_tx,
|
|
PHY_vars_UE_g[UE_id]->lte_frame_parms.nb_antennas_rx,
|
|
map_str_to_int(small_scale_names,oai_emulation.environment_system_config.fading.small_scale.selected_option),
|
|
oai_emulation.environment_system_config.system_bandwidth_MB,
|
|
forgetting_factor,
|
|
0,
|
|
0);
|
|
random_channel(eNB2UE[eNB_id][UE_id]);
|
|
LOG_D(OCM,"[SIM] Initializing channel (%s, %d) from UE %d to eNB %d\n", oai_emulation.environment_system_config.fading.small_scale.selected_option,
|
|
map_str_to_int(small_scale_names, oai_emulation.environment_system_config.fading.small_scale.selected_option),UE_id, eNB_id);
|
|
|
|
UE2eNB[UE_id][eNB_id] = new_channel_desc_scm(PHY_vars_UE_g[UE_id]->lte_frame_parms.nb_antennas_tx,
|
|
PHY_vars_eNB_g[eNB_id]->lte_frame_parms.nb_antennas_rx,
|
|
map_str_to_int(small_scale_names, oai_emulation.environment_system_config.fading.small_scale.selected_option),
|
|
oai_emulation.environment_system_config.system_bandwidth_MB,
|
|
forgetting_factor,
|
|
0,
|
|
0);
|
|
|
|
random_channel(UE2eNB[UE_id][eNB_id]);
|
|
}
|
|
}
|
|
|
|
// Not needed anymore, done automatically in init_freq_channel upon first call to the function
|
|
|
|
// if (abstraction_flag==1)
|
|
// init_freq_channel(eNB2UE[0][0],PHY_vars_UE_g[0]->lte_frame_parms.N_RB_DL,PHY_vars_UE_g[0]->lte_frame_parms.N_RB_DL*12+1);
|
|
freq_channel(eNB2UE[0][0],PHY_vars_UE_g[0]->lte_frame_parms.N_RB_DL,PHY_vars_UE_g[0]->lte_frame_parms.N_RB_DL*12+1);
|
|
}
|
|
|
|
void init_otg_pdcp_buffer() {
|
|
s32 i;
|
|
otg_pdcp_buffer = malloc((NB_UE_INST + NB_eNB_INST) * sizeof(Packet_OTG_List));
|
|
|
|
for (i = 0; i < NB_UE_INST + NB_eNB_INST; i++) {
|
|
pkt_list_init(&(otg_pdcp_buffer[i]));
|
|
//LOG_I(EMU,"HEAD of otg_pdcp_buffer[%d] is %p\n", i, pkt_list_get_head(&(otg_pdcp_buffer[i])));
|
|
}
|
|
}
|
|
|
|
void update_omg () {
|
|
s32 UE_id, eNB_id;
|
|
int new_omg_model;
|
|
|
|
if ((frame % omg_period) == 0 ) { // call OMG every 10ms
|
|
update_nodes(oai_emulation.info.time_s);
|
|
display_node_list(enb_node_list);
|
|
display_node_list(ue_node_list);
|
|
if (oai_emulation.info.omg_model_ue >= MAX_NUM_MOB_TYPES){ // mix mobility model
|
|
for(UE_id=oai_emulation.info.first_ue_local; UE_id<(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local);UE_id++){
|
|
new_omg_model = randomGen(STATIC,RWALK);
|
|
LOG_D(OMG, "[UE] Node of ID %d is changing mobility generator ->%d \n", UE_id, new_omg_model);
|
|
// reset the mobility model for a specific node
|
|
set_new_mob_type (UE_id, UE, new_omg_model, oai_emulation.info.time_s);
|
|
}
|
|
}
|
|
|
|
if (oai_emulation.info.omg_model_enb >= MAX_NUM_MOB_TYPES) { // mix mobility model
|
|
for (eNB_id = oai_emulation.info.first_enb_local; eNB_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local); eNB_id++) {
|
|
new_omg_model = randomGen (STATIC, RWALK);
|
|
LOG_D (OMG,"[eNB] Node of ID %d is changing mobility generator ->%d \n", UE_id, new_omg_model);
|
|
// reset the mobility model for a specific node
|
|
set_new_mob_type (eNB_id, eNB, new_omg_model, oai_emulation.info.time_s);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void update_omg_ocm() {
|
|
enb_node_list = get_current_positions(oai_emulation.info.omg_model_enb, eNB, oai_emulation.info.time_s);
|
|
ue_node_list = get_current_positions(oai_emulation.info.omg_model_ue, UE, oai_emulation.info.time_s);
|
|
}
|
|
|
|
void update_ocm() {
|
|
s32 UE_id, eNB_id;
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++)
|
|
enb_data[eNB_id]->tx_power_dBm = PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower;
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++)
|
|
ue_data[UE_id]->tx_power_dBm = PHY_vars_UE_g[UE_id]->tx_power_dBm;
|
|
|
|
/* check if the openair channel model is activated used for PHY abstraction : path loss*/
|
|
if ((oai_emulation.info.ocm_enabled == 1)&& (ethernet_flag == 0 )) {
|
|
//LOG_D(OMG," extracting position of eNb...\n");
|
|
extract_position(enb_node_list, enb_data, NB_eNB_INST);
|
|
//LOG_D(OMG," extracting position of UE...\n");
|
|
// if (oai_emulation.info.omg_model_ue == TRACE)
|
|
extract_position(ue_node_list, ue_data, NB_UE_INST);
|
|
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id], oai_emulation.environment_system_config,ShaF);
|
|
//calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id], oai_emulation.environment_system_config,0);
|
|
UE2eNB[UE_id][eNB_id]->path_loss_dB = eNB2UE[eNB_id][UE_id]->path_loss_dB;
|
|
LOG_I(OCM,"Path loss between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n",
|
|
eNB_id,enb_data[eNB_id]->x,enb_data[eNB_id]->y,UE_id,ue_data[UE_id]->x,ue_data[UE_id]->y,
|
|
eNB2UE[eNB_id][UE_id]->path_loss_dB, eNB2UE[eNB_id][UE_id]->aoa);
|
|
}
|
|
}
|
|
}
|
|
|
|
else {
|
|
for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
|
|
for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
|
|
|
|
//UE2eNB[UE_id][eNB_id]->path_loss_dB = -105 + snr_dB;
|
|
if (eNB_id == (UE_id % NB_eNB_INST)) {
|
|
eNB2UE[eNB_id][UE_id]->path_loss_dB = -105 + snr_dB - PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower;
|
|
UE2eNB[UE_id][eNB_id]->path_loss_dB = -105 + snr_dB - PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower; //+20 to offset the difference in tx power of the UE wrt eNB
|
|
}
|
|
else {
|
|
eNB2UE[eNB_id][UE_id]->path_loss_dB = -105 + sinr_dB - PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower;
|
|
UE2eNB[UE_id][eNB_id]->path_loss_dB = -105 + sinr_dB - PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower;
|
|
}
|
|
LOG_I(OCM,"Path loss from eNB %d to UE %d => %f dB (eNB TX %d)\n",eNB_id,UE_id,eNB2UE[eNB_id][UE_id]->path_loss_dB,
|
|
PHY_vars_eNB_g[eNB_id]->lte_frame_parms.pdsch_config_common.referenceSignalPower);
|
|
// printf("[SIM] Path loss from UE %d to eNB %d => %f dB\n",UE_id,eNB_id,UE2eNB[UE_id][eNB_id]->path_loss_dB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void update_otg_eNB(int module_id, unsigned int ctime) {
|
|
#if defined(USER_MODE) && defined(OAI_EMU)
|
|
if (oai_emulation.info.otg_enabled ==1 ) {
|
|
|
|
int dst_id;
|
|
Packet_otg_elt *otg_pkt;
|
|
|
|
|
|
for (dst_id = 0; dst_id < NUMBER_OF_UE_MAX; dst_id++) {
|
|
for_times += 1;
|
|
// generate traffic if the ue is rrc reconfigured state
|
|
if (mac_get_rrc_status(module_id, 1/*eNB_flag*/, dst_id) > 2 /*RRC_CONNECTED*/ ) {
|
|
otg_pkt = malloc (sizeof(Packet_otg_elt));
|
|
if_times += 1;
|
|
|
|
(otg_pkt->otg_pkt).sdu_buffer = (u8*) packet_gen(module_id, dst_id + NB_eNB_INST, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size));
|
|
|
|
if ((otg_pkt->otg_pkt).sdu_buffer != NULL) {
|
|
otg_times += 1;
|
|
(otg_pkt->otg_pkt).rb_id = dst_id * NB_RB_MAX + DTCH;
|
|
(otg_pkt->otg_pkt).module_id = module_id;
|
|
(otg_pkt->otg_pkt).dst_id = dst_id;
|
|
(otg_pkt->otg_pkt).mode = PDCP_DATA_PDU;
|
|
//Adding the packet to the OTG-PDCP buffer
|
|
pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id]));
|
|
LOG_I(EMU, "[eNB %d] ADD pkt to OTG buffer for dst %d on rb_id %d\n", (otg_pkt->otg_pkt).module_id, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id);
|
|
} else {
|
|
//LOG_I(EMU, "OTG returns null \n");
|
|
free(otg_pkt);
|
|
otg_pkt=NULL;
|
|
}
|
|
}
|
|
LOG_T(EMU,"[eNB %d] UE mod id %d is not connected\n", module_id, dst_id);
|
|
//LOG_I(EMU,"HEAD of otg_pdcp_buffer[%d] is %p\n", module_id, pkt_list_get_head(&(otg_pdcp_buffer[module_id])));
|
|
}
|
|
|
|
#ifdef Rel10
|
|
int service_id, session_id, rb_id;
|
|
// MBSM multicast traffic
|
|
for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount
|
|
for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH
|
|
if (pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].instanciated_instance== module_id + 1){ // this service/session is configured
|
|
otg_pkt = malloc (sizeof(Packet_otg_elt));
|
|
// LOG_T(OTG,"multicast packet gen for (service/mch %d, session/lcid %d)\n", service_id, session_id);
|
|
rb_id = pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].rb_id;
|
|
(otg_pkt->otg_pkt).sdu_buffer = (u8*) packet_gen_multicast(module_id, session_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size));
|
|
if ((otg_pkt->otg_pkt).sdu_buffer != NULL) {
|
|
(otg_pkt->otg_pkt).rb_id = rb_id;
|
|
(otg_pkt->otg_pkt).module_id = module_id;
|
|
//(otg_pkt->otg_pkt).dst_id = session_id;
|
|
//Adding the packet to the OTG-PDCP buffer
|
|
(otg_pkt->otg_pkt).mode = PDCP_TM;
|
|
pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id]));
|
|
LOG_I(EMU, "[eNB %d] ADD pkt to OTG buffer for dst %d on rb_id %d\n", (otg_pkt->otg_pkt).module_id, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id);
|
|
} else {
|
|
//LOG_I(EMU, "OTG returns null \n");
|
|
free(otg_pkt);
|
|
otg_pkt=NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//LOG_I(EMU, "[eNB %d] update OTG nb_elts = %d \n", module_id, otg_pdcp_buffer[module_id].nb_elements);
|
|
|
|
//free(otg_pkt);
|
|
//otg_pkt = NULL;
|
|
}
|
|
#else
|
|
if (otg_enabled==1) {
|
|
ctime = frame * 100;
|
|
for (dst_id = 0; dst_id < NUMBER_OF_UE_MAX; dst_id++) {
|
|
if (mac_get_rrc_status(eNB_index, eNB_flag, dst_id ) > 2) {
|
|
otg_pkt = malloc (sizeof(Packet_otg_elt));
|
|
(otg_pkt->otg_pkt).sdu_buffer = packet_gen(module_id, dst_id, ctime, &pkt_size);
|
|
if (otg_pkt != NULL) {
|
|
rb_id = dst_id * NB_RB_MAX + DTCH;
|
|
(otg_pkt->otg_pkt).rb_id = rb_id;
|
|
(otg_pkt->otg_pkt).module_id = module_id;
|
|
(otg_pkt->otg_pkt).mode = PDCP_DATA_PDU;
|
|
//Adding the packet to the OTG-PDCP buffer
|
|
pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id]));
|
|
LOG_I(EMU, "[eNB %d] ADD pkt to OTG buffer for dst %d on rb_id %d\n", (otg_pkt->otg_pkt).module_id, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id);
|
|
} else {
|
|
//LOG_I(EMU, "OTG returns null \n");
|
|
free(otg_pkt);
|
|
otg_pkt=NULL;
|
|
}
|
|
/*else {
|
|
LOG_I(OTG,"nothing generated (src %d, dst %d)\n",src_id, dst_id);
|
|
}*/
|
|
}
|
|
/*else {
|
|
LOG_I(OTG,"rrc_status (src %d, dst %d) = %d\n",src_id, dst_id, mac_get_rrc_status(src_id, eNB_flag, dst_id ));
|
|
}*/
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void update_otg_UE(int UE_id, unsigned int ctime) {
|
|
#if defined(USER_MODE) && defined(OAI_EMU)
|
|
if (oai_emulation.info.otg_enabled ==1 ) {
|
|
int dst_id, src_id; //dst_id = eNB_index
|
|
int module_id = UE_id+NB_eNB_INST;
|
|
|
|
src_id = module_id;
|
|
|
|
for (dst_id=0;dst_id<NUMBER_OF_eNB_MAX;dst_id++) {
|
|
if (mac_get_rrc_status(UE_id, 0/*eNB_flag*/, dst_id ) > 2 /*RRC_CONNECTED*/) {
|
|
Packet_otg_elt *otg_pkt = malloc (sizeof(Packet_otg_elt));
|
|
// Manage to add this packet to the tail of your list
|
|
(otg_pkt->otg_pkt).sdu_buffer = (u8*) packet_gen(src_id, dst_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size));
|
|
|
|
if ((otg_pkt->otg_pkt).sdu_buffer != NULL) {
|
|
(otg_pkt->otg_pkt).rb_id = dst_id * NB_RB_MAX + DTCH;
|
|
(otg_pkt->otg_pkt).module_id = module_id;
|
|
(otg_pkt->otg_pkt).dst_id = dst_id;
|
|
//Adding the packet to the OTG-PDCP buffer
|
|
(otg_pkt->otg_pkt).mode = PDCP_DATA_PDU;
|
|
pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id]));
|
|
} else {
|
|
free(otg_pkt);
|
|
otg_pkt=NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
int init_slot_isr(void)
|
|
{
|
|
if (oai_emulation.info.slot_isr) {
|
|
struct itimerspec its;
|
|
|
|
int sfd;
|
|
|
|
sfd = timerfd_create(CLOCK_REALTIME, 0);
|
|
if (sfd == -1) {
|
|
LOG_E(EMU, "Failed in timerfd_create (%d:%s)\n", errno, strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Start the timer */
|
|
its.it_value.tv_sec = 0;
|
|
its.it_value.tv_nsec = 500 * 1000;
|
|
its.it_interval.tv_sec = its.it_value.tv_sec;
|
|
its.it_interval.tv_nsec = its.it_value.tv_nsec;
|
|
|
|
if (timerfd_settime(sfd, TFD_TIMER_ABSTIME, &its, NULL) == -1) {
|
|
LOG_E(EMU, "Failed in timer_settime (%d:%s)\n", errno, strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
oai_emulation.info.slot_sfd = sfd;
|
|
}
|
|
}
|
|
|
|
void wait_for_slot_isr(void)
|
|
{
|
|
uint64_t exp;
|
|
ssize_t res;
|
|
|
|
if (oai_emulation.info.slot_sfd > 0) {
|
|
res = read(oai_emulation.info.slot_sfd, &exp, sizeof(exp));
|
|
|
|
if ((res < 0) || (res != sizeof(exp))) {
|
|
LOG_E(EMU, "Failed in read (%d:%s)\n", errno, strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void exit_fun(const char* s)
|
|
{
|
|
void *array[10];
|
|
size_t size;
|
|
|
|
size = backtrace(array, 10);
|
|
backtrace_symbols_fd(array, size, 2);
|
|
|
|
fprintf(stderr, "Error: %s. Exiting!\n",s);
|
|
exit (-1);
|
|
}
|
|
|
|
void init_time() {
|
|
clock_gettime (CLOCK_REALTIME, &time_spec);
|
|
time_now = (unsigned long) time_spec.tv_nsec;
|
|
td_avg = 0;
|
|
sleep_time_us = SLEEP_STEP_US;
|
|
td_avg = TARGET_SF_TIME_NS;
|
|
}
|
|
|