Merge remote-tracking branch 'origin/develop' into feature-68-enb-agent
This commit is contained in:
@@ -268,6 +268,15 @@ Obj.# Case# Test# Description
|
||||
02 55 22 Band 7 FDD 10MHz DL Throughput (TCP) for 300 sec for 2TX/2RX (TM2)
|
||||
02 55 23 Band 7 FDD 20MHz DL Throughput (TCP) for 300 sec for 2TX/2RX (TM2)
|
||||
|
||||
02 57 lte-softmodem tests with USRP B210 RF as eNB and OAI EPC (eNB and EPC are on different machines) w/ OAI UE
|
||||
02 57 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX
|
||||
02 57 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX
|
||||
02 57 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX
|
||||
02 57 03 Band 7 FDD 5MHz DL Throughput for 300 sec for 1TX/1RX
|
||||
02 57 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX
|
||||
02 57 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX
|
||||
|
||||
|
||||
01 64 lte-softmodem-noS1 tests
|
||||
|
||||
02 Functional test case
|
||||
|
||||
@@ -552,7 +552,7 @@ def wait_testcaseclass_generic_threads(threadListGeneric, timeout = 1):
|
||||
# \param CleanupAluLteBox string that contains commands to stop ALU Bell Labs LTEBox (specified in test_case_list.xml)
|
||||
# \param ExmimoRfStop command to stop EXMIMO Card
|
||||
# \param nruns_lte-softmodem global parameter to override number of runs (nruns) within the test case
|
||||
def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo , logdirOpenaircnRepo, MachineList, user, password, CleanUpAluLteBox, ExmimoRfStop, nruns_lte_softmodem, timeout_cmd):
|
||||
def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo , logdirOpenaircnRepo, MachineList, user, password, CleanUpAluLteBox, ExmimoRfStop, nruns_lte_softmodem, GitOAI5GRepoBranch, GitOpenaircnRepoBranch,timeout_cmd):
|
||||
#We ignore the password sent to this function for secuirity reasons for password present in log files
|
||||
#It is recommended to add a line in /etc/sudoers that looks something like below. The line below will run sudo without password prompt
|
||||
# your_user_name ALL=(ALL:ALL) NOPASSWD: ALL
|
||||
@@ -583,7 +583,7 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
RRH_main_exec = testcase.findtext('RRH_main_exec',default='')
|
||||
RRH_main_exec_args = testcase.findtext('RRH_main_exec_args',default='')
|
||||
RRH_terminate_missing_procs = testcase.findtext('RRH_terminate_missing_procs',default='False')
|
||||
|
||||
RRH_branch = testcase.findtext('RRH_branch',default=GitOAI5GRepoBranch)
|
||||
|
||||
eNBMachine = testcase.findtext('eNB',default='')
|
||||
eNB_config_file = testcase.findtext('eNB_config_file',default='')
|
||||
@@ -599,6 +599,7 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
eNB_search_expr_true = testcase.findtext('eNB_search_expr_true','')
|
||||
if re.compile('\w+').match(eNB_search_expr_true) != None:
|
||||
eNB_search_expr_true = eNB_search_expr_true + ' duration=' + str(timeout_cmd-90) + 's'
|
||||
eNB_branch = testcase.findtext('eNB_branch',default=GitOAI5GRepoBranch)
|
||||
|
||||
UEMachine = testcase.findtext('UE',default='')
|
||||
UE_config_file = testcase.findtext('UE_config_file',default='')
|
||||
@@ -615,6 +616,7 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
UE_stop_script = testcase.findtext('UE_stop_script','')
|
||||
if re.compile('\w+').match(UE_search_expr_true) != None:
|
||||
UE_search_expr_true = UE_search_expr_true + ' duration=' + str(timeout_cmd-90) + 's'
|
||||
UE_branch = testcase.findtext('UE_branch',default=GitOAI5GRepoBranch)
|
||||
|
||||
EPCMachine = testcase.findtext('EPC',default='')
|
||||
EPC_config_file = testcase.findtext('EPC_config_file',default='')
|
||||
@@ -633,6 +635,8 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
EPC_traffic_exec_args = testcase.findtext('EPC_traffic_exec_args',default='')
|
||||
EPC_terminate_missing_procs = testcase.findtext('EPC_terminate_missing_procs',default='False')
|
||||
EPC_search_expr_true = testcase.findtext('EPC_search_expr_true','')
|
||||
EPC_branch = testcase.findtext('EPC_branch',default=GitOpenaircnRepoBranch)
|
||||
|
||||
if re.compile('\w+').match(EPC_search_expr_true) != None:
|
||||
EPC_search_expr_true = EPC_search_expr_true + ' duration=' + str(timeout_cmd-90) + 's'
|
||||
|
||||
@@ -689,7 +693,7 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
logdir_local_testcase = logdir_local + '/cmake_targets/autotests/log/'+ testcasename + '/run_' + str(run)
|
||||
#Make the log directory of test case
|
||||
if RRHMachine != '':
|
||||
cmd = 'rm -fr ' + logdir_RRH + ' ; mkdir -p ' + logdir_RRH
|
||||
cmd = 'rm -fr ' + logdir_RRH + ' ; mkdir -p ' + logdir_RRH
|
||||
result = oai_RRH.send_recv(cmd)
|
||||
cmd = 'rm -fr ' + logdir_eNB + ' ; mkdir -p ' + logdir_eNB
|
||||
result = oai_eNB.send_recv(cmd)
|
||||
@@ -709,7 +713,8 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
logfile_task_RRH_out = logdir_RRH + '/RRH_task_out' + '_' + str(run) + '_.log'
|
||||
logfile_task_RRH = logdir_local_testcase + '/RRH_task' + '_' + str(run) + '_.log'
|
||||
task_RRH_compile = ' ( uname -a ; date \n'
|
||||
task_RRH_compile = task_RRH_compile + 'cd ' + logdirOAI5GRepo + ' ; source oaienv ; source cmake_targets/tools/build_helper \n'
|
||||
task_RRH_compile = task_RRH_compile + 'cd ' + logdirOAI5GRepo + '; git reset --hard HEAD ; git checkout ' + RRH_branch + ' ; source oaienv \n'
|
||||
task_RRH_compile = task_RRH_compile + ' source cmake_targets/tools/build_helper \n'
|
||||
task_RRH_compile = task_RRH_compile + 'env |grep OPENAIR \n'
|
||||
task_RRH_compile = task_RRH_compile + update_config_file(oai_RRH, RRH_config_file, logdirOAI5GRepo, '$OPENAIR_DIR/cmake_targets/autotests/tools/search_repl.py') + '\n'
|
||||
if RRH_compile_prog != "":
|
||||
@@ -749,7 +754,8 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
logfile_pcap_tmp_eNB = '/tmp/' + '/eNB_tshark' + '_' + str(run) + '_.pcap'
|
||||
|
||||
task_eNB_compile = ' ( uname -a ; date \n'
|
||||
task_eNB_compile = task_eNB_compile + 'cd ' + logdirOAI5GRepo + ' ; source oaienv ; source cmake_targets/tools/build_helper \n'
|
||||
task_eNB_compile = task_eNB_compile + 'cd ' + logdirOAI5GRepo + '; git reset --hard HEAD ; git checkout ' + eNB_branch + ' ; source oaienv \n'
|
||||
task_eNB_compile = task_eNB_compile + ' source cmake_targets/tools/build_helper \n'
|
||||
task_eNB_compile = task_eNB_compile + 'env |grep OPENAIR \n'
|
||||
task_eNB_compile = task_eNB_compile + update_config_file(oai_eNB, eNB_config_file, logdirOAI5GRepo, '$OPENAIR_DIR/cmake_targets/autotests/tools/search_repl.py') + '\n'
|
||||
if eNB_compile_prog != "":
|
||||
@@ -799,8 +805,7 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
|
||||
task_UE_compile = ' ( uname -a ; date \n'
|
||||
task_UE_compile = task_UE_compile + 'array_exec_pid=()' + '\n'
|
||||
task_UE_compile = task_UE_compile + 'cd ' + logdirOAI5GRepo + '\n'
|
||||
task_UE_compile = task_UE_compile + 'source oaienv \n'
|
||||
task_UE_compile = task_UE_compile + 'cd ' + logdirOAI5GRepo + '; git reset --hard HEAD ; git checkout ' + UE_branch + ' ; source oaienv \n'
|
||||
task_UE_compile = task_UE_compile + 'source cmake_targets/tools/build_helper \n'
|
||||
task_UE_compile = task_UE_compile + 'env |grep OPENAIR \n'
|
||||
task_UE_compile = task_UE_compile + update_config_file(oai_UE, UE_config_file, logdirOAI5GRepo, '$OPENAIR_DIR/cmake_targets/autotests/tools/search_repl.py') + '\n'
|
||||
@@ -850,7 +855,7 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
|
||||
|
||||
task_EPC_compile = ' ( uname -a ; date \n'
|
||||
task_EPC_compile = task_EPC_compile + 'array_exec_pid=()' + '\n'
|
||||
task_EPC_compile = task_EPC_compile + 'cd ' + logdirOpenaircnRepo + ' ; source oaienv \n'
|
||||
task_EPC_compile = task_EPC_compile + 'cd ' + logdirOpenaircnRepo + '; git reset --hard HEAD ; git checkout ' + EPC_branch + ' ; source oaienv \n'
|
||||
task_EPC_compile = task_EPC_compile + update_config_file(oai_EPC, EPC_config_file, logdirOpenaircnRepo, logdirOpenaircnRepo+'/TEST/autotests/tools/search_repl.py') + '\n'
|
||||
task_EPC_compile = task_EPC_compile + 'source BUILD/TOOLS/build_helper \n'
|
||||
if EPC_compile_prog != "":
|
||||
@@ -2203,7 +2208,7 @@ for testcase in testcaseList:
|
||||
print "eNBMachine : " + eNBMachine + "UEMachine : " + UEMachine + "EPCMachine : " + EPCMachine + "MachineList : " + ','.join(MachineList)
|
||||
print "testcasename = " + testcasename + " class = " + testcaseclass
|
||||
#cleanOldProgramsAllMachines(oai_list, CleanUpOldProgs, CleanUpAluLteBox, ExmimoRfStop)
|
||||
handle_testcaseclass_softmodem (testcase, CleanUpOldProgs, logdirOAI5GRepo, logdirOpenaircnRepo, MachineList, user, pw, CleanUpAluLteBox, ExmimoRfStop, nruns_lte_softmodem, Timeout_cmd )
|
||||
handle_testcaseclass_softmodem (testcase, CleanUpOldProgs, logdirOAI5GRepo, logdirOpenaircnRepo, MachineList, user, pw, CleanUpAluLteBox, ExmimoRfStop, nruns_lte_softmodem, GitOAI5GRepoBranch, GitOpenaircnRepoBranch, Timeout_cmd )
|
||||
|
||||
#The lines below are copied from below to trace the failure of some of the machines in test setup. These lines below need to be removed in long term
|
||||
print "Creating xml file for overall results..."
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@ ID = ENB_PHY_DL_TICK
|
||||
ID = ENB_PHY_DLSCH_UE_DCI
|
||||
DESC = eNodeB downlink UE specific DCI as sent by the PHY layer
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format : int,harq_pid
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format : int,harq_pid : int,mcs : int,TBS
|
||||
ID = ENB_PHY_DLSCH_UE_ACK
|
||||
DESC = eNodeB downlink UE ACK as seen by the PHY layer in process_HARQ_feedback
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
@@ -28,7 +28,7 @@ ID = ENB_PHY_DLSCH_UE_NACK
|
||||
ID = ENB_PHY_ULSCH_UE_DCI
|
||||
DESC = eNodeB uplink UE specific DCI as sent by the PHY layer
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS
|
||||
ID = ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION
|
||||
DESC = eNodeB uplink UE retransmission due to PHICH NACK (see generate_phich_top)
|
||||
GROUP = ALL:PHY:GRAPHIC:ENB
|
||||
|
||||
+206
-54
@@ -24,6 +24,30 @@ typedef struct {
|
||||
view *pdcpview;
|
||||
view *rrcview;
|
||||
view *legacy;
|
||||
widget *current_ue_label;
|
||||
widget *prev_ue_button;
|
||||
widget *next_ue_button;
|
||||
widget *pusch_iq_ue_xy_plot;
|
||||
widget *ul_estimate_ue_xy_plot;
|
||||
widget *pucch1_energy_ue_xy_plot;
|
||||
widget *pucch_iq_ue_xy_plot;
|
||||
widget *dl_ul_harq_ue_label;
|
||||
widget *dl_mcs_xy_plot;
|
||||
widget *ul_mcs_xy_plot;
|
||||
logger *pusch_iq_ue_logger;
|
||||
logger *ul_estimate_ue_logger;
|
||||
logger *pucch1_energy_ue_threshold_logger;
|
||||
logger *pucch1_energy_ue_energy_logger;
|
||||
logger *pucch_iq_ue_logger;
|
||||
logger *dl_dci_logger[8];
|
||||
logger *dl_ack_logger[8];
|
||||
logger *dl_nack_logger[8];
|
||||
logger *ul_dci_logger[8];
|
||||
logger *ul_dci_retransmission_logger[8];
|
||||
logger *ul_ack_logger[8];
|
||||
logger *ul_nack_logger[8];
|
||||
logger *dl_mcs_logger;
|
||||
logger *ul_mcs_logger;
|
||||
} enb_gui;
|
||||
|
||||
typedef struct {
|
||||
@@ -31,6 +55,9 @@ typedef struct {
|
||||
int *is_on;
|
||||
int nevents;
|
||||
pthread_mutex_t lock;
|
||||
enb_gui *e;
|
||||
int ue; /* what UE is displayed in the UE specific views */
|
||||
void *database;
|
||||
} enb_data;
|
||||
|
||||
void is_on_changed(void *_d)
|
||||
@@ -86,18 +113,109 @@ static void *gui_thread(void *_g)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static filter *ticktime_filter(void *database, char *event, int i)
|
||||
static filter *ticktime_filter(void *database, char *event, int i, int ue)
|
||||
{
|
||||
/* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0" */
|
||||
return
|
||||
filter_and(
|
||||
filter_eq(filter_evarg(database, event, "harq_pid"), filter_int(i)),
|
||||
filter_and(
|
||||
filter_eq(filter_evarg(database, event, "UE_id"), filter_int(0)),
|
||||
filter_eq(filter_evarg(database, event, "UE_id"), filter_int(ue)),
|
||||
filter_eq(filter_evarg(database, event, "eNB_ID"), filter_int(0))));
|
||||
}
|
||||
|
||||
static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
static void set_current_ue(gui *g, enb_data *e, int ue)
|
||||
{
|
||||
int i;
|
||||
char s[256];
|
||||
|
||||
sprintf(s, "[UE %d] ", ue);
|
||||
label_set_text(g, e->e->current_ue_label, s);
|
||||
sprintf(s, "PUSCH IQ [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->pusch_iq_ue_xy_plot, s);
|
||||
sprintf(s, "UL estimated channel [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->ul_estimate_ue_xy_plot, s);
|
||||
sprintf(s, "PUCCH1 energy (SR) [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->pucch1_energy_ue_xy_plot, s);
|
||||
sprintf(s, "PUCCH IQ [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->pucch_iq_ue_xy_plot, s);
|
||||
sprintf(s, "DL/UL HARQ (x8) [UE %d]", ue);
|
||||
label_set_text(g, e->e->dl_ul_harq_ue_label, s);
|
||||
sprintf(s, "DL MCS [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->dl_mcs_xy_plot, s);
|
||||
sprintf(s, "UL MCS [UE %d]", ue);
|
||||
xy_plot_set_title(g, e->e->ul_mcs_xy_plot, s);
|
||||
|
||||
logger_set_filter(e->e->pusch_iq_ue_logger,
|
||||
filter_eq(
|
||||
filter_evarg(e->database, "ENB_PHY_PUSCH_IQ", "UE_ID"),
|
||||
filter_int(ue)));
|
||||
logger_set_filter(e->e->ul_estimate_ue_logger,
|
||||
filter_eq(
|
||||
filter_evarg(e->database, "ENB_PHY_UL_CHANNEL_ESTIMATE", "UE_ID"),
|
||||
filter_int(ue)));
|
||||
logger_set_filter(e->e->pucch1_energy_ue_threshold_logger,
|
||||
filter_eq(
|
||||
filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
|
||||
filter_int(ue)));
|
||||
logger_set_filter(e->e->pucch1_energy_ue_energy_logger,
|
||||
filter_eq(
|
||||
filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
|
||||
filter_int(ue)));
|
||||
logger_set_filter(e->e->pucch_iq_ue_logger,
|
||||
filter_eq(
|
||||
filter_evarg(e->database, "ENB_PHY_PUCCH_1AB_IQ", "UE_ID"),
|
||||
filter_int(ue)));
|
||||
for (i = 0; i < 8; i++) {
|
||||
logger_set_filter(e->e->dl_dci_logger[i],
|
||||
ticktime_filter(e->database, "ENB_PHY_DLSCH_UE_DCI", i, ue));
|
||||
logger_set_filter(e->e->dl_ack_logger[i],
|
||||
ticktime_filter(e->database, "ENB_PHY_DLSCH_UE_ACK", i, ue));
|
||||
logger_set_filter(e->e->dl_nack_logger[i],
|
||||
ticktime_filter(e->database, "ENB_PHY_DLSCH_UE_NACK", i, ue));
|
||||
logger_set_filter(e->e->ul_dci_logger[i],
|
||||
ticktime_filter(e->database, "ENB_PHY_ULSCH_UE_DCI", i, ue));
|
||||
logger_set_filter(e->e->ul_dci_retransmission_logger[i],
|
||||
ticktime_filter(e->database,
|
||||
"ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", i, ue));
|
||||
logger_set_filter(e->e->ul_ack_logger[i],
|
||||
ticktime_filter(e->database, "ENB_PHY_ULSCH_UE_ACK", i, ue));
|
||||
logger_set_filter(e->e->ul_nack_logger[i],
|
||||
ticktime_filter(e->database, "ENB_PHY_ULSCH_UE_NACK", i, ue));
|
||||
}
|
||||
logger_set_filter(e->e->dl_mcs_logger,
|
||||
filter_eq(
|
||||
filter_evarg(e->database, "ENB_PHY_DLSCH_UE_DCI", "UE_id"),
|
||||
filter_int(ue)));
|
||||
logger_set_filter(e->e->ul_mcs_logger,
|
||||
filter_eq(
|
||||
filter_evarg(e->database, "ENB_PHY_ULSCH_UE_DCI", "UE_id"),
|
||||
filter_int(ue)));
|
||||
}
|
||||
|
||||
static void click(void *private, gui *g,
|
||||
char *notification, widget *w, void *notification_data)
|
||||
{
|
||||
int *d = notification_data;
|
||||
int button = d[0];
|
||||
enb_data *ed = private;
|
||||
enb_gui *e = ed->e;
|
||||
int ue = ed->ue;
|
||||
|
||||
if (button != 1) return;
|
||||
if (w == e->prev_ue_button) { ue--; if (ue < 0) ue = 0; }
|
||||
if (w == e->next_ue_button) ue++;
|
||||
|
||||
if (pthread_mutex_lock(&ed->lock)) abort();
|
||||
if (ue != ed->ue) {
|
||||
set_current_ue(g, ed, ue);
|
||||
ed->ue = ue;
|
||||
}
|
||||
if (pthread_mutex_unlock(&ed->lock)) abort();
|
||||
}
|
||||
|
||||
static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
|
||||
enb_data *ed)
|
||||
{
|
||||
widget *main_window;
|
||||
widget *top_container;
|
||||
@@ -113,7 +231,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
widget *text;
|
||||
view *textview;
|
||||
int i;
|
||||
widget *w;
|
||||
widget *w, *w2;
|
||||
view *v;
|
||||
logger *l;
|
||||
|
||||
@@ -124,7 +242,26 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
line = new_container(g, HORIZONTAL);
|
||||
widget_add_child(g, top_container, line, -1);
|
||||
logo = new_image(g, openair_logo_png, openair_logo_png_len);
|
||||
widget_add_child(g, line, logo, -1);
|
||||
|
||||
/* logo + prev/next UE buttons */
|
||||
col = new_container(g, VERTICAL);
|
||||
widget_add_child(g, col, logo, -1);
|
||||
w = new_container(g, HORIZONTAL);
|
||||
widget_add_child(g, col, w, -1);
|
||||
w2 = new_label(g, "");
|
||||
widget_add_child(g, w, w2, -1);
|
||||
e->current_ue_label = w2;
|
||||
/* TODO: use button widget, not label widget */
|
||||
w2 = new_label(g, " [prev UE] ");
|
||||
widget_add_child(g, w, w2, -1);
|
||||
label_set_clickable(g, w2, 1);
|
||||
e->prev_ue_button = w2;
|
||||
w2 = new_label(g, " [next UE] ");
|
||||
widget_add_child(g, w, w2, -1);
|
||||
label_set_clickable(g, w2, 1);
|
||||
e->next_ue_button = w2;
|
||||
widget_add_child(g, line, col, -1);
|
||||
|
||||
input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20);
|
||||
widget_add_child(g, line, input_signal_plot, -1);
|
||||
xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70);
|
||||
@@ -138,21 +275,20 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
g, input_signal_plot, new_color(g, "#0c0c72"), XY_LOOP_MODE);
|
||||
logger_add_view(input_signal_log, input_signal_view);
|
||||
|
||||
/* UE 0 PUSCH IQ data */
|
||||
w = new_xy_plot(g, 55, 55, "PUSCH IQ [UE 0]", 50);
|
||||
/* UE x PUSCH IQ data */
|
||||
w = new_xy_plot(g, 55, 55, "", 50);
|
||||
e->pusch_iq_ue_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
xy_plot_set_range(g, w, -1000, 1000, -1000, 1000);
|
||||
l = new_iqlog(h, database, "ENB_PHY_PUSCH_IQ", "nb_rb",
|
||||
"N_RB_UL", "symbols_per_tti", "pusch_comp");
|
||||
v = new_view_xy(100*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "ENB_PHY_PUSCH_IQ", "UE_ID"),
|
||||
filter_int(0)));
|
||||
e->pusch_iq_ue_logger = l;
|
||||
|
||||
/* UE 0 estimated UL channel */
|
||||
w = new_xy_plot(g, 280, 55, "UL estimated channel [UE 0]", 50);
|
||||
/* UE x estimated UL channel */
|
||||
w = new_xy_plot(g, 280, 55, "", 50);
|
||||
e->ul_estimate_ue_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
xy_plot_set_range(g, w, 0, 512*10, -10, 80);
|
||||
l = new_framelog(h, database,
|
||||
@@ -161,43 +297,57 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
framelog_set_update_only_at_sf9(l, 0);
|
||||
v = new_view_xy(512*10, 10, g, w, new_color(g, "#0c0c72"), XY_LOOP_MODE);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "ENB_PHY_UL_CHANNEL_ESTIMATE", "UE_ID"),
|
||||
filter_int(0)));
|
||||
e->ul_estimate_ue_logger = l;
|
||||
|
||||
/* UE 0 PUCCH energy */
|
||||
w = new_xy_plot(g, 128, 55, "PUCCH1 energy (SR) [UE 0]", 50);
|
||||
/* UE x PUCCH energy */
|
||||
w = new_xy_plot(g, 128, 55, "", 50);
|
||||
e->pucch1_energy_ue_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
|
||||
l = new_ttilog(h, database,
|
||||
"ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "threshold", 0);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
|
||||
filter_int(0)));
|
||||
e->pucch1_energy_ue_threshold_logger = l;
|
||||
l = new_ttilog(h, database,
|
||||
"ENB_PHY_PUCCH_1_ENERGY", "frame", "subframe", "energy", 1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
|
||||
filter_int(0)));
|
||||
e->pucch1_energy_ue_energy_logger = l;
|
||||
|
||||
/* UE 0 PUCCH IQ data */
|
||||
w = new_xy_plot(g, 55, 55, "PUCCH IQ [UE 0]", 50);
|
||||
/* UE x PUCCH IQ data */
|
||||
w = new_xy_plot(g, 55, 55, "", 50);
|
||||
e->pucch_iq_ue_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
xy_plot_set_range(g, w, -100, 100, -100, 100);
|
||||
xy_plot_set_range(g, w, -2000, 2000, -2000, 2000);
|
||||
l = new_iqdotlog(h, database, "ENB_PHY_PUCCH_1AB_IQ", "I", "Q");
|
||||
v = new_view_xy(500, 10, g, w, new_color(g,"#000"), XY_LOOP_MODE);
|
||||
logger_add_view(l, v);
|
||||
logger_set_filter(l,
|
||||
filter_eq(
|
||||
filter_evarg(database, "ENB_PHY_PUCCH_1AB_IQ", "UE_ID"),
|
||||
filter_int(0)));
|
||||
e->pucch_iq_ue_logger = l;
|
||||
|
||||
/* UE x DL mcs */
|
||||
line = new_container(g, HORIZONTAL);
|
||||
widget_add_child(g, top_container, line, -1);
|
||||
w = new_xy_plot(g, 128, 55, "", 20);
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -2, 30);
|
||||
e->dl_mcs_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
|
||||
"ENB_PHY_DLSCH_UE_DCI", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
logger_add_view(l, v);
|
||||
e->dl_mcs_logger = l;
|
||||
|
||||
/* UE x UL mcs */
|
||||
w = new_xy_plot(g, 128, 55, "", 20);
|
||||
xy_plot_set_range(g, w, 0, 1024*10, -2, 30);
|
||||
e->ul_mcs_xy_plot = w;
|
||||
widget_add_child(g, line, w, -1);
|
||||
l = new_ticked_ttilog(h, database, "ENB_PHY_DL_TICK", "frame", "subframe",
|
||||
"ENB_PHY_ULSCH_UE_DCI", "mcs", 0, -1);
|
||||
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
|
||||
logger_add_view(l, v);
|
||||
e->ul_mcs_logger = l;
|
||||
|
||||
/* downlink/uplink UE DCIs */
|
||||
widget_add_child(g, top_container,
|
||||
@@ -250,8 +400,8 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
logger_add_view(timelog, subview);
|
||||
|
||||
/* harq processes' ticktime view */
|
||||
widget_add_child(g, top_container,
|
||||
new_label(g,"DL/UL HARQ (x8) [UE 0]"), -1);
|
||||
e->dl_ul_harq_ue_label = new_label(g, "");
|
||||
widget_add_child(g, top_container, e->dl_ul_harq_ue_label, -1);
|
||||
line = new_container(g, HORIZONTAL);
|
||||
widget_add_child(g, top_container, line, -1);
|
||||
timeline_plot = new_timeline(g, 512, 2*8+2, 3);
|
||||
@@ -271,15 +421,14 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
/* tick on UL view */
|
||||
subview = new_subview_ticktime(timeview, 9, new_color(g,"#bbb"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
/* DL harq pids */
|
||||
/* DL DCI */
|
||||
for (i = 0; i < 8; i++) {
|
||||
timelog = new_ticklog(h, database, "ENB_PHY_DLSCH_UE_DCI",
|
||||
"frame", "subframe");
|
||||
subview = new_subview_ticktime(timeview, i+1,
|
||||
new_color(g,"#55f"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
logger_set_filter(timelog,
|
||||
ticktime_filter(database, "ENB_PHY_DLSCH_UE_DCI", i));
|
||||
e->dl_dci_logger[i] = timelog;
|
||||
}
|
||||
/* DL ACK */
|
||||
for (i = 0; i < 8; i++) {
|
||||
@@ -288,8 +437,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
subview = new_subview_ticktime(timeview, i+1,
|
||||
new_color(g,"#282"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
logger_set_filter(timelog,
|
||||
ticktime_filter(database, "ENB_PHY_DLSCH_UE_ACK", i));
|
||||
e->dl_ack_logger[i] = timelog;
|
||||
}
|
||||
/* DL NACK */
|
||||
for (i = 0; i < 8; i++) {
|
||||
@@ -298,10 +446,9 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
subview = new_subview_ticktime(timeview, i+1,
|
||||
new_color(g,"#f22"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
logger_set_filter(timelog,
|
||||
ticktime_filter(database, "ENB_PHY_DLSCH_UE_NACK", i));
|
||||
e->dl_nack_logger[i] = timelog;
|
||||
}
|
||||
/* UL harq pids */
|
||||
/* UL DCI/retransmission without DCI */
|
||||
for (i = 0; i < 8; i++) {
|
||||
/* first transmission */
|
||||
timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_DCI",
|
||||
@@ -309,17 +456,14 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
subview = new_subview_ticktime(timeview, i+9+1,
|
||||
new_color(g,"#55f"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
logger_set_filter(timelog,
|
||||
ticktime_filter(database, "ENB_PHY_ULSCH_UE_DCI", i));
|
||||
e->ul_dci_logger[i] = timelog;
|
||||
/* retransmission */
|
||||
timelog = new_ticklog(h, database,
|
||||
"ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", "frame", "subframe");
|
||||
subview = new_subview_ticktime(timeview, i+9+1,
|
||||
new_color(g,"#99f"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
logger_set_filter(timelog,
|
||||
ticktime_filter(database,
|
||||
"ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", i));
|
||||
e->ul_dci_retransmission_logger[i] = timelog;
|
||||
}
|
||||
/* UL ACK */
|
||||
for (i = 0; i < 8; i++) {
|
||||
@@ -328,8 +472,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
subview = new_subview_ticktime(timeview, i+9+1,
|
||||
new_color(g,"#282"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
logger_set_filter(timelog,
|
||||
ticktime_filter(database, "ENB_PHY_ULSCH_UE_ACK", i));
|
||||
e->ul_ack_logger[i] = timelog;
|
||||
}
|
||||
/* UL NACK */
|
||||
for (i = 0; i < 8; i++) {
|
||||
@@ -338,8 +481,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
subview = new_subview_ticktime(timeview, i+9+1,
|
||||
new_color(g,"#f22"), 3600*1000);
|
||||
logger_add_view(timelog, subview);
|
||||
logger_set_filter(timelog,
|
||||
ticktime_filter(database, "ENB_PHY_ULSCH_UE_NACK", i));
|
||||
e->ul_nack_logger[i] = timelog;
|
||||
}
|
||||
|
||||
/* phy/mac/rlc/pdcp/rrc textlog */
|
||||
@@ -416,6 +558,10 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database)
|
||||
widget_add_child(g, top_container, text, -1);
|
||||
container_set_child_growable(g, top_container, text, 1);
|
||||
e->legacy = new_view_textlist(10000, 10, g, text);
|
||||
|
||||
set_current_ue(g, ed, 0);
|
||||
register_notifier(g, "click", e->prev_ue_button, click, ed);
|
||||
register_notifier(g, "click", e->next_ue_button, click, ed);
|
||||
}
|
||||
|
||||
void view_add_log(view *v, char *log, event_handler *h, void *database,
|
||||
@@ -495,7 +641,11 @@ int main(int n, char **v)
|
||||
g = gui_init();
|
||||
new_thread(gui_thread, g);
|
||||
|
||||
enb_main_gui(&eg, g, h, database);
|
||||
enb_data.ue = 0;
|
||||
enb_data.e = ⪚
|
||||
enb_data.database = database;
|
||||
|
||||
enb_main_gui(&eg, g, h, database, &enb_data);
|
||||
|
||||
for (i = 0; i < number_of_events; i++) {
|
||||
logger *textlog;
|
||||
@@ -639,7 +789,9 @@ restart:
|
||||
event e;
|
||||
e = get_event(enb_data.socket, v, database);
|
||||
if (e.type == -1) goto restart;
|
||||
if (pthread_mutex_lock(&enb_data.lock)) abort();
|
||||
handle_event(h, e);
|
||||
if (pthread_mutex_unlock(&enb_data.lock)) abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -13,6 +13,7 @@ struct filter {
|
||||
} v;
|
||||
|
||||
int (*eval)(struct filter *this, event e);
|
||||
void (*free)(struct filter *this);
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -52,7 +53,23 @@ int eval_evarg(struct filter *f, event e)
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* filter construction functions */
|
||||
/* free memory functions */
|
||||
/****************************************************************************/
|
||||
|
||||
void free_op2(struct filter *f)
|
||||
{
|
||||
free_filter(f->v.op2.a);
|
||||
free_filter(f->v.op2.b);
|
||||
free(f);
|
||||
}
|
||||
|
||||
void free_noop(struct filter *f)
|
||||
{
|
||||
free(f);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* filter construction/destruction functions */
|
||||
/****************************************************************************/
|
||||
|
||||
filter *filter_and(filter *a, filter *b)
|
||||
@@ -60,6 +77,7 @@ filter *filter_and(filter *a, filter *b)
|
||||
struct filter *ret = calloc(1, sizeof(struct filter));
|
||||
if (ret == NULL) abort();
|
||||
ret->eval = eval_and;
|
||||
ret->free = free_op2;
|
||||
ret->v.op2.a = a;
|
||||
ret->v.op2.b = b;
|
||||
return ret;
|
||||
@@ -70,6 +88,7 @@ filter *filter_eq(filter *a, filter *b)
|
||||
struct filter *ret = calloc(1, sizeof(struct filter));
|
||||
if (ret == NULL) abort();
|
||||
ret->eval = eval_eq;
|
||||
ret->free = free_op2;
|
||||
ret->v.op2.a = a;
|
||||
ret->v.op2.b = b;
|
||||
return ret;
|
||||
@@ -80,6 +99,7 @@ filter *filter_int(int v)
|
||||
struct filter *ret = calloc(1, sizeof(struct filter));
|
||||
if (ret == NULL) abort();
|
||||
ret->eval = eval_int;
|
||||
ret->free = free_noop;
|
||||
ret->v.v = v;
|
||||
return ret;
|
||||
}
|
||||
@@ -97,6 +117,7 @@ filter *filter_evarg(void *database, char *event_name, char *varname)
|
||||
f = get_format(database, event_id);
|
||||
|
||||
ret->eval = eval_evarg;
|
||||
ret->free = free_noop;
|
||||
ret->v.evarg.event_type = event_id;
|
||||
ret->v.evarg.arg_index = -1;
|
||||
|
||||
@@ -114,6 +135,14 @@ filter *filter_evarg(void *database, char *event_name, char *varname)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void free_filter(filter *_f)
|
||||
{
|
||||
struct filter *f;
|
||||
if (_f == NULL) return;
|
||||
f = _f;
|
||||
f->free(f);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* eval function */
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -12,4 +12,6 @@ filter *filter_evarg(void *database, char *event_name, char *varname);
|
||||
|
||||
int filter_eval(filter *f, event e);
|
||||
|
||||
void free_filter(filter *f);
|
||||
|
||||
#endif /* _FILTER_H_ */
|
||||
|
||||
@@ -2,8 +2,8 @@ CC=gcc
|
||||
CFLAGS=-Wall -g -pthread -I/usr/include/X11/Xft -I/usr/include/freetype2
|
||||
|
||||
OBJS=init.o loop.o toplevel_window.o x.o container.o widget.o \
|
||||
gui.o label.o event.o xy_plot.o textlist.o notify.o positioner.o \
|
||||
timeline.o space.o image.o
|
||||
gui.o label.o textarea.o event.o xy_plot.o textlist.o notify.o \
|
||||
positioner.o timeline.o space.o image.o
|
||||
|
||||
gui.a: $(OBJS)
|
||||
ar cr gui.a $(OBJS)
|
||||
|
||||
@@ -14,6 +14,10 @@ typedef void widget;
|
||||
|
||||
#define DEFAULT_FONT 0
|
||||
|
||||
/* tic type for XY plot */
|
||||
#define XY_PLOT_DEFAULT_TICK 0
|
||||
#define XY_PLOT_SCROLL_TICK 1
|
||||
|
||||
/* key modifiers */
|
||||
#define KEY_SHIFT (1<<0)
|
||||
#define KEY_CONTROL (1<<1)
|
||||
@@ -30,6 +34,7 @@ widget *new_toplevel_window(gui *gui, int width, int height, char *title);
|
||||
widget *new_container(gui *gui, int vertical);
|
||||
widget *new_positioner(gui *gui);
|
||||
widget *new_label(gui *gui, const char *text);
|
||||
widget *new_textarea(gui *gui, int width, int height, int maxsize);
|
||||
widget *new_xy_plot(gui *gui, int width, int height, char *label,
|
||||
int vruler_width);
|
||||
widget *new_textlist(gui *gui, int width, int nlines, int background_color);
|
||||
@@ -39,6 +44,9 @@ widget *new_space(gui *gui, int width, int height);
|
||||
widget *new_image(gui *gui, unsigned char *data, int length);
|
||||
|
||||
void label_set_clickable(gui *gui, widget *label, int clickable);
|
||||
void label_set_text(gui *gui, widget *label, char *text);
|
||||
|
||||
void textarea_set_text(gui *gui, widget *textarea, char *text);
|
||||
|
||||
void container_set_child_growable(gui *_gui, widget *_this,
|
||||
widget *child, int growable);
|
||||
@@ -49,6 +57,8 @@ void xy_plot_set_range(gui *gui, widget *this,
|
||||
void xy_plot_set_points(gui *gui, widget *this,
|
||||
int plot, int npoints, float *x, float *y);
|
||||
void xy_plot_get_dimensions(gui *gui, widget *this, int *width, int *height);
|
||||
void xy_plot_set_title(gui *gui, widget *this, char *label);
|
||||
void xy_plot_set_tick_type(gui *gui, widget *this, int type);
|
||||
|
||||
void textlist_add(gui *gui, widget *this, const char *text, int position,
|
||||
int color);
|
||||
|
||||
@@ -31,7 +31,7 @@ extern int volatile gui_logd;
|
||||
|
||||
enum widget_type {
|
||||
TOPLEVEL_WINDOW, CONTAINER, POSITIONER, TEXT_LIST, XY_PLOT, BUTTON, LABEL,
|
||||
TIMELINE, SPACE, IMAGE
|
||||
TEXTAREA, TIMELINE, SPACE, IMAGE
|
||||
};
|
||||
|
||||
struct widget_list;
|
||||
@@ -117,6 +117,7 @@ struct xy_plot_widget {
|
||||
int wanted_height;
|
||||
struct xy_plot_plot *plots;
|
||||
int nplots;
|
||||
int tick_type;
|
||||
};
|
||||
|
||||
struct timeline_subline {
|
||||
@@ -141,13 +142,24 @@ struct button_widget {
|
||||
|
||||
struct label_widget {
|
||||
struct widget common;
|
||||
const char *t;
|
||||
char *t;
|
||||
int color;
|
||||
int width; /* as given by the graphic's backend */
|
||||
int height; /* as given by the graphic's backend */
|
||||
int baseline; /* as given by the graphic's backend */
|
||||
};
|
||||
|
||||
struct textarea_widget {
|
||||
struct widget common;
|
||||
char *t;
|
||||
int tmaxsize;
|
||||
int color;
|
||||
int wanted_width;
|
||||
int wanted_height;
|
||||
int baseline; /* as given by the graphic's backend */
|
||||
int text_width; /* as given by the graphic's backend */
|
||||
};
|
||||
|
||||
struct space_widget {
|
||||
struct widget common;
|
||||
int wanted_width;
|
||||
|
||||
@@ -81,3 +81,21 @@ void label_set_clickable(gui *_g, widget *_this, int clickable)
|
||||
|
||||
gunlock(g);
|
||||
}
|
||||
|
||||
void label_set_text(gui *_g, widget *_this, char *text)
|
||||
{
|
||||
struct gui *g = _g;
|
||||
struct label_widget *this = _this;
|
||||
|
||||
glock(g);
|
||||
|
||||
free(this->t);
|
||||
this->t = strdup(text); if (this->t == NULL) OOM;
|
||||
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, text,
|
||||
&this->width, &this->height, &this->baseline);
|
||||
|
||||
send_event(g, REPACK, this->common.id);
|
||||
|
||||
gunlock(g);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "gui.h"
|
||||
#include "gui_defs.h"
|
||||
#include "x.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void paint(gui *_gui, widget *_w)
|
||||
{
|
||||
struct gui *g = _gui;
|
||||
struct textarea_widget *t = _w;
|
||||
LOGD("PAINT textarea '%s'\n", t->t);
|
||||
x_fill_rectangle(g->x, g->xwin, BACKGROUND_COLOR,
|
||||
t->common.x, t->common.y,
|
||||
t->common.width, t->common.height);
|
||||
x_draw_clipped_string(g->x, g->xwin, DEFAULT_FONT, t->color,
|
||||
t->common.x + t->common.width - t->text_width,
|
||||
t->common.y + t->baseline, t->t,
|
||||
t->common.x, t->common.y,
|
||||
t->common.width, t->common.height);
|
||||
}
|
||||
|
||||
static void hints(gui *_gui, widget *_w, int *width, int *height)
|
||||
{
|
||||
struct textarea_widget *t = _w;
|
||||
LOGD("HINTS textarea '%s'\n", t->t);
|
||||
*width = t->wanted_width;
|
||||
*height = t->wanted_height;
|
||||
}
|
||||
|
||||
widget *new_textarea(gui *_gui, int width, int height, int maxsize)
|
||||
{
|
||||
struct gui *g = _gui;
|
||||
struct textarea_widget *w;
|
||||
int _;
|
||||
|
||||
glock(g);
|
||||
|
||||
w = new_widget(g, TEXTAREA, sizeof(struct textarea_widget));
|
||||
|
||||
w->t = calloc(maxsize, 1);
|
||||
if (w->t == NULL) OOM;
|
||||
w->tmaxsize = maxsize;
|
||||
w->wanted_width = width;
|
||||
w->wanted_height = height;
|
||||
w->color = FOREGROUND_COLOR;
|
||||
w->text_width = 0;
|
||||
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, "jlM",
|
||||
&_, &_, &w->baseline);
|
||||
|
||||
w->common.paint = paint;
|
||||
w->common.hints = hints;
|
||||
|
||||
gunlock(g);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* public functions */
|
||||
/*************************************************************************/
|
||||
|
||||
void textarea_set_text(gui *_g, widget *_this, char *text)
|
||||
{
|
||||
struct gui *g = _g;
|
||||
struct textarea_widget *this = _this;
|
||||
int _;
|
||||
int len = strlen(text);
|
||||
if (len >= this->tmaxsize) {
|
||||
fprintf(stderr, "ERROR: string '%s' too big for textarea\n", text);
|
||||
return;
|
||||
}
|
||||
|
||||
glock(g);
|
||||
|
||||
strcpy(this->t, text);
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, text,
|
||||
&this->text_width, &_, &this->baseline);
|
||||
send_event(g, DIRTY, this->common.id);
|
||||
|
||||
gunlock(g);
|
||||
}
|
||||
@@ -265,7 +265,7 @@ void widget_dirty(gui *_gui, widget *_this)
|
||||
|
||||
static const char *names[] = {
|
||||
"TOPLEVEL_WINDOW", "CONTAINER", "POSITIONER", "TEXT_LIST",
|
||||
"XY_PLOT", "BUTTON", "LABEL", "TIMELINE", "SPACE", "IMAGE"
|
||||
"XY_PLOT", "BUTTON", "LABEL", "TEXTAREA", "TIMELINE", "SPACE", "IMAGE"
|
||||
};
|
||||
const char *widget_name(enum widget_type type)
|
||||
{
|
||||
@@ -277,6 +277,7 @@ const char *widget_name(enum widget_type type)
|
||||
case XY_PLOT:
|
||||
case BUTTON:
|
||||
case LABEL:
|
||||
case TEXTAREA:
|
||||
case TIMELINE:
|
||||
case SPACE:
|
||||
case IMAGE:
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
#include "gui.h"
|
||||
#include "gui_defs.h"
|
||||
#include "x.h"
|
||||
#include "../utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#if 0
|
||||
/* this version behaves differently when you resize the XY plot. Say
|
||||
* you increase the size. The old (smaller) view is put at the center
|
||||
* of the new view. Everything inside keeps the same size/aspect ratio.
|
||||
* The other version below resizes the old view so that it fully occupies
|
||||
* the new view. It may introduce aspect ratio changes, but usage seems
|
||||
* to suggest it's a better behaviour.
|
||||
*/
|
||||
static void paint(gui *_gui, widget *_this)
|
||||
{
|
||||
struct gui *g = _gui;
|
||||
@@ -70,9 +79,9 @@ static void paint(gui *_gui, widget *_this)
|
||||
*/
|
||||
char v[64];
|
||||
int vwidth, dummy;
|
||||
float x = (k * ticstep - allocated_xmin) /
|
||||
(allocated_xmax - allocated_xmin) *
|
||||
(allocated_plot_width - 1);
|
||||
int x = (k * ticstep - allocated_xmin) /
|
||||
(allocated_xmax - allocated_xmin) *
|
||||
(allocated_plot_width - 1);
|
||||
x_draw_line(g->x, g->xwin, FOREGROUND_COLOR,
|
||||
this->common.x + this->vrule_width + x,
|
||||
this->common.y + this->common.height - this->label_height * 2,
|
||||
@@ -85,7 +94,7 @@ static void paint(gui *_gui, widget *_this)
|
||||
this->common.y + this->common.height - this->label_height * 2 +
|
||||
this->label_baseline,
|
||||
v);
|
||||
LOGD("tic k %d val %g x %g\n", k, k * ticstep, x);
|
||||
LOGD("tic k %d val %g x %d\n", k, k * ticstep, x);
|
||||
}
|
||||
|
||||
/* vertical tics */
|
||||
@@ -112,9 +121,9 @@ static void paint(gui *_gui, widget *_this)
|
||||
for (k = kmin; k <= kmax; k++) {
|
||||
char v[64];
|
||||
int vwidth, dummy;
|
||||
float y = (k * ticstep - allocated_ymin) /
|
||||
(allocated_ymax - allocated_ymin) *
|
||||
(allocated_plot_height - 1);
|
||||
int y = (k * ticstep - allocated_ymin) /
|
||||
(allocated_ymax - allocated_ymin) *
|
||||
(allocated_plot_height - 1);
|
||||
sprintf(v, "%g", k * ticstep);
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy);
|
||||
x_draw_line(g->x, g->xwin, FOREGROUND_COLOR,
|
||||
@@ -155,6 +164,184 @@ static void paint(gui *_gui, widget *_this)
|
||||
x_plot_points(g->x, g->xwin, this->plots[n].color);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void paint(gui *_gui, widget *_this)
|
||||
{
|
||||
struct gui *g = _gui;
|
||||
struct xy_plot_widget *this = _this;
|
||||
int allocated_plot_width;
|
||||
int allocated_plot_height;
|
||||
float pxsize;
|
||||
float ticdist;
|
||||
float tic;
|
||||
float ticstep;
|
||||
int k, kmin, kmax;
|
||||
float allocated_xmin, allocated_xmax;
|
||||
float allocated_ymin, allocated_ymax;
|
||||
int i;
|
||||
int n;
|
||||
char v[64];
|
||||
int vwidth, dummy;
|
||||
|
||||
# define FLIP(v) (-(v) + allocated_plot_height-1)
|
||||
|
||||
LOGD("PAINT xy plot xywh %d %d %d %d\n", this->common.x, this->common.y, this->common.width, this->common.height);
|
||||
|
||||
//x_draw_rectangle(g->x, g->xwin, 1, this->common.x, this->common.y, this->common.width, this->common.height);
|
||||
|
||||
allocated_plot_width = this->common.width - this->vrule_width;
|
||||
allocated_plot_height = this->common.height - this->label_height * 2;
|
||||
|
||||
if (allocated_plot_width <= 1 || allocated_plot_height <= 1) {
|
||||
WARN("PAINT xy plot: width (%d) or height (%d) is wrong, not painting\n",
|
||||
this->common.width, this->common.height);
|
||||
return;
|
||||
}
|
||||
|
||||
/* plot zone */
|
||||
/* TODO: refine height - height of hrule text may be != from label */
|
||||
x_draw_rectangle(g->x, g->xwin, 1,
|
||||
this->common.x + this->vrule_width,
|
||||
this->common.y,
|
||||
this->common.width - this->vrule_width -1, /* -1 to see right border */
|
||||
this->common.height - this->label_height * 2);
|
||||
|
||||
/* horizontal tics */
|
||||
pxsize = (this->xmax - this->xmin) / allocated_plot_width;
|
||||
ticdist = 100;
|
||||
tic = floor(log10(ticdist * pxsize));
|
||||
ticstep = powf(10, tic);
|
||||
allocated_xmin = this->xmin;
|
||||
allocated_xmax = this->xmax;
|
||||
/* adjust tic if too tight */
|
||||
LOGD("pre x ticstep %g\n", ticstep);
|
||||
while (1) {
|
||||
if (ticstep / (allocated_xmax - allocated_xmin)
|
||||
* (allocated_plot_width - 1) > 40) break;
|
||||
ticstep *= 2;
|
||||
}
|
||||
LOGD("post x ticstep %g\n", ticstep);
|
||||
LOGD("xmin/max %g %g width allocated %d alloc xmin/max %g %g ticstep %g\n", this->xmin, this->xmax, allocated_plot_width, allocated_xmin, allocated_xmax, ticstep);
|
||||
kmin = ceil(allocated_xmin / ticstep);
|
||||
kmax = floor(allocated_xmax / ticstep);
|
||||
for (k = kmin; k <= kmax; k++) {
|
||||
/*
|
||||
(k * ticstep - allocated_xmin) / (allocated_max - allocated_xmin) =
|
||||
(x - 0) / (allocated_plot_width-1 - 0)
|
||||
*/
|
||||
int x = (k * ticstep - allocated_xmin) /
|
||||
(allocated_xmax - allocated_xmin) *
|
||||
(allocated_plot_width - 1);
|
||||
int px;
|
||||
x_draw_line(g->x, g->xwin, FOREGROUND_COLOR,
|
||||
this->common.x + this->vrule_width + x,
|
||||
this->common.y + this->common.height - this->label_height * 2,
|
||||
this->common.x + this->vrule_width + x,
|
||||
this->common.y + this->common.height - this->label_height * 2 - 5);
|
||||
sprintf(v, "%g", k * ticstep);
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy);
|
||||
|
||||
/* do not draw after the widget ('width-1' for if we use 'width'
|
||||
* it is still off by 1 pixel for whatever reason) */
|
||||
px = this->vrule_width + x - vwidth/2;
|
||||
if (px + vwidth > this->common.width-1)
|
||||
px = this->common.width-1 - vwidth;
|
||||
|
||||
x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR,
|
||||
this->common.x + px,
|
||||
this->common.y + this->common.height - this->label_height * 2 +
|
||||
this->label_baseline,
|
||||
v);
|
||||
LOGD("tic k %d val %g x %d\n", k, k * ticstep, x);
|
||||
}
|
||||
|
||||
/* vertical tics */
|
||||
allocated_ymin = this->ymin;
|
||||
allocated_ymax = this->ymax;
|
||||
switch (this->tick_type) {
|
||||
case XY_PLOT_DEFAULT_TICK:
|
||||
pxsize = (this->ymax - this->ymin) / allocated_plot_height;
|
||||
ticdist = 30;
|
||||
tic = floor(log10(ticdist * pxsize));
|
||||
ticstep = powf(10, tic);
|
||||
/* adjust tic if too tight */
|
||||
LOGD("pre y ticstep %g\n", ticstep);
|
||||
while (1) {
|
||||
if (ticstep / (allocated_ymax - allocated_ymin)
|
||||
* (allocated_plot_height - 1) > 20) break;
|
||||
ticstep *= 2;
|
||||
}
|
||||
LOGD("post y ticstep %g\n", ticstep);
|
||||
LOGD("ymin/max %g %g height allocated %d alloc "
|
||||
"ymin/max %g %g ticstep %g\n", this->ymin, this->ymax,
|
||||
allocated_plot_height, allocated_ymin, allocated_ymax, ticstep);
|
||||
kmin = ceil(allocated_ymin / ticstep);
|
||||
kmax = floor(allocated_ymax / ticstep);
|
||||
for (k = kmin; k <= kmax; k++) {
|
||||
int y = (k * ticstep - allocated_ymin) /
|
||||
(allocated_ymax - allocated_ymin) *
|
||||
(allocated_plot_height - 1);
|
||||
sprintf(v, "%g", k * ticstep);
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy);
|
||||
x_draw_line(g->x, g->xwin, FOREGROUND_COLOR,
|
||||
this->common.x + this->vrule_width,
|
||||
this->common.y + FLIP(y),
|
||||
this->common.x + this->vrule_width + 5,
|
||||
this->common.y + FLIP(y));
|
||||
x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR,
|
||||
this->common.x + this->vrule_width - vwidth - 2,
|
||||
this->common.y + FLIP(y)-this->label_height/2+this->label_baseline,
|
||||
v);
|
||||
}
|
||||
break;
|
||||
case XY_PLOT_SCROLL_TICK:
|
||||
/* print only max value, formatted using 'bps' for readability */
|
||||
bps(v, this->ymax, "");
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, v, &vwidth, &dummy, &dummy);
|
||||
x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR,
|
||||
this->common.x + this->vrule_width - vwidth - 2,
|
||||
this->common.y + +this->label_baseline,
|
||||
v);
|
||||
/* vertically divide into 5 */
|
||||
for (k = 1; k < 5; k++) {
|
||||
int y = round((k * (allocated_plot_height - 1)) / 5.);
|
||||
x_draw_line(g->x, g->xwin, FOREGROUND_COLOR,
|
||||
this->common.x + this->vrule_width,
|
||||
this->common.y + y,
|
||||
this->common.x + this->vrule_width + 5,
|
||||
this->common.y + y);
|
||||
}
|
||||
break;
|
||||
} /* swich (this->tick_type) */
|
||||
|
||||
/* label at bottom, in the middle */
|
||||
x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR,
|
||||
this->common.x + (this->common.width - this->label_width) / 2,
|
||||
this->common.y + this->common.height - this->label_height
|
||||
+ this->label_baseline,
|
||||
this->label);
|
||||
|
||||
for (n = 0; n < this->nplots; n++) {
|
||||
/* points */
|
||||
float ax, bx, ay, by;
|
||||
ax = (allocated_plot_width-1) / (allocated_xmax - allocated_xmin);
|
||||
bx = -ax * allocated_xmin;
|
||||
ay = (allocated_plot_height-1) / (allocated_ymax - allocated_ymin);
|
||||
by = -ay * allocated_ymin;
|
||||
for (i = 0; i < this->plots[n].npoints; i++) {
|
||||
int x, y;
|
||||
x = ax * this->plots[n].x[i] + bx;
|
||||
y = ay * this->plots[n].y[i] + by;
|
||||
if (x >= 0 && x < allocated_plot_width &&
|
||||
y >= 0 && y < allocated_plot_height)
|
||||
x_add_point(g->x,
|
||||
this->common.x + this->vrule_width + x,
|
||||
this->common.y + FLIP(y));
|
||||
}
|
||||
x_plot_points(g->x, g->xwin, this->plots[n].color);
|
||||
}
|
||||
}
|
||||
|
||||
static void hints(gui *_gui, widget *_w, int *width, int *height)
|
||||
{
|
||||
@@ -191,6 +378,7 @@ widget *new_xy_plot(gui *_gui, int width, int height, char *label,
|
||||
w->ymax = 1;
|
||||
w->plots = NULL;
|
||||
w->nplots = 0;
|
||||
w->tick_type = XY_PLOT_DEFAULT_TICK;
|
||||
|
||||
w->common.paint = paint;
|
||||
w->common.hints = hints;
|
||||
@@ -290,3 +478,36 @@ void xy_plot_get_dimensions(gui *_gui, widget *_this, int *width, int *height)
|
||||
|
||||
gunlock(g);
|
||||
}
|
||||
|
||||
void xy_plot_set_title(gui *_gui, widget *_this, char *label)
|
||||
{
|
||||
struct gui *g = _gui;
|
||||
struct xy_plot_widget *this = _this;
|
||||
|
||||
glock(g);
|
||||
|
||||
free(this->label);
|
||||
this->label = strdup(label); if (this->label == NULL) OOM;
|
||||
/* TODO: be sure calling X there is valid wrt "global model" (we are
|
||||
* not in the "gui thread") */
|
||||
x_text_get_dimensions(g->x, DEFAULT_FONT, label,
|
||||
&this->label_width, &this->label_height, &this->label_baseline);
|
||||
|
||||
send_event(g, REPACK, this->common.id);
|
||||
|
||||
gunlock(g);
|
||||
}
|
||||
|
||||
void xy_plot_set_tick_type(gui *_gui, widget *_this, int type)
|
||||
{
|
||||
struct gui *g = _gui;
|
||||
struct xy_plot_widget *this = _this;
|
||||
|
||||
glock(g);
|
||||
|
||||
this->tick_type = type;
|
||||
|
||||
send_event(g, DIRTY, this->common.id);
|
||||
|
||||
gunlock(g);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ CC=gcc
|
||||
CFLAGS=-Wall -g -pthread -I..
|
||||
|
||||
OBJS=logger.o textlog.o framelog.o ttilog.o timelog.o ticklog.o iqlog.o \
|
||||
iqdotlog.o
|
||||
iqdotlog.o ticked_ttilog.o throughputlog.o
|
||||
|
||||
logger.a: $(OBJS)
|
||||
ar cr logger.a $(OBJS)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "logger.h"
|
||||
#include "logger_defs.h"
|
||||
#include "filter/filter.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void logger_add_view(logger *_l, view *v)
|
||||
@@ -13,5 +14,6 @@ void logger_add_view(logger *_l, view *v)
|
||||
void logger_set_filter(logger *_l, void *filter)
|
||||
{
|
||||
struct logger *l = _l;
|
||||
free_filter(l->filter);
|
||||
l->filter = filter;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,13 @@ logger *new_textlog(void *event_handler, void *database,
|
||||
logger *new_ttilog(void *event_handler, void *database,
|
||||
char *event_name, char *frame_varname, char *subframe_varname,
|
||||
char *data_varname, int convert_to_dB);
|
||||
logger *new_ticked_ttilog(void *event_handler, void *database,
|
||||
char *tick_event_name, char *frame_varname, char *subframe_varname,
|
||||
char *event_name, char *data_varname,
|
||||
int convert_to_dB, float empty_value);
|
||||
logger *new_throughputlog(void *event_handler, void *database,
|
||||
char *tick_event_name, char *frame_varname, char *subframe_varname,
|
||||
char *event_name, char *data_varname);
|
||||
logger *new_timelog(void *event_handler, void *database, char *event_name);
|
||||
logger *new_ticklog(void *event_handler, void *database,
|
||||
char *event_name, char *frame_name, char *subframe_name);
|
||||
@@ -28,5 +35,6 @@ void textlog_dump_buffer(logger *_this, int dump_buffer);
|
||||
|
||||
void logger_add_view(logger *l, view *v);
|
||||
void logger_set_filter(logger *l, void *filter);
|
||||
void ticked_ttilog_set_tick_filter(logger *l, void *filter);
|
||||
|
||||
#endif /* _LOGGER_H_ */
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "logger.h"
|
||||
#include "logger_defs.h"
|
||||
#include "event.h"
|
||||
#include "database.h"
|
||||
#include "handler.h"
|
||||
#include "filter/filter.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
struct throughputlog {
|
||||
struct logger common;
|
||||
void *database;
|
||||
int tick_frame_arg;
|
||||
int tick_subframe_arg;
|
||||
int data_frame_arg;
|
||||
int data_subframe_arg;
|
||||
int data_arg;
|
||||
int last_tick_frame;
|
||||
int last_tick_subframe;
|
||||
unsigned long bits[1000];
|
||||
unsigned long total;
|
||||
int insert_point;
|
||||
char *tick_event_name;
|
||||
unsigned long tick_handler_id;
|
||||
/* tick filter - NULL is no filter set */
|
||||
void *tick_filter;
|
||||
};
|
||||
|
||||
static void _event(void *p, event e)
|
||||
{
|
||||
struct throughputlog *l = p;
|
||||
int frame;
|
||||
int subframe;
|
||||
unsigned long value;
|
||||
|
||||
if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0)
|
||||
return;
|
||||
|
||||
frame = e.e[l->data_frame_arg].i;
|
||||
subframe = e.e[l->data_subframe_arg].i;
|
||||
|
||||
if (frame != l->last_tick_frame || subframe != l->last_tick_subframe) {
|
||||
printf("WARNING: %s:%d: data comes without previous tick!\n",
|
||||
__FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.e[l->data_arg].type) {
|
||||
case EVENT_INT: value = e.e[l->data_arg].i; break;
|
||||
case EVENT_ULONG: value = e.e[l->data_arg].ul; break;
|
||||
default: printf("%s:%d: unsupported type\n", __FILE__, __LINE__); abort();
|
||||
}
|
||||
|
||||
l->total += value;
|
||||
l->bits[l->insert_point] += value;
|
||||
}
|
||||
|
||||
static void _tick_event(void *p, event e)
|
||||
{
|
||||
struct throughputlog *l = p;
|
||||
int i;
|
||||
int frame;
|
||||
int subframe;
|
||||
|
||||
if (l->tick_filter != NULL && filter_eval(l->tick_filter, e) == 0)
|
||||
return;
|
||||
|
||||
frame = e.e[l->tick_frame_arg].i;
|
||||
subframe = e.e[l->tick_subframe_arg].i;
|
||||
|
||||
for (i = 0; i < l->common.vsize; i++)
|
||||
l->common.v[i]->append(l->common.v[i], frame, subframe, (double)l->total);
|
||||
|
||||
l->insert_point = (l->insert_point + 1) % 1000;
|
||||
l->total -= l->bits[l->insert_point];
|
||||
l->bits[l->insert_point] = 0;
|
||||
|
||||
l->last_tick_frame = frame;
|
||||
l->last_tick_subframe = subframe;
|
||||
}
|
||||
|
||||
logger *new_throughputlog(event_handler *h, void *database,
|
||||
char *tick_event_name, char *frame_varname, char *subframe_varname,
|
||||
char *event_name, char *data_varname)
|
||||
{
|
||||
struct throughputlog *ret;
|
||||
int event_id;
|
||||
database_event_format f;
|
||||
int i;
|
||||
|
||||
ret = calloc(1, sizeof(struct throughputlog)); if (ret == NULL) abort();
|
||||
|
||||
ret->common.event_name = strdup(event_name);
|
||||
if (ret->common.event_name == NULL) abort();
|
||||
ret->database = database;
|
||||
|
||||
ret->tick_event_name = strdup(tick_event_name);
|
||||
if (ret->tick_event_name == NULL) abort();
|
||||
|
||||
/* tick event */
|
||||
event_id = event_id_from_name(database, tick_event_name);
|
||||
|
||||
ret->tick_handler_id=register_handler_function(h,event_id,_tick_event,ret);
|
||||
|
||||
f = get_format(database, event_id);
|
||||
|
||||
/* look for frame and subframe */
|
||||
ret->tick_frame_arg = -1;
|
||||
ret->tick_subframe_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], frame_varname)) ret->tick_frame_arg = i;
|
||||
if (!strcmp(f.name[i], subframe_varname)) ret->tick_subframe_arg = i;
|
||||
}
|
||||
if (ret->tick_frame_arg == -1) {
|
||||
printf("%s:%d: frame argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, frame_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->tick_subframe_arg == -1) {
|
||||
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, subframe_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->tick_frame_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, frame_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->tick_subframe_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, subframe_varname);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* data event */
|
||||
event_id = event_id_from_name(database, event_name);
|
||||
|
||||
ret->common.handler_id = register_handler_function(h,event_id,_event,ret);
|
||||
|
||||
f = get_format(database, event_id);
|
||||
|
||||
/* look for frame, subframe and data args */
|
||||
ret->data_frame_arg = -1;
|
||||
ret->data_subframe_arg = -1;
|
||||
ret->data_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], frame_varname)) ret->data_frame_arg = i;
|
||||
if (!strcmp(f.name[i], subframe_varname)) ret->data_subframe_arg = i;
|
||||
if (!strcmp(f.name[i], data_varname)) ret->data_arg = i;
|
||||
}
|
||||
if (ret->data_frame_arg == -1) {
|
||||
printf("%s:%d: frame argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, frame_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->data_subframe_arg == -1) {
|
||||
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, subframe_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->data_arg == -1) {
|
||||
printf("%s:%d: data argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, data_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_frame_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, frame_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_subframe_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, subframe_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_arg], "int") != 0 &&
|
||||
strcmp(f.type[ret->data_arg], "float") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type"
|
||||
" (should be 'int' or 'float')\n",
|
||||
__FILE__, __LINE__, data_varname);
|
||||
abort();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void throughputlog_set_tick_filter(logger *_l, void *filter)
|
||||
{
|
||||
struct throughputlog *l = (struct throughputlog *)_l;
|
||||
free(l->tick_filter);
|
||||
l->tick_filter = filter;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
#include "logger.h"
|
||||
#include "logger_defs.h"
|
||||
#include "event.h"
|
||||
#include "database.h"
|
||||
#include "handler.h"
|
||||
#include "filter/filter.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
struct ticked_ttilog {
|
||||
struct logger common;
|
||||
void *database;
|
||||
int tick_frame_arg;
|
||||
int tick_subframe_arg;
|
||||
int data_frame_arg;
|
||||
int data_subframe_arg;
|
||||
int data_arg;
|
||||
int convert_to_dB;
|
||||
int last_tick_frame;
|
||||
int last_tick_subframe;
|
||||
float last_value;
|
||||
float empty_value;
|
||||
char *tick_event_name;
|
||||
unsigned long tick_handler_id;
|
||||
/* tick filter - NULL is no filter set */
|
||||
void *tick_filter;
|
||||
};
|
||||
|
||||
static void _event(void *p, event e)
|
||||
{
|
||||
struct ticked_ttilog *l = p;
|
||||
int frame;
|
||||
int subframe;
|
||||
float value;
|
||||
|
||||
if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0)
|
||||
return;
|
||||
|
||||
frame = e.e[l->data_frame_arg].i;
|
||||
subframe = e.e[l->data_subframe_arg].i;
|
||||
|
||||
if (frame != l->last_tick_frame || subframe != l->last_tick_subframe) {
|
||||
printf("WARNING: %s:%d: data comes without previous tick!\n",
|
||||
__FILE__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.e[l->data_arg].type) {
|
||||
case EVENT_INT: value = e.e[l->data_arg].i; break;
|
||||
case EVENT_ULONG: value = e.e[l->data_arg].ul; break;
|
||||
default: printf("%s:%d: unsupported type\n", __FILE__, __LINE__); abort();
|
||||
}
|
||||
|
||||
if (l->convert_to_dB) value = 10 * log10(value);
|
||||
|
||||
l->last_value = value;
|
||||
}
|
||||
|
||||
static void _tick_event(void *p, event e)
|
||||
{
|
||||
struct ticked_ttilog *l = p;
|
||||
int i;
|
||||
int frame;
|
||||
int subframe;
|
||||
|
||||
if (l->tick_filter != NULL && filter_eval(l->tick_filter, e) == 0)
|
||||
return;
|
||||
|
||||
frame = e.e[l->tick_frame_arg].i;
|
||||
subframe = e.e[l->tick_subframe_arg].i;
|
||||
|
||||
for (i = 0; i < l->common.vsize; i++)
|
||||
l->common.v[i]->append(l->common.v[i], frame, subframe, l->last_value);
|
||||
|
||||
l->last_value = l->empty_value;
|
||||
l->last_tick_frame = frame;
|
||||
l->last_tick_subframe = subframe;
|
||||
}
|
||||
|
||||
logger *new_ticked_ttilog(event_handler *h, void *database,
|
||||
char *tick_event_name, char *frame_varname, char *subframe_varname,
|
||||
char *event_name, char *data_varname,
|
||||
int convert_to_dB, float empty_value)
|
||||
{
|
||||
struct ticked_ttilog *ret;
|
||||
int event_id;
|
||||
database_event_format f;
|
||||
int i;
|
||||
|
||||
ret = calloc(1, sizeof(struct ticked_ttilog)); if (ret == NULL) abort();
|
||||
|
||||
ret->common.event_name = strdup(event_name);
|
||||
if (ret->common.event_name == NULL) abort();
|
||||
ret->database = database;
|
||||
ret->convert_to_dB = convert_to_dB;
|
||||
|
||||
ret->tick_event_name = strdup(tick_event_name);
|
||||
if (ret->tick_event_name == NULL) abort();
|
||||
ret->empty_value = empty_value;
|
||||
ret->last_value = empty_value;
|
||||
|
||||
/* tick event */
|
||||
event_id = event_id_from_name(database, tick_event_name);
|
||||
|
||||
ret->tick_handler_id=register_handler_function(h,event_id,_tick_event,ret);
|
||||
|
||||
f = get_format(database, event_id);
|
||||
|
||||
/* look for frame and subframe */
|
||||
ret->tick_frame_arg = -1;
|
||||
ret->tick_subframe_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], frame_varname)) ret->tick_frame_arg = i;
|
||||
if (!strcmp(f.name[i], subframe_varname)) ret->tick_subframe_arg = i;
|
||||
}
|
||||
if (ret->tick_frame_arg == -1) {
|
||||
printf("%s:%d: frame argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, frame_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->tick_subframe_arg == -1) {
|
||||
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, subframe_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->tick_frame_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, frame_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->tick_subframe_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, subframe_varname);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* data event */
|
||||
event_id = event_id_from_name(database, event_name);
|
||||
|
||||
ret->common.handler_id = register_handler_function(h,event_id,_event,ret);
|
||||
|
||||
f = get_format(database, event_id);
|
||||
|
||||
/* look for frame, subframe and data args */
|
||||
ret->data_frame_arg = -1;
|
||||
ret->data_subframe_arg = -1;
|
||||
ret->data_arg = -1;
|
||||
for (i = 0; i < f.count; i++) {
|
||||
if (!strcmp(f.name[i], frame_varname)) ret->data_frame_arg = i;
|
||||
if (!strcmp(f.name[i], subframe_varname)) ret->data_subframe_arg = i;
|
||||
if (!strcmp(f.name[i], data_varname)) ret->data_arg = i;
|
||||
}
|
||||
if (ret->data_frame_arg == -1) {
|
||||
printf("%s:%d: frame argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, frame_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->data_subframe_arg == -1) {
|
||||
printf("%s:%d: subframe argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, subframe_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (ret->data_arg == -1) {
|
||||
printf("%s:%d: data argument '%s' not found in event '%s'\n",
|
||||
__FILE__, __LINE__, data_varname, event_name);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_frame_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, frame_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_subframe_arg], "int") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type (should be 'int')\n",
|
||||
__FILE__, __LINE__, subframe_varname);
|
||||
abort();
|
||||
}
|
||||
if (strcmp(f.type[ret->data_arg], "int") != 0 &&
|
||||
strcmp(f.type[ret->data_arg], "float") != 0) {
|
||||
printf("%s:%d: argument '%s' has wrong type"
|
||||
" (should be 'int' or 'float')\n",
|
||||
__FILE__, __LINE__, data_varname);
|
||||
abort();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ticked_ttilog_set_tick_filter(logger *_l, void *filter)
|
||||
{
|
||||
struct ticked_ttilog *l = (struct ticked_ttilog *)_l;
|
||||
free(l->tick_filter);
|
||||
l->tick_filter = filter;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
|
||||
void new_thread(void *(*f)(void *), void *data)
|
||||
{
|
||||
@@ -36,6 +37,16 @@ void sleepms(int ms)
|
||||
if (nanosleep(&t, NULL)) abort();
|
||||
}
|
||||
|
||||
void bps(char *out, float v, char *suffix)
|
||||
{
|
||||
static char *bps_unit[4] = { "", "k", "M", "G" };
|
||||
int flog;
|
||||
if (v < 1000) flog = 0; else flog = floor(floor(log10(v)) / 3);
|
||||
if (flog > 3) flog = 3;
|
||||
v /= pow(10, flog*3);
|
||||
sprintf(out, "%g%s%s", round(v*100)/100, bps_unit[flog], suffix);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* list */
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
void new_thread(void *(*f)(void *), void *data);
|
||||
void sleepms(int ms);
|
||||
void bps(char *out, float v, char *suffix);
|
||||
|
||||
/****************************************************************************/
|
||||
/* list */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
CC=gcc
|
||||
CFLAGS=-Wall -g -pthread -I.. -I../logger
|
||||
|
||||
OBJS=stdout.o textlist.o xy.o tti.o time.o ticktime.o
|
||||
OBJS=stdout.o textlist.o xy.o tti.o time.o ticktime.o scrolltti.o
|
||||
|
||||
view.a: $(OBJS)
|
||||
ar cr view.a $(OBJS)
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "view.h"
|
||||
#include "../utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
struct scrolltti {
|
||||
view common;
|
||||
gui *g;
|
||||
widget *w;
|
||||
widget *throughput_textarea;
|
||||
int plot;
|
||||
float refresh_rate;
|
||||
pthread_mutex_t lock;
|
||||
unsigned long data[1000];
|
||||
unsigned long total; /* sum data[0..999] to have smoother value printed */
|
||||
float xout[1000];
|
||||
float yout[1000];
|
||||
int insert_point;
|
||||
};
|
||||
|
||||
/* this array is used to get Y range 1000, 2000, 5000, 10000, ... */
|
||||
static int tolog[11] = { -1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10 };
|
||||
|
||||
static void *scrolltti_thread(void *_this)
|
||||
{
|
||||
struct scrolltti *this = _this;
|
||||
int i;
|
||||
int p;
|
||||
float max, mlog;
|
||||
char o[64];
|
||||
|
||||
while (1) {
|
||||
if (pthread_mutex_lock(&this->lock)) abort();
|
||||
/* TODO: optimize */
|
||||
p = this->insert_point;
|
||||
max = 0;
|
||||
for (i = 0; i < 1000; i++) {
|
||||
this->xout[i] = i;
|
||||
this->yout[i] = this->data[p];
|
||||
if (this->data[p] > max) max = this->data[p];
|
||||
p = (p + 1) % 1000;
|
||||
}
|
||||
bps(o, this->total/1000., "b/s");
|
||||
textarea_set_text(this->g, this->throughput_textarea, o);
|
||||
/* for Y range we want 1000, 2000, 5000, 10000, 20000, 50000, etc. */
|
||||
if (max < 1000) max = 1000;
|
||||
mlog = pow(10, floor(log10(max)));
|
||||
max = tolog[(int)ceil(max/mlog)] * mlog;
|
||||
xy_plot_set_range(this->g, this->w, 0, 1000, 0, max);
|
||||
xy_plot_set_points(this->g, this->w, this->plot,
|
||||
1000, this->xout, this->yout);
|
||||
if (pthread_mutex_unlock(&this->lock)) abort();
|
||||
sleepms(1000/this->refresh_rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clear(view *this)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void append(view *_this, int frame, int subframe, double value)
|
||||
{
|
||||
struct scrolltti *this = (struct scrolltti *)_this;
|
||||
|
||||
if (pthread_mutex_lock(&this->lock)) abort();
|
||||
this->total -= this->data[this->insert_point];
|
||||
this->data[this->insert_point] = value;
|
||||
this->total += this->data[this->insert_point];
|
||||
this->insert_point = (this->insert_point + 1) % 1000;
|
||||
if (pthread_mutex_unlock(&this->lock)) abort();
|
||||
}
|
||||
|
||||
view *new_view_scrolltti(float refresh_rate, gui *g, widget *w, int color,
|
||||
widget *throughput_textarea)
|
||||
{
|
||||
struct scrolltti *ret = calloc(1, sizeof(struct scrolltti));
|
||||
if (ret == NULL) abort();
|
||||
|
||||
ret->common.clear = clear;
|
||||
ret->common.append = (void (*)(view *, ...))append;
|
||||
|
||||
ret->refresh_rate = refresh_rate;
|
||||
ret->g = g;
|
||||
ret->w = w;
|
||||
ret->throughput_textarea = throughput_textarea;
|
||||
ret->plot = xy_plot_new_plot(g, w, color);
|
||||
|
||||
if (pthread_mutex_init(&ret->lock, NULL)) abort();
|
||||
|
||||
new_thread(scrolltti_thread, ret);
|
||||
|
||||
return (view *)ret;
|
||||
}
|
||||
@@ -19,6 +19,8 @@ view *new_view_xy(int length, float refresh_rate, gui *g, widget *w,
|
||||
int color, enum xy_mode mode);
|
||||
view *new_view_tti(float refresh_rate, gui *g, widget *w,
|
||||
int color);
|
||||
view *new_view_scrolltti(float refresh_rate, gui *g, widget *w,
|
||||
int color, widget *throughput_label);
|
||||
view *new_view_time(int number_of_seconds, float refresh_rate,
|
||||
gui *g, widget *w);
|
||||
view *new_subview_time(view *time, int line, int color, int size);
|
||||
|
||||
@@ -779,7 +779,9 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
|
||||
|
||||
T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id),
|
||||
T_INT(dci_alloc->rnti), T_INT(dci_alloc->format),
|
||||
T_INT(eNB->dlsch[(int)UE_id][0]->current_harq_pid));
|
||||
T_INT(eNB->dlsch[(int)UE_id][0]->current_harq_pid),
|
||||
T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[eNB->dlsch[(int)UE_id][0]->current_harq_pid]->mcs),
|
||||
T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[eNB->dlsch[(int)UE_id][0]->current_harq_pid]->TBS));
|
||||
|
||||
eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
|
||||
|
||||
@@ -873,8 +875,12 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
|
||||
eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
|
||||
|
||||
T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id),
|
||||
T_INT(dci_alloc->rnti), T_INT(harq_pid));
|
||||
|
||||
T_INT(dci_alloc->rnti), T_INT(harq_pid),
|
||||
T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->mcs),
|
||||
T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->round),
|
||||
T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->first_rb),
|
||||
T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->nb_rb),
|
||||
T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->TBS));
|
||||
}
|
||||
|
||||
void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int num_pdcch_symbols) {
|
||||
@@ -1138,7 +1144,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
|
||||
|
||||
#endif
|
||||
|
||||
if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_DL)) return;
|
||||
if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
|
||||
if (do_meas==1) start_meas(&eNB->phy_proc_tx);
|
||||
|
||||
@@ -876,11 +876,8 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
|
||||
|
||||
if (openair0_cfg[card].rx_freq[ant]>0) {
|
||||
p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX + RXLPFNORM + RXLPFEN + rx_filter);
|
||||
|
||||
p_exmimo_config->rf.rf_freq_rx[ant] = (unsigned int)openair0_cfg[card].rx_freq[ant];
|
||||
|
||||
printf("openair0 : programming card %d RX antenna %d (freq %u, gain %d)\n",card,ant,p_exmimo_config->rf.rf_freq_rx[ant],p_exmimo_config->rf.rx_gain[ant][0]);
|
||||
|
||||
switch (openair0_cfg[card].rxg_mode[ant]) {
|
||||
default:
|
||||
case max_gain:
|
||||
@@ -916,6 +913,8 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
|
||||
}
|
||||
break;
|
||||
}
|
||||
printf("openair0 : programming card %d RX antenna %d (freq %u, gain %d)\n",card,ant,p_exmimo_config->rf.rf_freq_rx[ant],p_exmimo_config->rf.rx_gain[ant][0]);
|
||||
|
||||
} else {
|
||||
p_exmimo_config->rf.rf_mode[ant] = 0;
|
||||
p_exmimo_config->rf.do_autocal[ant] = 0;
|
||||
|
||||
+30
-21
@@ -134,8 +134,8 @@ time_stats_t softmodem_stats_mt; // main thread
|
||||
time_stats_t softmodem_stats_hw; // hw acquisition
|
||||
time_stats_t softmodem_stats_rxtx_sf; // total tx time
|
||||
time_stats_t softmodem_stats_rx_sf; // total rx time
|
||||
int32_t **rxdata;
|
||||
int32_t **txdata;
|
||||
//int32_t **rxdata;
|
||||
//int32_t **txdata;
|
||||
|
||||
uint8_t seqno; //sequence number
|
||||
|
||||
@@ -302,12 +302,13 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
|
||||
6,
|
||||
phy_vars_eNB->frame_parms.nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF],
|
||||
dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1),
|
||||
phy_vars_eNB->frame_parms.ofdm_symbol_size,
|
||||
6,
|
||||
phy_vars_eNB->frame_parms.nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL)
|
||||
PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF],
|
||||
dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1),
|
||||
phy_vars_eNB->frame_parms.ofdm_symbol_size,
|
||||
6,
|
||||
phy_vars_eNB->frame_parms.nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F],
|
||||
dummy_tx_b,
|
||||
@@ -385,7 +386,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
|
||||
// turn on tx switch N_TA_offset before
|
||||
//LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset);
|
||||
for (i=0; i<phy_vars_eNB->N_TA_offset; i++) {
|
||||
tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2;
|
||||
tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset;
|
||||
if (tx_offset<0)
|
||||
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
|
||||
|
||||
@@ -468,8 +469,16 @@ void proc_tx_full(PHY_VARS_eNB *eNB,
|
||||
// if TX fronthaul go ahead
|
||||
if (eNB->tx_fh) eNB->tx_fh(eNB,proc);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (proc->frame_tx>1000) {
|
||||
write_output("/tmp/txsig0.m","txs0", &eNB->common_vars.txdata[eNB->Mod_id][0][0], eNB->frame_parms.samples_per_tti*10,1,1);
|
||||
write_output("/tmp/txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB->Mod_id][0][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
|
||||
write_output("/tmp/txsig1.m","txs1", &eNB->common_vars.txdata[eNB->Mod_id][1][0], eNB->frame_parms.samples_per_tti*10,1,1);
|
||||
write_output("/tmp/txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB->Mod_id][1][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
|
||||
//if (transmission_mode == 7) write_output("/tmp/txsigF5.m","txsF5", &eNB->common_vars.txdataF[eNB->Mod_id][5][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
|
||||
exit_fun("");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void proc_tx_rru_if4p5(PHY_VARS_eNB *eNB,
|
||||
@@ -539,7 +548,8 @@ int wait_CCs(eNB_rxtx_proc_t *proc) {
|
||||
static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
|
||||
|
||||
start_meas(&softmodem_stats_rxtx_sf);
|
||||
// ****************************************
|
||||
|
||||
// ****************************************
|
||||
// Common RX procedures subframe n
|
||||
phy_procedures_eNB_common_RX(eNB);
|
||||
|
||||
@@ -1477,7 +1487,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
|
||||
int i, CC_id;
|
||||
int j;
|
||||
|
||||
uint16_t N_TA_offset = 0;
|
||||
//uint16_t N_TA_offset = 0;
|
||||
|
||||
LTE_DL_FRAME_PARMS *frame_parms;
|
||||
|
||||
@@ -1490,6 +1500,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
if (frame_parms->frame_type == TDD) {
|
||||
if (frame_parms->N_RB_DL == 100)
|
||||
N_TA_offset = 624;
|
||||
@@ -1498,7 +1509,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
|
||||
else if (frame_parms->N_RB_DL == 25)
|
||||
N_TA_offset = 624/4;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
if (openair0_cfg[CC_id].mmapped_dma == 1) {
|
||||
@@ -1508,11 +1519,8 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
|
||||
printf("Mapping eNB CC_id %d, rx_ant %d\n",CC_id,i);
|
||||
free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
|
||||
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[CC_id].rxbase[i];
|
||||
|
||||
|
||||
|
||||
|
||||
printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
|
||||
|
||||
for (j=0; j<16; j++) {
|
||||
printf("rxbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j]);
|
||||
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j] = 16-j;
|
||||
@@ -1533,15 +1541,15 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
|
||||
}
|
||||
}
|
||||
else { // not memory-mapped DMA
|
||||
|
||||
|
||||
//nothing to do, everything already allocated in lte_init
|
||||
/*
|
||||
rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
|
||||
txdata = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
|
||||
|
||||
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
|
||||
free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
|
||||
rxdata[i] = (int32_t*)(32 + malloc16(32+frame_parms->samples_per_tti*10*sizeof(int32_t))); // FIXME broken memory allocation
|
||||
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory
|
||||
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]; //-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory
|
||||
memset(rxdata[i], 0, frame_parms->samples_per_tti*10*sizeof(int32_t));
|
||||
printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i],rxdata[i],N_TA_offset);
|
||||
}
|
||||
@@ -1553,6 +1561,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
|
||||
memset(txdata[i],0, frame_parms->samples_per_tti*10*sizeof(int32_t));
|
||||
printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1339,12 +1339,6 @@ void init_openair0() {
|
||||
else
|
||||
openair0_cfg[card].rx_freq[i]=0.0;
|
||||
|
||||
printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
|
||||
card,i, openair0_cfg[card].tx_gain[i],
|
||||
openair0_cfg[card].rx_gain[i],
|
||||
openair0_cfg[card].tx_freq[i],
|
||||
openair0_cfg[card].rx_freq[i]);
|
||||
|
||||
openair0_cfg[card].autocal[i] = 1;
|
||||
openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
|
||||
if (UE_flag == 0) {
|
||||
@@ -1354,10 +1348,12 @@ void init_openair0() {
|
||||
openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off;
|
||||
}
|
||||
|
||||
|
||||
printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
|
||||
card,i, openair0_cfg[card].tx_gain[i],
|
||||
openair0_cfg[card].rx_gain[i],
|
||||
openair0_cfg[card].tx_freq[i],
|
||||
openair0_cfg[card].rx_freq[i]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1587,7 +1583,18 @@ int main( int argc, char **argv )
|
||||
|
||||
UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
|
||||
UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
|
||||
UE[CC_id]->N_TA_offset = 0;
|
||||
|
||||
if (frame_parms[CC_id]->frame_type==FDD) {
|
||||
UE[CC_id]->N_TA_offset = 0;
|
||||
}
|
||||
else {
|
||||
if (frame_parms[CC_id]->N_RB_DL == 100)
|
||||
UE[CC_id]->N_TA_offset = 624;
|
||||
else if (frame_parms[CC_id]->N_RB_DL == 50)
|
||||
UE[CC_id]->N_TA_offset = 624/2;
|
||||
else if (frame_parms[CC_id]->N_RB_DL == 25)
|
||||
UE[CC_id]->N_TA_offset = 624/4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1627,8 +1634,17 @@ int main( int argc, char **argv )
|
||||
|
||||
PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0];
|
||||
|
||||
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
|
||||
|
||||
if (frame_parms[CC_id]->frame_type==FDD) {
|
||||
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
|
||||
}
|
||||
else {
|
||||
if (frame_parms[CC_id]->N_RB_DL == 100)
|
||||
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624;
|
||||
else if (frame_parms[CC_id]->N_RB_DL == 50)
|
||||
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2;
|
||||
else if (frame_parms[CC_id]->N_RB_DL == 25)
|
||||
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+12
-12
@@ -98,8 +98,8 @@ extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
extern int oai_exit;
|
||||
|
||||
extern int32_t **rxdata;
|
||||
extern int32_t **txdata;
|
||||
int32_t **rxdata;
|
||||
int32_t **txdata;
|
||||
|
||||
//extern unsigned int tx_forward_nsamps;
|
||||
//extern int tx_delay;
|
||||
@@ -1628,14 +1628,14 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
|
||||
}
|
||||
|
||||
/*
|
||||
if (frame_parms->frame_type == TDD) {
|
||||
if (frame_parms->frame_type == TDD) {
|
||||
if (frame_parms->N_RB_DL == 100)
|
||||
N_TA_offset = 624;
|
||||
else if (frame_parms->N_RB_DL == 50)
|
||||
N_TA_offset = 624/2;
|
||||
else if (frame_parms->N_RB_DL == 25)
|
||||
N_TA_offset = 624/4;
|
||||
}
|
||||
N_TA_offset = 624;
|
||||
else if (frame_parms->N_RB_DL == 50)
|
||||
N_TA_offset = 624/2;
|
||||
else if (frame_parms->N_RB_DL == 25)
|
||||
N_TA_offset = 624/4;
|
||||
}
|
||||
*/
|
||||
|
||||
// replace RX signal buffers with mmaped HW versions
|
||||
@@ -1645,9 +1645,9 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
|
||||
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
|
||||
printf( "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i );
|
||||
free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
|
||||
rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
|
||||
phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
|
||||
printf("rxdata[%d] : %p\n",i,rxdata[i]);
|
||||
rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
|
||||
phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
|
||||
printf("rxdata[%d] : %p\n",i,rxdata[i]);
|
||||
}
|
||||
|
||||
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
|
||||
|
||||
Reference in New Issue
Block a user