#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD (16) // Maximum association period is 16
#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max association pattern period is 160ms and minimum PRACH configuration period is 10ms
#define MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max nb of association periods in an association pattern period of 160ms
#define MAX_NB_FRAME_IN_PRACH_CONF_PERIOD (16) // Max PRACH configuration period is 160ms and frame is 10ms
#define MAX_NB_SLOT_IN_FRAME (160) // Max number of slots in a frame (@ SCS 240kHz = 160)
#define MAX_NB_FRAME_IN_ASSOCIATION_PATTERN_PERIOD (16) // Maximum number of frames in the maximum association pattern period
#define MAX_NB_SSB (64) // Maximum number of possible SSB indexes
#define MAX_RO_PER_SSB (8) // Maximum number of consecutive ROs that can be mapped to an SSB according to the ssb_per_RACH config
// Maximum number of ROs that can be mapped to an SSB in an association pattern
// This is to reserve enough elements in the SSBs list for each mapped ROs for a single SSB
// An arbitrary maximum number is chosen to be safe: maximum number of slots in an association pattern * maximum number of ROs in a slot
uint8_tnb_of_assoc_period;// Nb of association periods within the association pattern
uint8_tnb_of_prach_conf_period_in_max_period;// Nb of PRACH configuration periods within the maximum association pattern period (according to the size of the configured PRACH
uint8_tnb_of_frame;// Total number of frames included in the association pattern period (after mapping the SSBs and determining the real association pattern length)
}prach_association_pattern_t;
// SSB details
typedefstructssb_info{
boolean_ttransmitted;// True if the SSB index is transmitted according to the SSB positions map configuration
prach_occasion_info_t*mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN];// List of mapped RACH Occasions to this SSB index
uint16_tnb_mapped_ro;// Total number of mapped ROs to this SSB index
}ssb_info_t;
// List of all the possible SSBs and their details
LOG_D(MAC,"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n",
// WIP: Assumption for now is that all the PRACH configuration periods within a maximum association pattern period have the same number of PRACH occasions
// (No PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule)
// There is only one possible association period which can contain up to 16 PRACH configuration periods
LOG_D(MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n");
AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN>ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n",ssb_list.tx_ssb[ssb_idx].nb_mapped_ro);
LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n",ssb_idx,ro_p->slot,ro_p->start_symbol,slot,ro_in_time,ro_in_freq,prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq);
LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u\n",ssb_list.tx_ssb[ssb_idx].nb_mapped_ro);
// If all the required SSBs are mapped to this RO, exit the loop of SSBs
if(ro_p->nb_mapped_ssb==ssb_rach_ratio){
ssb_idx++;
break;
}
}// if ssb_idx is transmitted
}// for ssb_idx
// Exit the loop of ROs if there is no more SSB to map
if(MAX_NB_SSB==ssb_idx)break;
}// for ro_in_freq
// Exit the loop of ROs if there is no more SSB to map
if(MAX_NB_SSB==ssb_idx)break;
}// for ro_in_time
// Exit the loop of slots if there is no more SSB to map
if(MAX_NB_SSB==ssb_idx)break;
}// for slot
// Exit the loop frames if there is no more SSB to map
if(MAX_NB_SSB==ssb_idx)break;
}// for frame
// Exit the loop of PRACH configurations if there is no more SSB to map
if(MAX_NB_SSB==ssb_idx)break;
}// for n_prach_conf
// WIP: note that there is no re-mapping of the SSBs within the association period since there is no invalid ROs in the PRACH config periods that would create this situation
}// if multiple_ssbs_per_ro
else{
// --------------------
// --------------------
// Multiple ROs per SSB
// --------------------
// --------------------
n_prach_conf=0;
// Go through the list of transmitted SSBs
for(ssb_idx=0;ssb_idx<MAX_NB_SSB;ssb_idx++){
uint8_tnb_mapped_ro_in_association_period=0;// Reset the nb of mapped ROs for the new SSB index
// Map only the transmitted ssb_idx
if(true==ssb_list.tx_ssb[ssb_idx].transmitted){
// Map all the required ROs to this SSB
// Go through the list of PRACH config periods within this association period
AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN>ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n",ssb_list.tx_ssb[ssb_idx].nb_mapped_ro);
nb_mapped_ro_in_association_period++;
LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n",ssb_idx,ro_p->slot,ro_p->start_symbol,slot,ro_in_time,ro_in_freq,prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq);
LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n",ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,nb_mapped_ro_in_association_period);
// Exit the loop if this SSB has been mapped to all the required ROs
// WIP: Assuming that ssb_rach_ratio equals the maximum nb of times a given ssb_idx is mapped within an association period:
// this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule
AssertFatal(prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb,"%u not found in the mapped SSBs to the PRACH occasion",selected_gnb_ssb_idx);
if(format1!=0xff){
switch(format0){// dual PRACH format
case0xa1:
prach_config_pdu->prach_format=11;
break;
case0xa2:
prach_config_pdu->prach_format=12;
break;
case0xa3:
prach_config_pdu->prach_format=13;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
}else{
switch(format0){// single PRACH format
case0:
prach_config_pdu->prach_format=0;
break;
case1:
prach_config_pdu->prach_format=1;
break;
case2:
prach_config_pdu->prach_format=2;
break;
case3:
prach_config_pdu->prach_format=3;
break;
case0xa1:
prach_config_pdu->prach_format=4;
break;
case0xa2:
prach_config_pdu->prach_format=5;
break;
case0xa3:
prach_config_pdu->prach_format=6;
break;
case0xb1:
prach_config_pdu->prach_format=7;
break;
case0xb4:
prach_config_pdu->prach_format=8;
break;
case0xc0:
prach_config_pdu->prach_format=9;
break;
case0xc2:
prach_config_pdu->prach_format=10;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");