Commit 6f5205ec authored by Ejaz Ahmed's avatar Ejaz Ahmed

Commented out Rx to Tx notification mechanism; added configurations

parent f5250c1e
......@@ -624,10 +624,9 @@ void processSlotTX(void *arg) {
if (proc->tx_slot_type == NR_SIDELINK_SLOT && UE->sl_mode == 2) {
// wait for rx slots to send indication (if any) that SLSCH decoding is finished
// for(int i=0; i < rxtxD->tx_wait_for_slsch; i++) {
// LOG_I(NR_PHY, "EJJ: tx slot: %d, rxtxD->tx_wait_for_slsch: %d pullNotifiedFIFO\n", proc->nr_slot_tx, rxtxD->tx_wait_for_slsch);
// LOG_D(NR_PHY, "tx frame:slot %d:%d, rxtxD->tx_wait_for_slsch: %d pullNotifiedFIFO\n", proc->frame_tx, proc->nr_slot_tx, rxtxD->tx_wait_for_slsch);
// notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo[proc->nr_slot_tx]);
// delNotifiedFIFO_elt(res);
// }
......@@ -647,8 +646,7 @@ void processSlotTX(void *arg) {
sl_indication.phy_data = &phy_data;
sl_indication.slot_type = SIDELINK_SLOT_TYPE_TX;
LOG_D(NR_PHY,"Sending SL indication RX %d.%d TX %d.%d\n",proc->frame_rx,proc->nr_slot_rx,proc->frame_tx,proc->nr_slot_tx);
LOG_D(NR_PHY, "calling sl_indication: RX %d.%d TX %d.%d %s\n",proc->frame_rx,proc->nr_slot_rx,proc->frame_tx,proc->nr_slot_tx, __FUNCTION__);
LOG_D(NR_PHY,"Sending SL indication RX %d.%d TX %d.%d %s\n",proc->frame_rx,proc->nr_slot_rx,proc->frame_tx,proc->nr_slot_tx, __FUNCTION__);
UE->if_inst->sl_indication(&sl_indication);
stop_meas(&UE->ue_ul_indication_stats);
......@@ -938,7 +936,7 @@ void *UE_thread(void *arg)
int num_ind_fifo = nb_slot_frame;
for(int i=0; i < num_ind_fifo; i++) {
UE->tx_wait_for_dlsch[num_ind_fifo] = 0;
//UE->tx_wait_for_slsch[num_ind_fifo] = 0;
// UE->tx_wait_for_slsch[num_ind_fifo] = 0;
UE->tx_resume_ind_fifo[i] = malloc(sizeof(*UE->tx_resume_ind_fifo[i]));
initNotifiedFIFO(UE->tx_resume_ind_fifo[i]);
}
......
......@@ -654,7 +654,7 @@ typedef struct PHY_VARS_NR_UE_s {
notifiedFIFO_t phy_config_ind;
notifiedFIFO_t *tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
//int tx_wait_for_slsch[NR_MAX_SLOTS_PER_FRAME];
// int tx_wait_for_slsch[NR_MAX_SLOTS_PER_FRAME];
//Sidelink parameters
sl_nr_sidelink_mode_t sl_mode;
......@@ -712,7 +712,7 @@ typedef struct nr_phy_data_s {
sl_nr_rx_config_pscch_pdu_t nr_sl_pscch_pdu;
sl_nr_rx_config_pssch_sci_pdu_t nr_sl_pssch_sci_pdu;
sl_nr_rx_config_pssch_pdu_t nr_sl_pssch_pdu;
//sl_nr_rx_config_psfch_pdu_t nr_sl_psfch_pdu;
sl_nr_rx_config_psfch_pdu_t nr_sl_psfch_pdu;
} nr_phy_data_t;
/* this structure is used to pass both UE phy vars and
* proc to the function UE_thread_rxn_txnp4
......@@ -724,7 +724,7 @@ typedef struct nr_rxtx_thread_data_s {
notifiedFIFO_t txFifo;
nr_phy_data_t phy_data;
int tx_wait_for_dlsch;
//int tx_wait_for_slsch;
// int tx_wait_for_slsch;
} nr_rxtx_thread_data_t;
typedef struct LDPCDecode_ue_s {
......
......@@ -270,7 +270,7 @@
/* FFS_NR_TODO it defines ue capability which is the number of slots */
/* - between reception of pdsch and tarnsmission of its acknowlegment */
/* - between reception of un uplink grant and its related transmission */
#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (4)
#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (3)
#ifndef NO_RAT_NR
#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */
......
......@@ -761,8 +761,8 @@ int8_t sl_handle_scheduled_response(nr_scheduled_response_t *scheduled_response)
break;
case SL_NR_CONFIG_TYPE_TX_PSFCH:
LOG_I(NR_PHY, "Recvd CONFIG_TYPE_TX_PSFCH\n");
//phy_data_tx->sl_tx_action = SL_NR_CONFIG_TYPE_TX_PSFCH;
//phy_data_tx->nr_sl_psfch_pdu = sl_tx_config->tx_config_list[0].tx_psfch_config_pdu;
phy_data_tx->sl_tx_action = SL_NR_CONFIG_TYPE_TX_PSFCH;
phy_data_tx->nr_sl_psfch_pdu = sl_tx_config->tx_config_list[0].tx_psfch_config_pdu;
break;
default:
AssertFatal(0,"Incorrect sl_tx config req pdutype \n");
......
......@@ -150,7 +150,7 @@ int sl_nr_ue_slot_select(sl_nr_phy_config_request_t *cfg,
ul_sym++;
}
}
LOG_D(NR_MAC, "frame:slot %d:%d num of ul_sym %d, NR_NUMBER_OF_SYMBOLS_PER_SLOT %d\n", nr_frame, nr_slot, ul_sym, NR_NUMBER_OF_SYMBOLS_PER_SLOT);
if(ul_sym == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
slot_type = NR_SIDELINK_SLOT;
} else if (ul_sym){
......
......@@ -658,6 +658,7 @@ void send_slot_ind(notifiedFIFO_t *nf, int slot) {
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL);
int *msgData = (int *) NotifiedFifoData(newElt);
*msgData = slot;
LOG_I(PHY, "Pushed slot %d in notified fifo\n", slot);
pushNotifiedFIFO(nf, newElt);
}
}
......
......@@ -228,8 +228,8 @@ int nr_slsch_procedures(PHY_VARS_NR_UE *ue, int frame_rx, int slot_rx, int SLSCH
// feedback_slot %= NR_MAX_SLOTS_PER_FRAME;
// phy_data->sl_active = true;
// send_slot_ind(ue->tx_resume_ind_fifo[feedback_slot], slot_rx);
// LOG_I(NR_PHY, "%s EJJ: Sent slot indication: slot_rx %d feedback_slot %d, sl_active %d\n", __FUNCTION__, slot_rx, feedback_slot, phy_data->sl_active);
// LOG_I(NR_MAC, "harq pid: %d psfch_period %d, slot_rx %d, delta_slots %d, feedback_slot %d, time_gap %d\n", harq_pid, psfch_period, slot_rx, delta_slots, feedback_slot, psfch_min_time_gap);
// LOG_D(NR_PHY, "%s Sent slot indication: slot_rx %d feedback_slot %d, sl_active %d\n", __FUNCTION__, slot_rx, feedback_slot, phy_data->sl_active);
// LOG_I(NR_MAC, "harq pid: %d Sent slot indication psfch_period %d, slot_rx %d, delta_slots %d, feedback_slot %d, time_gap %d\n", harq_pid, psfch_period, slot_rx, delta_slots, feedback_slot, psfch_min_time_gap);
return nbDecode;
}
......@@ -300,8 +300,9 @@ void nr_postDecode_slsch(PHY_VARS_NR_UE *UE, notifiedFIFO_elt_t *req,UE_nr_rxtx_
// dumpsig=1;
}
slsch->last_iteration_cnt = rdata->decodeIterations;
// sl_rx_indication.sfn = proc->frame_rx;
// sl_rx_indication.slot = proc->nr_slot_rx;
// FIXME: There may be need to add condition for PSFCH
sl_rx_indication.sfn = proc->frame_rx;
sl_rx_indication.slot = proc->nr_slot_rx;
nr_fill_sl_rx_indication(&sl_rx_indication,SL_NR_RX_PDU_TYPE_SLSCH,UE,1,proc,(void*)&slsch_status,0);
nr_fill_sl_indication(&sl_indication,&sl_rx_indication,NULL,proc,UE,phy_data);
LOG_D(NR_PHY, "calling sl_indication: RX %d.%d TX %d.%d %s\n",proc->frame_rx,proc->nr_slot_rx,proc->frame_tx,proc->nr_slot_tx, __FUNCTION__);
......
......@@ -64,13 +64,13 @@ bool nr_schedule_slsch(NR_UE_MAC_INST_t *mac, int frameP,int slotP, nr_sci_pdu_t
sci_pdu->beta_offset_indicator = 0;
// Fill SCI2A
sci2_pdu->harq_pid = 0; // slotP FIXIT - The value should only be 0-15 which can be in 4-bits
sci2_pdu->harq_pid = slotP; // slotP FIXIT - The value should only be 0-15 which can be in 4-bits
sci2_pdu->ndi = (1-sci2_pdu->ndi)&1;
sci2_pdu->rv_index=0;
sci2_pdu->source_id=0x12;
sci2_pdu->dest_id=0xabcd;
sci2_pdu->harq_feedback=1;
sci2_pdu->cast_type=0;
sci2_pdu->cast_type=2;
if (format2==NR_SL_SCI_FORMAT_2C || format2==NR_SL_SCI_FORMAT_2A)
sci2_pdu->csi_req=1;
if (format2==NR_SL_SCI_FORMAT_2B)
......
......@@ -645,7 +645,7 @@ void nr_ue_process_mac_sl_pdu(int module_idP,
return;
}
LOG_I(NR_MAC, "Filling psfch pdu %d\n", module_idP);
LOG_D(NR_MAC, "Filling psfch pdu %d\n", module_idP);
NR_SL_PSFCH_Config_r16_t *sl_psfch_config = mac->sl_tx_res_pool->sl_PSFCH_Config_r16->choice.setup;
const uint8_t time_gap[] = {2, 3};
uint8_t psfch_min_time_gap = time_gap[*sl_psfch_config->sl_MinTimeGapPSFCH_r16];
......@@ -653,15 +653,12 @@ void nr_ue_process_mac_sl_pdu(int module_idP,
mac->sl_info.list[0] = calloc(1, sizeof(NR_SL_UE_info_t));
harq_proc = &mac->sl_info.list[0]->UE_sched_ctrl.sl_harq_processes[harq_pid];
// mac->sl_info.list[0]->dest_id = mac->sci_pdu_rx.source_id;
// mac->sl_info.list[0]->uid = module_idP;
const uint8_t psfch_periods[] = {0,1,2,4};
long psfch_period = (sl_psfch_config->sl_PSFCH_Period_r16)
? psfch_periods[*sl_psfch_config->sl_PSFCH_Period_r16] : 0;
int delta_slots = (slot + psfch_min_time_gap) % psfch_period ? psfch_period - (slot + psfch_min_time_gap) % psfch_period: 0;
sched_slot = slot + psfch_min_time_gap + delta_slots;
sched_frame = frame;
LOG_I(NR_MAC, "harq pid: %d psfch_period %d, slot %d, delta_slots %d, sched_slot %d, time_gap %d\n", harq_pid, psfch_period, slot, delta_slots, sched_slot, psfch_min_time_gap);
if (sched_slot >= NR_MAX_SLOTS_PER_FRAME) {
sched_slot %= NR_MAX_SLOTS_PER_FRAME;
sched_frame = (sched_frame + 1) %1024;
......@@ -670,7 +667,9 @@ void nr_ue_process_mac_sl_pdu(int module_idP,
harq_proc->feedback_slot = sched_slot;
harq_proc->feedback_frame = sched_frame;
harq_proc->is_active = true;
LOG_I(NR_MAC, "feedback_slot %d, feedback_frame %d, slot %d, frame %d\n", harq_proc->feedback_slot, harq_proc->feedback_frame, slot, frame);
LOG_I(NR_MAC, "harq pid: %p:%d:%d psfch_period %d, delta_slots %d, feedback frame:slot %d:%d, frame:slot %d:%d, time_gap %d\n", harq_proc, harq_pid, mac->sl_info.list[0]->UE_sched_ctrl.sl_harq_processes[harq_pid].is_active, psfch_period, delta_slots, harq_proc->feedback_frame, harq_proc->feedback_slot, frame, slot, psfch_min_time_gap);
uint8_t ack_nack = (rx_ind->rx_indication_body + pdu_id)->rx_slsch_pdu.ack_nack;
mac->sl_tx_config_psfch_pdu[harq_pid] = calloc(1, sizeof(sl_nr_tx_config_psfch_pdu_t));
uint16_t m0 = compute_m0(module_idP);
......@@ -693,9 +692,8 @@ void nr_ue_process_mac_sl_pdu(int module_idP,
mac->sl_tx_config_psfch_pdu[harq_pid]->prb = 1;
mac->sl_tx_config_psfch_pdu[harq_pid]->psfch_payload = 1;
mac->sl_tx_config_psfch_pdu[harq_pid]->bit_len_harq = 1;
LOG_D(NR_MAC,"Filled psfch pdu\n");
LOG_I(NR_MAC,"Filled psfch pdu\n");
//nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind);
if ((rx_ind->rx_indication_body + pdu_id)->rx_slsch_pdu.ack_nack == 0)
return;
......
This diff is collapsed.
......@@ -462,25 +462,25 @@ void fill_pssch_pscch_pdu(sl_nr_tx_config_pscch_pssch_pdu_t *nr_sl_pssch_pscch_p
nr_sl_pssch_pscch_pdu->slsch_payload_length = slsch_pdu_length;
};
// void config_psfch_pdu_rx(NR_UE_MAC_INST_t *mac,
// sl_nr_rx_config_psfch_pdu_t *nr_sl_psfch_pdu,
// const NR_SL_BWP_Generic_r16_t *sl_bwp,
// const NR_SL_ResourcePool_r16_t *sl_res_pool) {
// nr_sl_psfch_pdu->freq_hop_flag = 0;
// nr_sl_psfch_pdu->group_hop_flag = 0;
// nr_sl_psfch_pdu->sequence_hop_flag = 0;
// nr_sl_psfch_pdu->second_hop_prb = 0;
// nr_sl_psfch_pdu->nr_of_symbols = 1;
// const uint8_t values[] = {7, 8, 9, 10, 11, 12, 13, 14};
// uint8_t sl_num_symbols = *sl_bwp->sl_LengthSymbols_r16 ?
// values[*sl_bwp->sl_LengthSymbols_r16] : 0;
// nr_sl_psfch_pdu->start_symbol_index = *sl_bwp->sl_StartSymbol_r16 + sl_num_symbols - 2;
// nr_sl_psfch_pdu->hopping_id = 0;
// nr_sl_psfch_pdu->prb = 1;
// //TODO
// // nr_sl_psfch_pdu->initial_cyclic_shift = mac->sl_;
// // nr_sl_psfch_pdu->mcs = mac->sl_;
// }
void config_psfch_pdu_rx(NR_UE_MAC_INST_t *mac,
sl_nr_rx_config_psfch_pdu_t *nr_sl_psfch_pdu,
const NR_SL_BWP_Generic_r16_t *sl_bwp,
const NR_SL_ResourcePool_r16_t *sl_res_pool) {
nr_sl_psfch_pdu->freq_hop_flag = 0;
nr_sl_psfch_pdu->group_hop_flag = 0;
nr_sl_psfch_pdu->sequence_hop_flag = 0;
nr_sl_psfch_pdu->second_hop_prb = 0;
nr_sl_psfch_pdu->nr_of_symbols = 1;
const uint8_t values[] = {7, 8, 9, 10, 11, 12, 13, 14};
uint8_t sl_num_symbols = *sl_bwp->sl_LengthSymbols_r16 ?
values[*sl_bwp->sl_LengthSymbols_r16] : 0;
nr_sl_psfch_pdu->start_symbol_index = *sl_bwp->sl_StartSymbol_r16 + sl_num_symbols - 2;
nr_sl_psfch_pdu->hopping_id = 0;
nr_sl_psfch_pdu->prb = 1;
//TODO
// nr_sl_psfch_pdu->initial_cyclic_shift = mac->sl_;
// nr_sl_psfch_pdu->mcs = mac->sl_;
}
void config_pscch_pdu_rx(sl_nr_rx_config_pscch_pdu_t *nr_sl_pscch_pdu,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
......
......@@ -141,7 +141,6 @@ static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool,
//and HARQ feedback for all transmissions in the resource pool is disabled.
// {sl0, sl1, sl2, sl4}
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16 = calloc(1, sizeof(long));
*sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16 = NR_SL_PSFCH_Config_r16__sl_PSFCH_Period_r16_sl4;
// Set of PRBs that are actually used for PSFCH transmission and reception (bitmap)
// 0b10101010101010101010101010101010101010101010101001 (PRBs bitmap)
......@@ -151,21 +150,18 @@ static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool,
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->buf = calloc(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->size, sizeof(uint8_t));
memset(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->buf, 0xAA, 6); // 48 bits
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->buf[6] = (0b01 << 6); // 2 bits
// Number of cyclic shift pairs used for a PSFCH transmission that can be multiplexed in a PRB
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_NumMuxCS_Pair_r16 = calloc(1, sizeof(long));
*sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_NumMuxCS_Pair_r16 = NR_SL_PSFCH_Config_r16__sl_NumMuxCS_Pair_r16_n2;
// The minimum time gap between PSFCH and the associated PSSCH in the unit of slots {sl2, sl3}
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_MinTimeGapPSFCH_r16 = calloc(1, sizeof(long));
*sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_MinTimeGapPSFCH_r16 = NR_SL_PSFCH_Config_r16__sl_MinTimeGapPSFCH_r16_sl2;
// Scrambling ID {0..1023} for sequence hopping of the PSFCH used in the resource pool
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16 = calloc(1, sizeof(long));
*sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16 = 1;
// Indicates the number of PSFCH resources available {startSubCH, allocSubCH} for multiplexing HARQ-ACK information in a PSFCH transmission
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_CandidateResourceType_r16 = calloc(1, sizeof(long));
*sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_CandidateResourceType_r16 = NR_SL_PSFCH_Config_r16__sl_PSFCH_CandidateResourceType_r16_startSubCH;
// indicates allowed sync sources which are allowed to use this resource pool
sl_res_pool->sl_SyncAllowed_r16 = calloc(1, sizeof(NR_SL_SyncAllowed_r16_t));
......
......@@ -74,7 +74,12 @@
#define SL_CONFIG_STRING_RESPOOL_SUBCH_START_RB "sl_StartRB_Subchannel"
#define SL_CONFIG_STRING_RESPOOL_NUM_RBS "sl_RB_Number"
#define SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS "sl_NumSubchannel"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_PERIOD "sl_PSFCH_Period"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_RB_SET "sl_PSFCH_RB_Set"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_NUMMUXCS_PAIR "sl_NumMuxCS_Pair"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_MINTIMEGAP "sl_MinTimeGapPSFCH"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_HOPID "sl_PSFCH_HopID"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_CANDIDATERESOURCETYPE "sl_PSFCH_CandidateResourceType"
#define SL_CONFIG_STRING_UEINFO "sl_UEINFO"
#define SL_CONFIG_STRING_UEINFO_SRCID "srcid"
......@@ -155,8 +160,12 @@
{SL_CONFIG_STRING_RESPOOL_SUBCH_SIZE_IN_RBS,NULL,0,.i64ptr=sl_res_pool->sl_SubchannelSize_r16,.defint64val=0,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_SUBCH_START_RB,NULL,0,.i64ptr=sl_res_pool->sl_StartRB_Subchannel_r16,.defint64val=0,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_NUM_RBS,NULL,0,.i64ptr=sl_res_pool->sl_RB_Number_r16,.defint64val=106,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS,NULL,0,.i64ptr=sl_res_pool->sl_NumSubchannel_r16,.defint64val=10,TYPE_INT64,0}}
{SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS,NULL,0,.i64ptr=sl_res_pool->sl_NumSubchannel_r16,.defint64val=10,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_PSFCH_PERIOD,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16,.defint64val=3,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_PSFCH_NUMMUXCS_PAIR,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_NumMuxCS_Pair_r16,.defint64val=1,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_PSFCH_MINTIMEGAP,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_MinTimeGapPSFCH_r16,.defint64val=1,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_PSFCH_HOPID,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16,.defint64val=1,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_PSFCH_CANDIDATERESOURCETYPE,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_CandidateResourceType_r16,.defint64val=0,TYPE_INT64,0}}
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Sidelink Top-Level UE Info */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
......
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