Commit b2b8d297 authored by Melissa Elkadi's avatar Melissa Elkadi

Memory bug fixes

Several places where memory ownership was changed
and the original owner was not set to NULL. Also,
the transaction_identifier is now based on the
received dl_dcch_msg in the LTE UE. Still need to
fix the t_id for the NR UE. Also added comments for
RACH procedure in NR UE.
parent da2873d6
...@@ -138,6 +138,75 @@ void init_nrUE_standalone_thread(int ue_idx) ...@@ -138,6 +138,75 @@ void init_nrUE_standalone_thread(int ue_idx)
pthread_setname_np(thread, "oai:nrue-stand"); pthread_setname_np(thread, "oai:nrue-stand");
} }
#if 0
static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
{
int current_sfn_slot;
sem_t sfn_slot_semaphore;
int last_sfn_slot = -1;
while (!oai_exit)
{
if (sem_wait(&sfn_slot_semaphore) != 0)
{
LOG_E(NR_MAC, "sem_wait() error\n");
abort();
}
int sfn_slot = current_sfn_slot;
if (sfn_slot == last_sfn_slot)
{
LOG_W(NR_MAC, "repeated sfn_sf = %d.%d\n",
sfn_slot >> 4, sfn_slot & 15);
continue;
}
last_sfn_slot = sfn_slot;
struct rx_tx_thread_data *rtd = arg;
if (rtd == NULL) {
LOG_E(MAC, "[SCHED][UE] rx_tx_thread_data *rtd: NULL pointer\n");
exit_fun("nothing to add");
}
UE_nr_rxtx_proc_t *proc = rtd->proc;
PHY_VARS_NR_UE *UE = NULL;
proc = &PHY_vars_UE_g[0][0]->proc;
int frame_tx = proc->frame_tx;
int nr_slot_tx = proc->nr_slot_tx;
uint8_t mod_id = UE->Mod_id;
NR_PRACH_RESOURCES_t *prach_resources = UE->prach_resources[0];
AssertFatal(prach_resources != NULL, "UE->prach_resources[%u] == NULL\n", 0);
uint8_t nr_prach = 0;
if (UE->mac_enabled == 0)
{
prach_resources->ra_TDD_map_index = 0;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
prach_resources->ra_RNTI = 0x1234;
nr_prach = 1;
prach_resources->init_msg1 = 1;
}
else
{
LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources\n", __FUNCTION__, frame_tx, nr_slot_tx);
nr_prach = nr_ue_get_rach(prach_resources, &UE->prach_vars[0]->prach_pdu, mod_id, UE->CC_id, frame_tx, 0, nr_slot_tx);
if (nr_prach == 1)
{
nr_Msg1_transmitted(mod_id, UE->CC_id, frame_tx, 0); //Once rach is = 1, then call this
}
else if (nr_prach == 2)
{
LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id);
UE->UE_mode[0] = PUSCH;
}
else if(nr_prach == 3)
{
LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id);
UE->UE_mode[0] = PRACH;
}
}
}
}
#endif
/*! /*!
* It performs band scanning and synchonization. * It performs band scanning and synchonization.
......
...@@ -853,6 +853,7 @@ rrc_ue_process_measConfig( ...@@ -853,6 +853,7 @@ rrc_ue_process_measConfig(
LOG_D(RRC, "Adding measurement object [%d][%ld]\n", eNB_index, ind); LOG_D(RRC, "Adding measurement object [%d][%ld]\n", eNB_index, ind);
ue->MeasObj[eNB_index][ind-1]=measObj; ue->MeasObj[eNB_index][ind-1]=measObj;
} }
measConfig->measObjectToAddModList->list.array[i] = NULL;
} }
LOG_I(RRC,"call rrc_mac_config_req \n"); LOG_I(RRC,"call rrc_mac_config_req \n");
...@@ -909,6 +910,7 @@ rrc_ue_process_measConfig( ...@@ -909,6 +910,7 @@ rrc_ue_process_measConfig(
LOG_D(RRC,"Adding ReportConfig [%d][%ld]\n", eNB_index, ind-1); LOG_D(RRC,"Adding ReportConfig [%d][%ld]\n", eNB_index, ind-1);
ue->ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; ue->ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
} }
measConfig->reportConfigToAddModList->list.array[i] = NULL;
} }
} }
...@@ -922,6 +924,7 @@ rrc_ue_process_measConfig( ...@@ -922,6 +924,7 @@ rrc_ue_process_measConfig(
LOG_D(RRC,"Adding Quantity configuration\n"); LOG_D(RRC,"Adding Quantity configuration\n");
ue->QuantityConfig[eNB_index] = measConfig->quantityConfig; ue->QuantityConfig[eNB_index] = measConfig->quantityConfig;
} }
measConfig->quantityConfig = NULL;
} }
if (measConfig->measIdToRemoveList != NULL) { if (measConfig->measIdToRemoveList != NULL) {
...@@ -946,6 +949,7 @@ rrc_ue_process_measConfig( ...@@ -946,6 +949,7 @@ rrc_ue_process_measConfig(
LOG_I(RRC,"Adding Measurement ID [%d][%ld]\n", eNB_index, ind-1); LOG_I(RRC,"Adding Measurement ID [%d][%ld]\n", eNB_index, ind-1);
ue->MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; ue->MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
} }
measConfig->measIdToAddModList->list.array[i] = NULL;
} }
} }
...@@ -957,6 +961,7 @@ rrc_ue_process_measConfig( ...@@ -957,6 +961,7 @@ rrc_ue_process_measConfig(
} else { } else {
ue->measGapConfig[eNB_index] = measConfig->measGapConfig; ue->measGapConfig[eNB_index] = measConfig->measGapConfig;
} }
measConfig->measGapConfig = NULL;
} }
if (measConfig->quantityConfig != NULL) { if (measConfig->quantityConfig != NULL) {
...@@ -969,6 +974,7 @@ rrc_ue_process_measConfig( ...@@ -969,6 +974,7 @@ rrc_ue_process_measConfig(
LOG_I(RRC,"Adding Quantity configuration\n"); LOG_I(RRC,"Adding Quantity configuration\n");
ue->QuantityConfig[eNB_index] = measConfig->quantityConfig; ue->QuantityConfig[eNB_index] = measConfig->quantityConfig;
} }
measConfig->quantityConfig = NULL;
ue->filter_coeff_rsrp = 1./pow(2, ue->filter_coeff_rsrp = 1./pow(2,
(*ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4); (*ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4);
...@@ -985,6 +991,7 @@ rrc_ue_process_measConfig( ...@@ -985,6 +991,7 @@ rrc_ue_process_measConfig(
if (measConfig->s_Measure != NULL) { if (measConfig->s_Measure != NULL) {
ue->s_measure = *measConfig->s_Measure; ue->s_measure = *measConfig->s_Measure;
} }
measConfig->s_Measure = NULL;
if (measConfig->speedStatePars != NULL) { if (measConfig->speedStatePars != NULL) {
if (ue->speedStatePars) { if (ue->speedStatePars) {
...@@ -992,6 +999,7 @@ rrc_ue_process_measConfig( ...@@ -992,6 +999,7 @@ rrc_ue_process_measConfig(
} else { } else {
ue->speedStatePars = measConfig->speedStatePars; ue->speedStatePars = measConfig->speedStatePars;
} }
measConfig->speedStatePars = NULL;
LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n", LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n",
ctxt_pP->module_id,ue->Info[0].UE_index); ctxt_pP->module_id,ue->Info[0].UE_index);
...@@ -1205,6 +1213,7 @@ rrc_ue_process_radioResourceConfigDedicated( ...@@ -1205,6 +1213,7 @@ rrc_ue_process_radioResourceConfigDedicated(
LOG_I(RRC,"Init physicalConfigDedicated UE_rrc_inst to radioResourceConfigDedicated->physicalConfigDedicated\n"); LOG_I(RRC,"Init physicalConfigDedicated UE_rrc_inst to radioResourceConfigDedicated->physicalConfigDedicated\n");
UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index] = radioResourceConfigDedicated->physicalConfigDedicated; UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index] = radioResourceConfigDedicated->physicalConfigDedicated;
} }
radioResourceConfigDedicated->physicalConfigDedicated = NULL;
} }
// Apply macMainConfig if present // Apply macMainConfig if present
...@@ -1227,6 +1236,7 @@ rrc_ue_process_radioResourceConfigDedicated( ...@@ -1227,6 +1236,7 @@ rrc_ue_process_radioResourceConfigDedicated(
} else { } else {
UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index] = radioResourceConfigDedicated->sps_Config; UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index] = radioResourceConfigDedicated->sps_Config;
} }
radioResourceConfigDedicated->sps_Config = NULL;
} }
// Establish SRBs if present // Establish SRBs if present
...@@ -1275,7 +1285,7 @@ rrc_ue_process_radioResourceConfigDedicated( ...@@ -1275,7 +1285,7 @@ rrc_ue_process_radioResourceConfigDedicated(
} else { } else {
UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt];
rrc_ue_establish_srb1(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); rrc_ue_establish_srb1(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]);
radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt] = NULL;
if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig) { if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig) {
if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
SRB1_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->choice.explicitValue; SRB1_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->choice.explicitValue;
...@@ -1323,7 +1333,7 @@ rrc_ue_process_radioResourceConfigDedicated( ...@@ -1323,7 +1333,7 @@ rrc_ue_process_radioResourceConfigDedicated(
} else { } else {
UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt];
rrc_ue_establish_srb2(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); rrc_ue_establish_srb2(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]);
radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt] = NULL;
if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig) { if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig) {
if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
LOG_I(RRC,"Applying Explicit SRB2 logicalChannelConfig\n"); LOG_I(RRC,"Applying Explicit SRB2 logicalChannelConfig\n");
...@@ -1432,6 +1442,7 @@ rrc_ue_process_radioResourceConfigDedicated( ...@@ -1432,6 +1442,7 @@ rrc_ue_process_radioResourceConfigDedicated(
radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity, radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity,
eNB_index, eNB_index,
ctxt_pP->module_id); ctxt_pP->module_id);
radioResourceConfigDedicated->drb_ToAddModList->list.array[i] = NULL;
rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index,
(LTE_RadioResourceConfigCommonSIB_t *)NULL, (LTE_RadioResourceConfigCommonSIB_t *)NULL,
UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index],
...@@ -1981,6 +1992,7 @@ rrc_ue_process_rrcConnectionReconfiguration( ...@@ -1981,6 +1992,7 @@ rrc_ue_process_rrcConnectionReconfiguration(
rrc_ue_process_measConfig(ctxt_pP, rrc_ue_process_measConfig(ctxt_pP,
eNB_index, eNB_index,
r_r8->measConfig); r_r8->measConfig);
r_r8->measConfig = NULL;
} }
if (r_r8->radioResourceConfigDedicated) { if (r_r8->radioResourceConfigDedicated) {
...@@ -1988,6 +2000,7 @@ rrc_ue_process_rrcConnectionReconfiguration( ...@@ -1988,6 +2000,7 @@ rrc_ue_process_rrcConnectionReconfiguration(
rrc_ue_process_radioResourceConfigDedicated(ctxt_pP, rrc_ue_process_radioResourceConfigDedicated(ctxt_pP,
eNB_index, eNB_index,
r_r8->radioResourceConfigDedicated); r_r8->radioResourceConfigDedicated);
r_r8->radioResourceConfigDedicated = NULL;
} }
//TTN for D2D //TTN for D2D
...@@ -2437,6 +2450,12 @@ rrc_ue_decode_dcch( ...@@ -2437,6 +2450,12 @@ rrc_ue_decode_dcch(
send_ue_information ++; send_ue_information ++;
} }
UE_RRC_INFO *info = &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP];
if (info->dl_dcch_msg != NULL) {
SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, info->dl_dcch_msg, ASFM_FREE_EVERYTHING);
}
info->dl_dcch_msg = dl_dcch_msg;
dl_dcch_msg = NULL;
break; break;
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease:
...@@ -6559,6 +6578,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) ...@@ -6559,6 +6578,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len)
bool received_nr_msg = true; bool received_nr_msg = true;
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
module_id_t module_id = 0; module_id_t module_id = 0;
eNB_index_t eNB_index = 0;
switch (msg_type) switch (msg_type)
{ {
...@@ -6573,7 +6593,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) ...@@ -6573,7 +6593,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len)
AssertFatal(msg_len <= sizeof(nrue_cap_buf->mesg), "msg_len = %d\n", msg_len); AssertFatal(msg_len <= sizeof(nrue_cap_buf->mesg), "msg_len = %d\n", msg_len);
memcpy(nrue_cap_buf->mesg, msg_buffer, msg_len); memcpy(nrue_cap_buf->mesg, msg_buffer, msg_len);
nrue_cap_buf->mesg_len = msg_len; nrue_cap_buf->mesg_len = msg_len;
UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[0]; UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[eNB_index];
nrue_cap_buf->dl_dcch_msg = info->dl_dcch_msg; nrue_cap_buf->dl_dcch_msg = info->dl_dcch_msg;
info->dl_dcch_msg = NULL; info->dl_dcch_msg = NULL;
message_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_NRUE_CAP_INFO_IND); message_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_NRUE_CAP_INFO_IND);
...@@ -6581,7 +6601,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) ...@@ -6581,7 +6601,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len)
RRC_NRUE_CAP_INFO_IND (message_p).sdu_size = sizeof(*nrue_cap_buf); RRC_NRUE_CAP_INFO_IND (message_p).sdu_size = sizeof(*nrue_cap_buf);
RRC_NRUE_CAP_INFO_IND (message_p).module_id = module_id; RRC_NRUE_CAP_INFO_IND (message_p).module_id = module_id;
RRC_NRUE_CAP_INFO_IND (message_p).rnti = info->rnti; RRC_NRUE_CAP_INFO_IND (message_p).rnti = info->rnti;
RRC_NRUE_CAP_INFO_IND (message_p).eNB_index = 0; RRC_NRUE_CAP_INFO_IND (message_p).eNB_index = eNB_index;
itti_send_msg_to_task (TASK_RRC_UE, 0, message_p); itti_send_msg_to_task (TASK_RRC_UE, 0, message_p);
LOG_I(RRC, "Sent itti RRC_NRUE_CAP_INFO_IND\n"); LOG_I(RRC, "Sent itti RRC_NRUE_CAP_INFO_IND\n");
break; break;
...@@ -6604,7 +6624,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) ...@@ -6604,7 +6624,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len)
rrc_dcch_data_copy_t *dl_dcch_buffer = itti_malloc (TASK_RRC_NSA_UE, rrc_dcch_data_copy_t *dl_dcch_buffer = itti_malloc (TASK_RRC_NSA_UE,
TASK_RRC_UE, TASK_RRC_UE,
sizeof(rrc_dcch_data_copy_t)); sizeof(rrc_dcch_data_copy_t));
UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[0]; UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[eNB_index];
dl_dcch_buffer->dl_dcch_msg = info->dl_dcch_msg; dl_dcch_buffer->dl_dcch_msg = info->dl_dcch_msg;
info->dl_dcch_msg = NULL; info->dl_dcch_msg = NULL;
message_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_DCCH_DATA_COPY_IND); message_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_DCCH_DATA_COPY_IND);
...@@ -6612,7 +6632,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) ...@@ -6612,7 +6632,7 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len)
RRC_DCCH_DATA_COPY_IND (message_p).sdu_size = sizeof(rrc_dcch_data_copy_t); RRC_DCCH_DATA_COPY_IND (message_p).sdu_size = sizeof(rrc_dcch_data_copy_t);
RRC_DCCH_DATA_COPY_IND (message_p).module_id = module_id; RRC_DCCH_DATA_COPY_IND (message_p).module_id = module_id;
RRC_DCCH_DATA_COPY_IND (message_p).rnti = info->rnti; RRC_DCCH_DATA_COPY_IND (message_p).rnti = info->rnti;
RRC_DCCH_DATA_COPY_IND (message_p).eNB_index = 0; RRC_DCCH_DATA_COPY_IND (message_p).eNB_index = eNB_index;
itti_send_msg_to_task (TASK_RRC_UE, 0, message_p); itti_send_msg_to_task (TASK_RRC_UE, 0, message_p);
LOG_I(RRC, "Sent itti RRC_DCCH_DATA_COPY_IND\n"); LOG_I(RRC, "Sent itti RRC_DCCH_DATA_COPY_IND\n");
break; break;
...@@ -6669,17 +6689,14 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) ...@@ -6669,17 +6689,14 @@ void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len)
OCTET_STRING_fromBuf(&rrcConfigurationComplete, OCTET_STRING_fromBuf(&rrcConfigurationComplete,
(const char *)msg_buffer, (const char *)msg_buffer,
msg_len); msg_len);
#if 0 //Melissa, this is a hack. We need the transaction_id from latest dl_dcch_msg the LTE UE received. (Ln 6658) UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[eNB_index];
LTE_RRCConnectionReconfiguration_t *rrc_saved = &UE_rrc_inst[ctxt.module_id].Info[0].dl_dcch_msg->message. uint8_t t_id = info->dl_dcch_msg->message.choice.c1.choice.
choice.c1.choice.rrcConnectionReconfiguration; rrcConnectionReconfiguration.rrc_TransactionIdentifier;
uint8_t t_id = rrc_saved->rrc_TransactionIdentifier;
rrc_saved = NULL;
#endif
UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[0];
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id,
ENB_FLAG_NO, info->rnti, ENB_FLAG_NO, info->rnti,
0, 0, 0); 0, 0, eNB_index);
rrc_ue_generate_RRCConnectionReconfigurationComplete(&ctxt, ctxt.eNB_index, 0, &rrcConfigurationComplete); LOG_I(RRC, "Melissa this is the t_id %d\n", t_id);
rrc_ue_generate_RRCConnectionReconfigurationComplete(&ctxt, ctxt.eNB_index, t_id, &rrcConfigurationComplete);
break; break;
} }
default: default:
......
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