Commit 87e25f56 authored by Michele Paffetti's avatar Michele Paffetti

adding some consideration and implement some checking based on FAPI...

 adding some consideration and implement some checking based on FAPI specifications for ndlsch path. Function for encoding, modulation ecc.. still to be added. Code Compile. 144 warnings
parent 637ab8cb
......@@ -2120,6 +2120,8 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
// generate DCIs in order of decreasing aggregation level, then common/ue spec
// MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization
for (L=3; L>=0; L--) {
//first common DCI
for (i=0; i<num_common_dci; i++) {
if (dci_alloc[i].L == (uint8_t)L) {
......@@ -2140,6 +2142,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
}
}
//start the second loop from the end of the previous one for ue specific DCI
for (; i<num_ue_spec_dci + num_common_dci; i++) {
if (dci_alloc[i].L == (uint8_t)L) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -42,7 +42,7 @@ typedef enum
{
DCIFormatN0 = 0,
DCIFormatN1,
DCIFormatN1_RA,
DCIFormatN1_RA,//is for initial RA procedure (semi-static information) so maybe is not needed
DCIFormatN1_RAR,
DCIFormatN2,
DCIFormatN2_Ind,
......@@ -288,4 +288,4 @@ typedef struct DCIN2_Pag DCIN2_Pag_t;
#define MAX_DCI_SIZE_BITS_NB_IOT 23
#endif
\ No newline at end of file
#endif
......@@ -56,7 +56,7 @@ void NB_add_dci(DCI_PDU_NB *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L = aggregation;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti = rnti;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format = dci_fmt;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].npdcch_start_symbol = npdcch_start_symbol;
DCI_pdu->npdcch_start_symbol = npdcch_start_symbol;
DCI_pdu->Num_dci++;
......@@ -122,7 +122,6 @@ int NB_generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
((DCIN0_t *)ULSCH_DCI_NB)->ndi =ndi;
((DCIN0_t *)ULSCH_DCI_NB)->DCIRep =DCIRep;
eNB->DCI_pdu->Num_dci++;
NB_add_dci(eNB->DCI_pdu,ULSCH_DCI_NB,rnti,sizeof(DCIN0_t),aggregation,sizeof_DCIN0_t,DCIFormatN0, npdcch_start_symbol);
......@@ -160,6 +159,7 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
eNB->DCI_pdu = (DCI_PDU_NB*) malloc(sizeof(DCI_PDU_NB));
//N1 parameters
/// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
......@@ -229,8 +229,8 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
/*Now configure the ndlsch structure*/
ndlsch->subframe_tx[subframe] = 1; // check if it's OK
ndlsch->rnti = rnti;
ndlsch->active = 1;
ndlsch->rnti = rnti; //we store the RNTI (e.g. for RNTI will be used later)
ndlsch->active = 0; //will be activated by the corresponding NDSLCH pdu
// use this value to configure PHY both harq_processes and resource mapping.
ndlsch_harq->scheduling_delay = Sched_delay;
......@@ -248,8 +248,7 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
* ISF = ResAssign
*/
ndlsch_harq->TBS = TBStable_NB_IoT[mcs][ResAssign]; // this table should be rewritten for nb-iot
ndlsch_harq->frame = frame;
ndlsch_harq->TBS = TBStable_NB_IoT[mcs][ResAssign];
ndlsch_harq->subframe = subframe;
//ndlsch_harq->B; we don-t have now my is given when we receive the dlsch data
......@@ -299,6 +298,8 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
/*Now configure the ndlsch structure*/
ndlsch->subframe_tx[subframe] = 1; // check if it's OK
ndlsch->rnti = rnti; //we store the RNTI (e.g. for RNTI will be used later)
ndlsch->active = 0;//will be activated by the corresponding NDSLCH pdu
// use this value to configure PHY both harq_processes and resource mapping.
ndlsch_harq->scheduling_delay = Sched_delay;
......
......@@ -818,14 +818,24 @@ typedef enum
}ndlsch_flag_t;
typedef struct {
//array containing the pdus of DCI
uint8_t *a[2];
//Array containing encoded DCI data
uint8_t *e[2];
}NB_IoT_eNB_NPDCCH_t;
typedef struct {
///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission
/// see FAPI/NFAPI specs Table 4-121
uint8_t npdcch_start_symbol;
/// Length of DCI in bits
uint8_t dci_length;
/// Aggregation level only 0,1 in NB-IoT
/// Aggregation level only 1,2 in NB-IoT
uint8_t L;
/// Position of first CCE of the dci
int firstCCE;
......@@ -842,6 +852,9 @@ typedef struct {
typedef struct {
//delete the count for the DCI numbers,NUM_DCI_MAX should set to 2
uint32_t num_npdcch_symbols;
///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission
/// see FAPI/NFAPI specs Table 4-45
uint8_t npdcch_start_symbol;
uint8_t Num_dci;
DCI_ALLOC_NB_t dci_alloc[2] ;
} DCI_PDU_NB;
......@@ -882,6 +895,8 @@ typedef struct {
uint8_t mcs;
// we don't have code block segmentation / crc attachment / concatenation in NB-IoT R13 36.212 6.4.2
// we don't have beamforming in NB-IoT
//this index will be used mainly for SI message buffer
uint8_t pdu_buffer_index;
} NB_IoT_DL_eNB_HARQ_t;
......
......@@ -92,7 +92,7 @@ void npbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
/*Function to pack the DCI*/
void NB_add_dci(DCI_PDU_NB *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt, uint8_t npdcch_start_symbol);
/*Use the UL DCI Information to configure PHY and also Packed*/
/*Use the UL DCI Information to configure PHY and also Pack the DCI*/
int NB_generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
DCI_CONTENT *DCI_Content,
......@@ -102,7 +102,7 @@ int NB_generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
uint8_t aggregation,
uint8_t npdcch_start_symbol
);
/*Use the DL DCI Information to configure PHY and also Packed*/
/*Use the DL DCI Information to configure PHY and also Pack the DCI*/
int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
int frame,
uint8_t subframe,
......@@ -115,5 +115,17 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
uint8_t npdcch_start_symbol
);
/*Function for DCI encoding, scrambling, modulation*/
uint8_t generate_dci_top_NB(
NB_IoT_eNB_NPDCCH_t* npdcch,
uint8_t Num_dci,
DCI_ALLOC_NB_t *dci_alloc,
int16_t amp,
NB_DL_FRAME_PARMS *fp,
int32_t **txdataF,
uint32_t subframe,
uint8_t npdcch_start_symbol);
#endif
......@@ -703,7 +703,7 @@ typedef struct PHY_VARS_eNB_s {
*/
NB_IoT_eNB_NPBCH *npbch;
//NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX_NB_IoT]; //check the max size of this array
NB_IoT_eNB_NPDCCH_t *npdcch; //check if should be an array and the max size of this array
NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT];
NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR
NB_IoT_eNB_NDLSCH_t *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1;
......
......@@ -152,6 +152,13 @@ typedef struct {
} DL_GapConfig_NB;
typedef struct {
/// Number of resource blocks (RB) in DL of the LTE (for knowing the bandwidth)
uint8_t N_RB_DL;
/// Number of resource blocks (RB) in UL of the LTE ((for knowing the bandwidth)
uint8_t N_RB_UL;
/// Cell ID
uint16_t Nid_cell;
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
......@@ -226,8 +233,6 @@ typedef struct {
// CE level to determine the NPRACH Configuration (one CE for each NPRACH config.)
uint8_t CE;
/*
* index of the PRB assigned to NB-IoT carrier in in-band/guard-band operating mode
*/
......
......@@ -123,6 +123,7 @@ void handle_nfapi_dlsch_pdu_NB(PHY_VARS_eNB *eNB,
{
eNB->ndlsch_ra->harq_process->pdu = sdu;
eNB->ndlsch_ra->npdsch_start_symbol = rel13->start_symbol;
eNB->ndlsch_ra->active = 1;
}
else
{ //this for ue data
......@@ -137,8 +138,11 @@ void handle_nfapi_dlsch_pdu_NB(PHY_VARS_eNB *eNB,
ndlsch = eNB->ndlsch[(uint8_t)UE_id];
ndlsch_harq = eNB->ndlsch[(uint8_t)UE_id]->harq_process;
AssertFatal(ndlsch_harq!=NULL,"dlsch_harq for ue specific is null\n");
ndlsch->npdsch_start_symbol = rel13->start_symbol;
ndlsch_harq->pdu = sdu;
ndlsch->active = 1;
}
}
......@@ -152,6 +156,11 @@ void handle_nfapi_dlsch_pdu_NB(PHY_VARS_eNB *eNB,
/////////////////////////////////////////////////////////////////////////////////////////////////
//Memo for initialization TODO: target/SIMU/USER/init_lte.c/init_lte_eNB --> new_eNB_dlsch(..) //
//this is where the allocation of PHy_vars_eNB and all the ndlsch structures happen //
/////////////////////////////////////////////////////////////////////////////////////////////////
// do the schedule response and trigger the TX
void schedule_response(Sched_Rsp_t *Sched_INFO)
......@@ -211,7 +220,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
for (i=0;i<number_dl_pdu;i++) //in principle this should be always = 1
for (i=0;i<number_dl_pdu;i++) //in principle this should be at most 2 (in case of DCI)
{
dl_config_pdu = &DL_req->dl_config_pdu_list[i];
switch (dl_config_pdu->pdu_type)
......@@ -235,7 +244,16 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
break;
case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE:
//we can have three types of NDLSCH based on our assumptions: SIB1, SI, Data, RAR
//remember that SI messages have no DCI in NB-IoT therefore this is the only way to configure the ndlsch_SI/ndlsch_SIB1 structure
//remember that SI messages have no DCI in NB-IoT therefore this is the only way to configure the ndlsch_SI/ndlsch_SIB1 structures ndlsch->active = 1;
/*
* OBSERVATION:
* Although 2 DCI may be received over a schedule_response the transmission of the NDLSCH data foresees only 1 NDLSCH PDU at time.
* Therefore is the MAC scheduler that knowing the different timing delay will send the corresponding schedule_response containing the NDLSCH PDU and the MAC PDU
* at the proper DL subframe
* -for this reason the activation of the ndslch structure is done only when we receive the NDLSCH pdu (here) such the in the TX procedure only 1 ue-specific pdu
* result active from the loop before calling the ndlsch_procedure
*/
handle_nfapi_dlsch_pdu_NB(eNB, proc,dl_config_pdu,Sched_INFO->sdu[i]);
......
......@@ -376,6 +376,7 @@ uint16_t get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1);
int8_t find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
//NB-IoT
int8_t find_ue_NB(uint16_t rnti, PHY_VARS_eNB *eNB);
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rnti);
......
......@@ -487,24 +487,19 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
DCI_format_NB_t DCI_format;
NB_IoT_eNB_NDLSCH_t *ndlsch;
DCI_Content = (DCI_CONTENT*) malloc(sizeof(DCI_CONTENT));
// In NB-IoT, there is no DCI for SI, we might use the scheduling infomation from SIB1-NB to get the phyical layer configuration.
//mapping the fapi parameters to the oai parameters
// check DCI format is N1 (format 0) or N2 (format 1)
// check DCI format is N1 (format 0)
if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_format == 0)
{
//check DCI format N1 is for RAR rnti_type in FAPI specs table 4-45
if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti_type == 1)
{
DCI_format = DCIFormatN1_RAR;
ndlsch= eNB->ndlsch_ra;//we store the RNTI for the RAR
ndlsch->ndlsch_type = RAR;
//mapping the fapi parameters to the oai parameters
DCI_format = DCIFormatN1_RAR;
//DCI format N1 to RAR
DCI_Content->DCIN1_RAR.type = 1;
......@@ -519,7 +514,11 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
// fill the dlsch_ra_NB sructure for RAR, and packed the DCI PDU
LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");
ndlsch= eNB->ndlsch_ra;
ndlsch->ndlsch_type = RAR;
LOG_D(PHY,"Generating dlsch params for RA_RNTI and packing DCI\n");
NB_generate_eNB_dlsch_params_from_dci(eNB,
frame,
subframe,
......@@ -539,10 +538,12 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
//TODO target/SIMU/USER?init_lte/init_lte_eNB we should allocate the ndlsch structures
UE_id = find_ue_NB(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti, eNB);
AssertFatal(UE_id == -1, "no ndlsch context available or no ndlsch context corresponding to that rnti\n");
AssertFatal(UE_id != -1, "no ndlsch context available or no ndlsch context corresponding to that rnti\n");
ndlsch = eNB->ndlsch[(uint8_t)UE_id]; //in the old implementation they also consider UE_id = 1;
ndlsch->ndlsch_type = UE_Data;
//mapping the fapi parameters to the oai parameters
DCI_format = DCIFormatN1;
//DCI format N1 to DLSCH
DCI_Content->DCIN1.type = 1;
......@@ -555,8 +556,14 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
DCI_Content->DCIN1.HARQackRes = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource;
DCI_Content->DCIN1.DCIRep = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number;
//fill the ndlsch structure for UE
//fill the ndlsch structure for UE and packed the DCI PD
ndlsch = eNB->ndlsch[(uint8_t)UE_id]; //in the old implementation they also consider UE_id = 1;
ndlsch->ndlsch_type = UE_Data;
//parameters we don't consider pdsch config dedicated since not calling the phy config dedicated step2
LOG_D(PHY,"Generating dlsch params for DCIN1 data and packing DCI\n");
NB_generate_eNB_dlsch_params_from_dci(eNB,
frame,
subframe,
......@@ -1041,12 +1048,13 @@ void NB_phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
*
*
*XXX important: set the flag HARQ process->status to DISABLE when PHY finished the SI-transmission over the 2 or 8 subframes
*XXX important: whenever we enter for some error in the ndlsch_procedure with a pdu that is NULL but all the data of the SI have been transmitted --> generate error
*XXX : the npdlsch_procedure in this case should be only called when is triggered by the MAC schedule_response (use the status flag set by the schedule_response)
*XXX important: whenever we enter for some error in the ndlsch_procedure with a pdu that is NULL but all the data of the SI have been transmitted (pdu_buffer_index = 0)
*XXX --> generate error
*XXX: the npdlsch_procedure in this case should be only called when is triggered by the MAC schedule_response (use the status flag set by the schedule_response)
*
*/
if(eNB->ndlsch_SI->harq_process->status == ACTIVE && (eNB->ndlsch_SI->harq_process->status != ACTIVE || subframe != 4)) //condition on SIB1-NB
if(eNB->ndlsch_SI->harq_process->status == ACTIVE && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE || subframe != 4)) //condition on SIB1-NB
{
if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
{
......@@ -1078,31 +1086,79 @@ void NB_phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
}
///check for RAR transmission
if(eNB->ndlsch_ra != NULL && eNB->ndlsch_ra->active == 1)
if(eNB->ndlsch_ra != NULL && eNB->ndlsch_ra->active == 1 && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE || subframe != 4)) //condition on SIB1-NB
{
if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5 && subframe != 9)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
eNB->ndlsch_ra->harq_process->pdu);
npdsch_procedures(eNB,
proc,
eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
eNB->ndlsch_ra->harq_process->pdu);
eNB->ndlsch_ra->active= 0;
//it should be activated only when we receive the proper DCIN1_RAR
eNB->ndlsch_ra->active= 0;
}
}
else //this frame not foresee the transmission of NSSS (subframe 9 is available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
eNB->ndlsch_ra->harq_process->pdu);
}
//it should be activated only when we receive the proper DCIN1_RAR
eNB->ndlsch_ra->active= 0; // maybe this is already done inside the ndlsch_procedure
}
}
}
/*
* Delays between DCI transmission and NDLSCH transmission are taken in consideration by the MAC scheduler by sending in the proper subframe the scheduler_response
* Transmission over more subframe and Repetitions are managed directly by the PHY layer
* We should have only 1 ue-specific ndlsch structure active at each time (active flag is set = 1 only at the corresponding NDLSCH pdu reception and not at the DCI time
* (NDLSCH transmission should be compliant with the FAPI procedure Figure 3-49)
*
* XXX how are managed the transmission and repetitions???
*
*/
//transmission of UE specific ndlsch data
//this should give only 1 result (since only 1 ndlsch procedure is activated at once) so we brak after the transmission
for (int UE_id = 0; i < NUMBER_OF_UE_MAX_NB_IoT; UE_id++)
{
if(eNB->ndlsch[(uint8_t)UE_id] != NULL && eNB->ndlsch[(uint8_t)UE_id]->active == 1)
if(eNB->ndlsch[(uint8_t)UE_id] != NULL && eNB->ndlsch[(uint8_t)UE_id]->active == 1 && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE || subframe != 4)) //condition on sib1-NB
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch[(uint8_t)UE_id],
eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5 && subframe != 9)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch[(uint8_t)UE_id],
eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
break;
}
}
else //this frame not foresee the transmission of NSSS (subframe 9 is available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch[(uint8_t)UE_id],
eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
break;
}
}
}
//we don't care about subframe TX for the PUCCH since not defined by NB-IoT
......@@ -1114,11 +1170,13 @@ void NB_phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
/*If we have DCI to generate do it now*/
generate_dci_top_NB(
eNB->npdcch,
dci_pdu->Num_dci,
dci_pdu->dci_alloc,
AMP,
fp,
eNB->common_vars.txdataF[0],
subframe);
subframe,
dci_pdu->npdcch_start_symbol); //this parameter depends by eutraControlRegionSize (see TS36.213 16.6.1)
}
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