Commit d9255b5c authored by hbilel's avatar hbilel

[OAI-UE] T-tracer UE updates

parent 378020ce
...@@ -30,14 +30,16 @@ typedef struct { ...@@ -30,14 +30,16 @@ typedef struct {
widget *pdsch_iq_ue_xy_plot; widget *pdsch_iq_ue_xy_plot;
widget *dl_estimate_ue_xy_plot; widget *dl_estimate_ue_xy_plot;
widget *pdcch_energy_ue_xy_plot; widget *pdcch_energy_ue_xy_plot;
widget *pdsch_energy_ue_xy_plot;
widget *pdcch_iq_ue_xy_plot; widget *pdcch_iq_ue_xy_plot;
widget *dl_ul_harq_ue_label; widget *dl_ul_harq_ue_label;
widget *dl_mcs_xy_plot; widget *dl_mcs_xy_plot;
widget *ul_mcs_xy_plot; widget *ul_mcs_xy_plot;
widget *pusch_power_xy_plot;
widget *pucch_power_xy_plot;
widget *phy_meas_xy_plot;
logger *pdsch_iq_ue_logger; logger *pdsch_iq_ue_logger;
logger *dl_estimate_ue_logger; logger *dl_estimate_ue_logger;
logger *pdcch_energy_ue_threshold_logger;
logger *pdcch_energy_ue_energy_logger;
logger *pdcch_iq_ue_logger; logger *pdcch_iq_ue_logger;
logger *dl_dci_logger[8]; logger *dl_dci_logger[8];
logger *dl_ack_logger[8]; logger *dl_ack_logger[8];
...@@ -48,6 +50,13 @@ typedef struct { ...@@ -48,6 +50,13 @@ typedef struct {
logger *ul_nack_logger[8]; logger *ul_nack_logger[8];
logger *dl_mcs_logger; logger *dl_mcs_logger;
logger *ul_mcs_logger; logger *ul_mcs_logger;
logger *pusch_power_logger;
logger *pusch_ampl_logger;
logger *pucch_power_logger;
logger *pucch_ampl_logger;
logger *pdcch_energy_logger;
logger *pdsch_energy_logger;
logger *phy_meas_logger;
} ue_gui; } ue_gui;
typedef struct { typedef struct {
...@@ -137,6 +146,8 @@ static void set_current_ue(gui *g, ue_data *e, int ue) ...@@ -137,6 +146,8 @@ static void set_current_ue(gui *g, ue_data *e, int ue)
xy_plot_set_title(g, e->e->dl_estimate_ue_xy_plot, s); xy_plot_set_title(g, e->e->dl_estimate_ue_xy_plot, s);
sprintf(s, "PDCCH energy [UE %d]", ue); sprintf(s, "PDCCH energy [UE %d]", ue);
xy_plot_set_title(g, e->e->pdcch_energy_ue_xy_plot, s); xy_plot_set_title(g, e->e->pdcch_energy_ue_xy_plot, s);
sprintf(s, "PDSCH energy [UE %d]", ue);
xy_plot_set_title(g, e->e->pdsch_energy_ue_xy_plot, s);
sprintf(s, "PDCCH IQ [UE %d]", ue); sprintf(s, "PDCCH IQ [UE %d]", ue);
xy_plot_set_title(g, e->e->pdcch_iq_ue_xy_plot, s); xy_plot_set_title(g, e->e->pdcch_iq_ue_xy_plot, s);
sprintf(s, "DL/UL HARQ (x8) [UE %d]", ue); sprintf(s, "DL/UL HARQ (x8) [UE %d]", ue);
...@@ -145,7 +156,13 @@ static void set_current_ue(gui *g, ue_data *e, int ue) ...@@ -145,7 +156,13 @@ static void set_current_ue(gui *g, ue_data *e, int ue)
xy_plot_set_title(g, e->e->dl_mcs_xy_plot, s); xy_plot_set_title(g, e->e->dl_mcs_xy_plot, s);
sprintf(s, "UL MCS [UE %d]", ue); sprintf(s, "UL MCS [UE %d]", ue);
xy_plot_set_title(g, e->e->ul_mcs_xy_plot, s); xy_plot_set_title(g, e->e->ul_mcs_xy_plot, s);
sprintf(s, "PUSCH POWER [UE %d]", ue);
xy_plot_set_title(g, e->e->pusch_power_xy_plot, s);
sprintf(s, "PUCCH POWER [UE %d]", ue);
xy_plot_set_title(g, e->e->pucch_power_xy_plot, s);
sprintf(s, "PHY Measurements [UE %d]", ue);
xy_plot_set_title(g, e->e->phy_meas_xy_plot, s);
logger_set_filter(e->e->pdsch_iq_ue_logger, logger_set_filter(e->e->pdsch_iq_ue_logger,
filter_eq( filter_eq(
filter_evarg(e->database, "UE_PHY_PDSCH_IQ", "UE_ID"), filter_evarg(e->database, "UE_PHY_PDSCH_IQ", "UE_ID"),
...@@ -154,18 +171,26 @@ static void set_current_ue(gui *g, ue_data *e, int ue) ...@@ -154,18 +171,26 @@ static void set_current_ue(gui *g, ue_data *e, int ue)
filter_eq( filter_eq(
filter_evarg(e->database, "UE_PHY_DL_CHANNEL_ESTIMATE", "UE_ID"), filter_evarg(e->database, "UE_PHY_DL_CHANNEL_ESTIMATE", "UE_ID"),
filter_int(ue))); filter_int(ue)));
logger_set_filter(e->e->pdcch_energy_ue_threshold_logger, logger_set_filter(e->e->pdcch_energy_logger,
filter_eq( filter_eq(
filter_evarg(e->database, "UE_PHY_PDCCH_ENERGY", "UE_ID"), filter_evarg(e->database, "UE_PHY_PDCCH_ENERGY", "UE_ID"),
filter_int(ue))); filter_int(ue)));
logger_set_filter(e->e->pdsch_energy_logger,
filter_eq(
filter_evarg(e->database, "UE_PHY_PDSCH_ENERGY", "UE_ID"),
filter_int(ue)));
logger_set_filter(e->e->phy_meas_logger,
filter_eq(
filter_evarg(e->database, "UE_PHY_MEAS", "UE_ID"),
filter_int(ue)));
/*logger_set_filter(e->pucch1_energy_ue_energy_logger, /*logger_set_filter(e->pucch1_energy_ue_energy_logger,
filter_eq( filter_eq(
filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"), filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
filter_int(ue)));*/ filter_int(ue)));*/
logger_set_filter(e->e->pdcch_iq_ue_logger, /*logger_set_filter(e->e->pdcch_iq_ue_logger,
filter_eq( filter_eq(
filter_evarg(e->database, "UE_PHY_PDCCH_IQ", "UE_ID"), filter_evarg(e->database, "UE_PHY_PDCCH_IQ", "UE_ID"),
filter_int(ue))); filter_int(ue)));*/
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
logger_set_filter(e->e->dl_dci_logger[i], logger_set_filter(e->e->dl_dci_logger[i],
ticktime_filter(e->database, "UE_PHY_DLSCH_UE_DCI", i, ue)); ticktime_filter(e->database, "UE_PHY_DLSCH_UE_DCI", i, ue));
...@@ -191,6 +216,22 @@ static void set_current_ue(gui *g, ue_data *e, int ue) ...@@ -191,6 +216,22 @@ static void set_current_ue(gui *g, ue_data *e, int ue)
filter_eq( filter_eq(
filter_evarg(e->database, "UE_PHY_ULSCH_UE_DCI", "UE_id"), filter_evarg(e->database, "UE_PHY_ULSCH_UE_DCI", "UE_id"),
filter_int(ue))); filter_int(ue)));
logger_set_filter(e->e->pusch_power_logger,
filter_eq(
filter_evarg(e->database, "UE_PHY_PUSCH_TX_POWER", "UE_id"),
filter_int(ue)));
logger_set_filter(e->e->pusch_ampl_logger,
filter_eq(
filter_evarg(e->database, "UE_PHY_PUSCH_TX_POWER", "UE_id"),
filter_int(ue)));
logger_set_filter(e->e->pucch_power_logger,
filter_eq(
filter_evarg(e->database, "UE_PHY_PUCCH_TX_POWER", "UE_id"),
filter_int(ue)));
logger_set_filter(e->e->pucch_ampl_logger,
filter_eq(
filter_evarg(e->database, "UE_PHY_PUCCH_TX_POWER", "UE_id"),
filter_int(ue)));
} }
static void click(void *private, gui *g, static void click(void *private, gui *g,
...@@ -279,7 +320,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, ...@@ -279,7 +320,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
w = new_xy_plot(g, 55, 55, "", 50); w = new_xy_plot(g, 55, 55, "", 50);
e->pdsch_iq_ue_xy_plot = w; e->pdsch_iq_ue_xy_plot = w;
widget_add_child(g, line, w, -1); widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, -1000, 1000, -1000, 1000); xy_plot_set_range(g, w, -500, 500, -500, 500);
l = new_iqlog(h, database, "UE_PHY_PDSCH_IQ", "nb_rb", l = new_iqlog(h, database, "UE_PHY_PDSCH_IQ", "nb_rb",
"N_RB_UL", "symbols_per_tti", "pusch_comp"); "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); v = new_view_xy(100*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE);
...@@ -299,27 +340,97 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, ...@@ -299,27 +340,97 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
logger_add_view(l, v); logger_add_view(l, v);
e->dl_estimate_ue_logger = l; e->dl_estimate_ue_logger = l;
/* PHY Meas */
w = new_xy_plot(g, 128, 55, "", 50);
e->phy_meas_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -130, 35);
/*l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rssi", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
logger_add_view(l, v);
e->phy_meas_logger = l;*/
l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "rsrp", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
logger_add_view(l, v);
e->phy_meas_logger = l;
l = new_ticked_ttilog(h, database,"UE_PHY_DL_TICK", "frame", "subframe","UE_PHY_MEAS", "snr", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c720c"));
logger_add_view(l, v);
e->phy_meas_logger = l;
/* UE x PDSCH energy */
w = new_xy_plot(g, 128, 55, "", 50);
e->pdsch_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,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level00", 1);
v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
logger_add_view(l, v);
e->pdsch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level01", 1);
v = new_view_tti(10, g, w, new_color(g, "#00ff00"));
logger_add_view(l, v);
e->pdsch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level10", 1);
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"));
logger_add_view(l, v);
e->pdsch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level11", 1);
v = new_view_tti(10, g, w, new_color(g, "#0000ff"));
logger_add_view(l, v);
e->pdsch_energy_logger = l;
/* UE x PDCCH energy */ /* UE x PDCCH energy */
w = new_xy_plot(g, 128, 55, "", 50); w = new_xy_plot(g, 128, 55, "", 50);
e->pdcch_energy_ue_xy_plot = w; e->pdcch_energy_ue_xy_plot = w;
widget_add_child(g, line, w, -1); widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -10, 80); xy_plot_set_range(g, w, 0, 1024*10, -10, 80);
l = new_ttilog(h, database, l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "threshold", 0); "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level00", 1);
v = new_view_tti(10, g, w, new_color(g, "#ff0000")); v = new_view_tti(10, g, w, new_color(g, "#ff0000"));
logger_add_view(l, v); logger_add_view(l, v);
e->pdcch_energy_ue_threshold_logger = l; e->pdcch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level01", 1);
v = new_view_tti(10, g, w, new_color(g, "#00ff00"));
logger_add_view(l, v);
e->pdcch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level10", 1);
v = new_view_tti(10, g, w, new_color(g, "#0f0f0f"));
logger_add_view(l, v);
e->pdcch_energy_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level11", 1);
v = new_view_tti(10, g, w, new_color(g, "#0000ff"));
logger_add_view(l, v);
e->pdcch_energy_logger = l;
/* UE x PDCCH IQ data */
w = new_xy_plot(g, 55, 55, "", 50);
e->pdcch_iq_ue_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, -100, 100, -100, 100);
l = new_iqlog(h, database, "UE_PHY_PDCCH_IQ", "nb_rb",
"NB_RB_DL", "symbols_per_tti", "rxdataF_comp");
v = new_view_xy(100*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE);
logger_add_view(l, v);
e->pdcch_iq_ue_logger = l;
/* UE x PDCCH IQ data */ /* UE x PDCCH IQ data */
w = new_xy_plot(g, 55, 55, "", 50); /*w = new_xy_plot(g, 55, 55, "", 50);
e->pdcch_iq_ue_xy_plot = w; e->pdcch_iq_ue_xy_plot = w;
widget_add_child(g, line, w, -1); widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, -2000, 2000, -2000, 2000); xy_plot_set_range(g, w, -2000, 2000, -2000, 2000);
l = new_iqdotlog(h, database, "UE_PHY_PDCCH_IQ", "I", "Q"); l = new_iqdotlog(h, database, "UE_PHY_PDCCH_IQ", "I", "Q");
v = new_view_xy(500, 10, g, w, new_color(g,"#000"), XY_LOOP_MODE); v = new_view_xy(500, 10, g, w, new_color(g,"#000"), XY_LOOP_MODE);
logger_add_view(l, v); logger_add_view(l, v);
e->pdcch_iq_ue_logger = l; e->pdcch_iq_ue_logger = l;*/
/* UE x DL mcs */ /* UE x DL mcs */
line = new_container(g, HORIZONTAL); line = new_container(g, HORIZONTAL);
widget_add_child(g, top_container, line, -1); widget_add_child(g, top_container, line, -1);
...@@ -338,12 +449,49 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, ...@@ -338,12 +449,49 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
xy_plot_set_range(g, w, 0, 1024*10, -2, 30); xy_plot_set_range(g, w, 0, 1024*10, -2, 30);
e->ul_mcs_xy_plot = w; e->ul_mcs_xy_plot = w;
widget_add_child(g, line, w, -1); widget_add_child(g, line, w, -1);
l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", l = new_ticked_ttilog(h, database, "UE_PHY_UL_TICK", "frame", "subframe",
"UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1); "UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
logger_add_view(l, v); logger_add_view(l, v);
e->ul_mcs_logger = l; e->ul_mcs_logger = l;
/* UE x PUSCH TX Power */
// line = new_container(g, HORIZONTAL);
// widget_add_child(g, top_container, line, -1);
w = new_xy_plot(g, 128, 55, "", 20);
e->pusch_power_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
l = new_ttilog(h, database,
"UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "p0_pusch", 0);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
logger_add_view(l, v);
e->pusch_power_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "ampl", 1);
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
logger_add_view(l, v);
e->pusch_ampl_logger = l;
/* UE x PUCCH TX Power */
// line = new_container(g, HORIZONTAL);
// widget_add_child(g, top_container, line, -1);
w = new_xy_plot(g, 128, 55, "", 20);
e->pucch_power_xy_plot = w;
widget_add_child(g, line, w, -1);
xy_plot_set_range(g, w, 0, 1024*10, -30, 50);
l = new_ttilog(h, database,
"UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "p0_pucch", 0);
v = new_view_tti(10, g, w, new_color(g, "#0c0c72"));
logger_add_view(l, v);
e->pucch_power_logger = l;
l = new_ttilog(h, database,
"UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "ampl", 1);
v = new_view_tti(10, g, w, new_color(g, "#720c0c"));
logger_add_view(l, v);
e->pucch_ampl_logger = l;
/* downlink/uplink UE DCIs */ /* downlink/uplink UE DCIs */
widget_add_child(g, top_container, widget_add_child(g, top_container,
new_label(g,"DL/UL TICK/DCI/ACK/NACK [all UEs]"), -1); new_label(g,"DL/UL TICK/DCI/ACK/NACK [all UEs]"), -1);
...@@ -407,9 +555,9 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, ...@@ -407,9 +555,9 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
new_color(g, i==0 || i==9 ? "#ddd" : (i%9)&1 ? "#e6e6e6" : "#eee")); new_color(g, i==0 || i==9 ? "#ddd" : (i%9)&1 ? "#e6e6e6" : "#eee"));
timeview = new_view_ticktime(10, g, timeline_plot); timeview = new_view_ticktime(10, g, timeline_plot);
ticktime_set_tick(timeview, ticktime_set_tick(timeview,
new_ticklog(h, database, "ENB_MASTER_TICK", "frame", "subframe")); new_ticklog(h, database, "UE_MASTER_TICK", "frame", "subframe"));
/* tick */ /* tick */
timelog = new_ticklog(h, database, "ENB_MASTER_TICK", "frame", "subframe"); timelog = new_ticklog(h, database, "UE_MASTER_TICK", "frame", "subframe");
/* tick on DL view */ /* tick on DL view */
subview = new_subview_ticktime(timeview, 0, new_color(g,"#bbb"), 3600*1000); subview = new_subview_ticktime(timeview, 0, new_color(g,"#bbb"), 3600*1000);
logger_add_view(timelog, subview); logger_add_view(timelog, subview);
...@@ -453,14 +601,14 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, ...@@ -453,14 +601,14 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database,
logger_add_view(timelog, subview); logger_add_view(timelog, subview);
e->ul_dci_logger[i] = timelog; e->ul_dci_logger[i] = timelog;
/* retransmission */ /* retransmission */
/*
timelog = new_ticklog(h, database, timelog = new_ticklog(h, database,
"ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", "frame", "subframe"); "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", "frame", "subframe");
subview = new_subview_ticktime(timeview, i+9+1, subview = new_subview_ticktime(timeview, i+9+1,
new_color(g,"#99f"), 3600*1000); new_color(g,"#99f"), 3600*1000);
logger_add_view(timelog, subview); logger_add_view(timelog, subview);
e->ul_dci_retransmission_logger[i] = timelog; e->ul_dci_retransmission_logger[i] = timelog;
*/
} }
/* UL ACK */ /* UL ACK */
...@@ -659,6 +807,7 @@ int main(int n, char **v) ...@@ -659,6 +807,7 @@ int main(int n, char **v)
free(desc); free(desc);
} }
on_off(database, "UE_MASTER_TICK", is_on, 1);
on_off(database, "UE_PHY_UL_TICK", is_on, 1); on_off(database, "UE_PHY_UL_TICK", is_on, 1);
on_off(database, "UE_PHY_DL_TICK", is_on, 1); on_off(database, "UE_PHY_DL_TICK", is_on, 1);
on_off(database, "UE_PHY_DLSCH_UE_DCI", is_on, 1); on_off(database, "UE_PHY_DLSCH_UE_DCI", is_on, 1);
...@@ -675,12 +824,11 @@ int main(int n, char **v) ...@@ -675,12 +824,11 @@ int main(int n, char **v)
on_off(database, "UE_PHY_PDSCH_ENERGY", is_on, 1); on_off(database, "UE_PHY_PDSCH_ENERGY", is_on, 1);
on_off(database, "UE_PHY_PUSCH_TX_POWER", is_on, 1); on_off(database, "UE_PHY_PUSCH_TX_POWER", is_on, 1);
on_off(database, "UE_PHY_PUCCH_TX_POWER", is_on, 1); on_off(database, "UE_PHY_PUCCH_TX_POWER", is_on, 1);
on_off(database, "UE_PHY_MEAS", is_on, 1);
/*
on_off(database, "LEGACY_GROUP_INFO", is_on, 1); on_off(database, "LEGACY_GROUP_INFO", is_on, 1);
on_off(database, "LEGACY_GROUP_ERROR", is_on, 1); on_off(database, "LEGACY_GROUP_ERROR", is_on, 1);
on_off(database, "LEGACY_GROUP_WARNING", is_on, 1); on_off(database, "LEGACY_GROUP_WARNING", is_on, 1);
*/
view_add_log(eg.phyview, "UE_PHY_UL_TICK", h, database, is_on); view_add_log(eg.phyview, "UE_PHY_UL_TICK", h, database, is_on);
view_add_log(eg.phyview, "UE_PHY_DL_TICK", h, database, is_on); view_add_log(eg.phyview, "UE_PHY_DL_TICK", h, database, is_on);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment