/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see .
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file phy_procedures_lte_eNB.c
* \brief Implementation of eNB procedures from 36.213 LTE specifications
* \author R. Knopp, F. Kaltenberger, N. Nikaein
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "MAC_INTERFACE/defs.h"
#include "MAC_INTERFACE/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif
//#define DEBUG_PHY_PROC (Already defined in cmake)
//#define DEBUG_ULSCH
//#ifdef OPENAIR2
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
//#endif
#include "assertions.h"
#include "msc.h"
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
# if ENABLE_RAL
# include "timer.h"
# endif
#endif
//#define DIAG_PHY
#define NS_PER_SLOT 500000
#define PUCCH 1
extern int exit_openair;
//extern void do_OFDM_mod(mod_sym_t **txdataF, int32_t **txdata, uint32_t frame, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(16)));
int eNB_sync_buffer0[640*6] __attribute__ ((aligned(16)));
int eNB_sync_buffer1[640*6] __attribute__ ((aligned(16)));
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};
extern uint16_t hundred_times_log10_NPRB[100];
unsigned int max_peak_val;
int max_sect_id, max_sync_pos;
//DCI_ALLOC_t dci_alloc[8];
#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif
#if defined(SMBV) && !defined(EXMIMO)
extern const char smbv_fname[];
extern unsigned short config_frames[4];
extern uint8_t smbv_frame_cnt;
#endif
#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif
uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_subframe)
{
const int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
const int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->ulsch_eNB[UE_id]->rnti,frame,subframe,
phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex);
if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) { // 5 ms SR period
if ((subframe%5) == phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex)
return(1);
} else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period
if (subframe==(phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5))
return(1);
} else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period
if ((10*(frame&1)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15))
return(1);
} else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period
if ((10*(frame&3)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35))
return(1);
} else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period
if ((10*(frame&7)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75))
return(1);
}
return(0);
}
void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
{
DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->tail_freelist] = harq_pid;
DLSCH_ptr->tail_freelist = (DLSCH_ptr->tail_freelist + 1) % 10;
}
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
{
if (DLSCH_ptr->head_freelist == DLSCH_ptr->tail_freelist) {
LOG_E(PHY, "%s:%d: you cannot read this!\n", __FILE__, __LINE__);
abort();
}
/* basic check, in case several threads deal with the free list at the same time
* in normal situations it should not happen, that's also why we don't use any
* locking mechanism to protect the free list
* to be refined in case things don't work properly
*/
if (harq_pid != DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]) {
LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
abort();
}
DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
}
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
{
uint8_t i;
#ifdef DEBUG_PHY_PROC
LOG_I(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
(uint16_t)rnti);
#endif
for (i=0; idlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
return(-1);
} else {
if (phy_vars_eNB->eNB_UE_stats[i].crnti==0) {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
LOG_I(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
phy_vars_eNB->dlsch_eNB[i][0]->rnti = rnti;
phy_vars_eNB->ulsch_eNB[i]->rnti = rnti;
phy_vars_eNB->eNB_UE_stats[i].crnti = rnti;
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_below = 0;
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
LOG_I(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
phy_vars_eNB->rx_total_gain_eNB_dB,
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH);
return(i);
}
}
}
return(-1);
}
int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction_flag)
{
uint8_t i;
int j;
for (i=0; idlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rnti);
LOG_E(PHY,"Can't remove UE, not enough memory allocated\n");
return(-1);
} else {
if (phy_vars_eNB->eNB_UE_stats[i].crnti==rnti) {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rnti);
#ifdef DEBUG_PHY_PROC
LOG_I(PHY,"eNB %d removing UE %d with rnti %x\n",phy_vars_eNB->Mod_id,i,rnti);
#endif
//msg("[PHY] UE_id %d\n",i);
clean_eNb_dlsch(phy_vars_eNB->dlsch_eNB[i][0], abstraction_flag);
clean_eNb_ulsch(phy_vars_eNB->ulsch_eNB[i],abstraction_flag);
//phy_vars_eNB->eNB_UE_stats[i].crnti = 0;
memset(&phy_vars_eNB->eNB_UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
// mac_exit_wrapper("Removing UE");
/* clear the harq pid freelist */
phy_vars_eNB->dlsch_eNB[i][0]->head_freelist = 0;
phy_vars_eNB->dlsch_eNB[i][0]->tail_freelist = 0;
for (j = 0; j < 8; j++)
put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], j);
return(i);
}
}
}
MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rnti);
return(-1);
}
int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB)
{
uint8_t i;
for (i=0; ieNB_UE_stats[i].crnti==0) {
/*if ((phy_vars_eNB->dlsch_eNB[i]) &&
(phy_vars_eNB->dlsch_eNB[i][0]) &&
(phy_vars_eNB->dlsch_eNB[i][0]->rnti==0))*/
LOG_D(PHY,"Next free UE id is %d\n",i);
return(i);
}
}
return(-1);
}
int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t ul_flag)
{
LTE_eNB_DLSCH_t *DLSCH_ptr;
LTE_eNB_ULSCH_t *ULSCH_ptr;
uint8_t ulsch_subframe,ulsch_frame;
uint8_t i;
int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
if (UE_id==-1) {
LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
*round=0;
return(-1);
}
if (ul_flag == 0) {// this is a DL request
DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][0];
// set to no available process first
*harq_pid = -1;
for (i=0; iMdlharq; i++) {
if (DLSCH_ptr->harq_processes[i]!=NULL) {
if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe;
if (sf2<=sf1)
sfdiff = sf1-sf2;
else // this happens when wrapping around 1024 frame barrier
sfdiff = 10240 + sf1-sf2;
LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff);
if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms)
sfdiff_max = sfdiff;
*harq_pid = i;
*round = DLSCH_ptr->harq_processes[i]->round;
}
}
} else { // a process is not defined
LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id);
return(-1);
}
}
/* if no active harq pid, get the oldest in the freelist, if any */
if (*harq_pid == 255 && DLSCH_ptr->head_freelist != DLSCH_ptr->tail_freelist) {
*harq_pid = DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist];
*round = 0;
LOG_D(PHY,"process %d is first free process\n", *harq_pid);
}
LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
frame,subframe,*harq_pid);
} else { // This is a UL request
ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch_eNB[(uint32_t)UE_id];
ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,subframe);
ulsch_frame = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,frame,subframe);
// Note this is for TDD configuration 3,4,5 only
*harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,
ulsch_frame,
ulsch_subframe);
*round = ULSCH_ptr->harq_processes[*harq_pid]->round;
LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
}
return(0);
}
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
//return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
}
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
//return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
}
#ifdef EMOS
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *phy_vars_eNB)
{
}
#endif
/*
void phy_procedures_eNB_S_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag) {
int sect_id = 0, aa;
if (next_slot%2==0) {
#ifdef DEBUG_PHY_PROC
msg("[PHY][eNB %d] Frame %d, slot %d: Generating pilots for DL-S\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot);
#endif
for (sect_id=0;sect_idlte_frame_parms.nb_antennas_tx; aa++) {
#ifdef IFFT_FPGA
memset(&phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id][aa][next_slot*(phy_vars_eNB->lte_frame_parms.N_RB_DL*12)*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)],
0,(phy_vars_eNB->lte_frame_parms.N_RB_DL*12)*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)*sizeof(mod_sym_t));
#else
memset(&phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id][aa][next_slot*phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)],
0,phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)*sizeof(mod_sym_t));
#endif
}
generate_pilots_slot(phy_vars_eNB,
phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id],
AMP,
next_slot);
msg("[PHY][eNB] Frame %d, subframe %d Generating PSS\n",
phy_vars_eNB->frame,next_slot>>1);
generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id],
4*AMP,
&phy_vars_eNB->lte_frame_parms,
2,
next_slot);
}
else {
#ifdef PHY_ABSTRACTION
generate_pss_emul(phy_vars_eNB,sect_id);
#endif
}
}
}
}
*/
void phy_procedures_eNB_S_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type)
{
UNUSED(r_type);
// unsigned char sect_id=0;
int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_rx, subframe);
#endif
// for (sect_id=0;sect_idfirst_run_I0_measurements);
}
#ifdef PHY_ABSTRACTION
else {
lte_eNB_I0_measurements_emul(phy_vars_eNB,
0);
}
#endif
}
#ifdef EMOS
void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *phy_vars_eNB)
{
uint8_t aa;
uint16_t last_subframe_emos;
uint16_t pilot_pos1 = 3 - phy_vars_eNB->lte_frame_parms.Ncp, pilot_pos2 = 10 - 2*phy_vars_eNB->lte_frame_parms.Ncp;
uint32_t bytes;
last_subframe_emos=0;
#ifdef EMOS_CHANNEL
//if (last_slot%2==1) // this is for all UL subframes
if (subframe==3)
for (aa=0; aalte_frame_parms.nb_antennas_rx; aa++) {
memcpy(&emos_dump_eNB.channel[aa][last_subframe_emos*2*phy_vars_eNB->lte_frame_parms.N_RB_UL*12],
&phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos1],
phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int));
memcpy(&emos_dump_eNB.channel[aa][(last_subframe_emos*2+1)*phy_vars_eNB->lte_frame_parms.N_RB_UL*12],
&phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos2],
phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int));
}
#endif
if (subframe==4) {
emos_dump_eNB.timestamp = rt_get_time_ns();
emos_dump_eNB.frame_tx = phy_vars_eNB->proc[subframe].frame_rx;
emos_dump_eNB.rx_total_gain_dB = phy_vars_eNB->rx_total_gain_eNB_dB;
emos_dump_eNB.mimo_mode = phy_vars_eNB->transmission_mode[0];
memcpy(&emos_dump_eNB.PHY_measurements_eNB,
&phy_vars_eNB->PHY_measurements_eNB[0],
sizeof(PHY_MEASUREMENTS_eNB));
memcpy(&emos_dump_eNB.eNB_UE_stats[0],&phy_vars_eNB->eNB_UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats));
bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_eNB, sizeof(fifo_dump_emos_eNB));
//bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test"));
if (bytes!=sizeof(fifo_dump_emos_eNB)) {
LOG_W(PHY,"[eNB %d] Frame %d, subframe %d, Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB));
} else {
if (phy_vars_eNB->proc[(subframe+1)%10].frame_tx%100==0) {
LOG_I(PHY,"[eNB %d] Frame %d (%d), subframe %d, Writing %d bytes EMOS data to FIFO\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[(subframe+1)%10].frame_rx, ((fifo_dump_emos_eNB*)&emos_dump_eNB)->frame_tx, subframe, bytes);
}
}
}
}
#endif
#ifndef OPENAIR2
void fill_dci(DCI_PDU *DCI_pdu, uint8_t sched_subframe, PHY_VARS_eNB *phy_vars_eNB)
{
int i;
uint8_t cooperation_flag = phy_vars_eNB->cooperation_flag;
uint8_t transmission_mode = phy_vars_eNB->transmission_mode[0];
uint32_t rballoc = 0x7FFF;
uint32_t rballoc2 = 0x000F;
int subframe = phy_vars_eNB->proc[sched_subframe].subframe_tx;
/*
uint32_t rand = taus();
if ((subframe==8) || (subframe==9) || (subframe==0))
rand = (rand%5)+5;
else
rand = (rand%4)+5;
*/
uint32_t bcch_pdu;
uint64_t dlsch_pdu;
DCI_pdu->Num_common_dci = 0;
DCI_pdu->Num_ue_spec_dci=0;
switch (subframe) {
case 5:
DCI_pdu->Num_common_dci = 1;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = SI_RNTI;
DCI_pdu->dci_alloc[0].format = format1A;
DCI_pdu->dci_alloc[0].ra_flag = 0;
switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
case 6:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->type = 1;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->rv = 1;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->mcs = 1;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_1_5MHz_TDD_1_6_t));
} else {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->type = 1;
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1;
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1;
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_1_5MHz_TDD_1_6_t));
}
break;
case 25:
default:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_FDD_t;
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->type = 1;
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->rv = 1;
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->mcs = 1;
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_5MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
} else {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->type = 1;
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1;
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1;
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
}
break;
case 50:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_10MHz_FDD_t;
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->type = 1;
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->rv = 1;
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->mcs = 1;
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_10MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_10MHz_TDD_1_6_t));
} else {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->type = 1;
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1;
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1;
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_10MHz_TDD_1_6_t));
}
break;
case 100:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_20MHz_FDD_t;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->type = 1;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->rv = 1;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->mcs = 1;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_20MHz_TDD_1_6_t));
} else {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->type = 1;
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1;
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1;
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0;
((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_20MHz_TDD_1_6_t));
}
break;
}
case 6:
/*
DCI_pdu->Num_ue_spec_dci = 1;
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI2_5MHz_2A_M10PRB_TDD_t;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0x1236;
DCI_pdu->dci_alloc[0].format = format2_2A_M10PRB;
DCI_pdu->dci_alloc[0].ra_flag = 0;
DLSCH_alloc_pdu1.rballoc = 0x00ff;
DLSCH_alloc_pdu1.TPC = 0;
DLSCH_alloc_pdu1.dai = 0;
DLSCH_alloc_pdu1.harq_pid = 0;
DLSCH_alloc_pdu1.tb_swap = 0;
DLSCH_alloc_pdu1.mcs1 = 0;
DLSCH_alloc_pdu1.ndi1 = 1;
DLSCH_alloc_pdu1.rv1 = 0;
DLSCH_alloc_pdu1.tpmi = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1,sizeof(DCI2_5MHz_2A_M10PRB_TDD_t));
*/
break;
case 7:
DCI_pdu->Num_ue_spec_dci = 1;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0x1235;
DCI_pdu->dci_alloc[0].format = format1;
DCI_pdu->dci_alloc[0].ra_flag = 0;
if (transmission_mode<3) {
//user 1
switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
case 25:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_FDD_t;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
//((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28);
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_5MHz_TDD_t));
/*
//user2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1;
DCI_pdu->dci_alloc[1].ra_flag = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1;
//((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28);
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = 1;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_5MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t));
*/
} else {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_TDD_t;
((DCI1_5MHz_TDD_t *)&dlsch_pdu)->rballoc = rballoc;
((DCI1_5MHz_TDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_5MHz_TDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_5MHz_TDD_t *)&dlsch_pdu)->harq_pid = 0;
((DCI1_5MHz_TDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
//((DCI1_5MHz_TDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28);
((DCI1_5MHz_TDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1_5MHz_TDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_5MHz_TDD_t));
/*
//user2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1;
DCI_pdu->dci_alloc[1].ra_flag = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1;
//((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28);
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = 1;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_5MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t));
*/
}
break;
case 50:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_10MHz_FDD_t;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->harq_pid = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
//((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28);
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_10MHz_TDD_t));
/*
//user2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_10MHz_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1;
DCI_pdu->dci_alloc[1].ra_flag = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1;
//((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28);
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->ndi = 1;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_10MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_10MHz_TDD_t));
*/
} else {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_10MHz_TDD_t;
((DCI1_10MHz_TDD_t *)&dlsch_pdu)->rballoc = rballoc;
((DCI1_10MHz_TDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_10MHz_TDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_10MHz_TDD_t *)&dlsch_pdu)->harq_pid = 0;
((DCI1_10MHz_TDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
//((DCI1_10MHz_TDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28);
((DCI1_10MHz_TDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1_10MHz_TDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_10MHz_TDD_t));
/*
//user2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_10MHz_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1;
DCI_pdu->dci_alloc[1].ra_flag = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1;
//((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28);
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->ndi = 1;
((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_10MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_10MHz_TDD_t));
*/
}
break;
case 100:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_FDD_t;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
//((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28);
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_5MHz_TDD_t));
/*
//user2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1;
DCI_pdu->dci_alloc[1].ra_flag = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1;
//((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28);
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = 1;
((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_5MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t));
*/
} else {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_20MHz_TDD_t;
((DCI1_20MHz_TDD_t *)&dlsch_pdu)->rballoc = rballoc;
((DCI1_20MHz_TDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_20MHz_TDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_20MHz_TDD_t *)&dlsch_pdu)->harq_pid = 0;
((DCI1_20MHz_TDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
//((DCI1_20MHz_TDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28);
((DCI1_20MHz_TDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
((DCI1_20MHz_TDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_20MHz_TDD_t));
/*
//user2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_20MHz_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1;
DCI_pdu->dci_alloc[1].ra_flag = 0;
((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2;
((DCI1_20MHz_FDD_t *)&dlsch_pdu)->TPC = 0;
((DCI1_20MHz_FDD_t *)&dlsch_pdu)->dai = 0;
((DCI1_20MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1;
//((DCI1_20MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28);
((DCI1_20MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs;
((DCI1_20MHz_FDD_t *)&dlsch_pdu)->ndi = 1;
((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_20MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t));
*/
}
break;
}
} else if (transmission_mode==5) {
DCI_pdu->Num_ue_spec_dci = 2;
// user 1
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
DCI_pdu->dci_alloc[0].L = 3;
DCI_pdu->dci_alloc[0].rnti = 0x1235;
DCI_pdu->dci_alloc[0].format = format1E_2A_M10PRB;
DCI_pdu->dci_alloc[0].ra_flag = 0;
DLSCH_alloc_pdu1E.tpmi = 5; //5=use feedback
DLSCH_alloc_pdu1E.rv = 0;
DLSCH_alloc_pdu1E.ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
//DLSCH_alloc_pdu1E.mcs = cqi_to_mcs[phy_vars_eNB->eNB_UE_stats->DL_cqi[0]];
//DLSCH_alloc_pdu1E.mcs = (unsigned char) (taus()%28);
DLSCH_alloc_pdu1E.mcs = openair_daq_vars.target_ue_dl_mcs;
//DLSCH_alloc_pdu1E.mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28);
phy_vars_eNB->eNB_UE_stats[0].dlsch_mcs1 = DLSCH_alloc_pdu1E.mcs;
DLSCH_alloc_pdu1E.harq_pid = 0;
DLSCH_alloc_pdu1E.dai = 0;
DLSCH_alloc_pdu1E.TPC = 0;
DLSCH_alloc_pdu1E.rballoc = openair_daq_vars.ue_dl_rb_alloc;
DLSCH_alloc_pdu1E.rah = 0;
DLSCH_alloc_pdu1E.dl_power_off = 0; //0=second user present
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
//user 2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
DCI_pdu->dci_alloc[1].L = 0;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1E_2A_M10PRB;
DCI_pdu->dci_alloc[1].ra_flag = 0;
//DLSCH_alloc_pdu1E.mcs = openair_daq_vars.target_ue_dl_mcs;
//DLSCH_alloc_pdu1E.mcs = (unsigned char) (taus()%28);
//DLSCH_alloc_pdu1E.mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28);
DLSCH_alloc_pdu1E.mcs = (unsigned char) (((phy_vars_eNB->proc[sched_subframe].frame_tx%1024)/3)%28);
phy_vars_eNB->eNB_UE_stats[1].dlsch_mcs1 = DLSCH_alloc_pdu1E.mcs;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
// set the precoder of the second UE orthogonal to the first
phy_vars_eNB->eNB_UE_stats[1].DL_pmi_single = (phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single ^ 0x1555);
}
break;
/*
case 8:
DCI_pdu->Num_common_dci = 1;
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0xbeef;
DCI_pdu->dci_alloc[0].format = format1A;
DCI_pdu->dci_alloc[0].ra_flag = 1;
RA_alloc_pdu.type = 1;
RA_alloc_pdu.vrb_type = 0;
RA_alloc_pdu.rballoc = computeRIV(25,12,3);
RA_alloc_pdu.ndi = 1;
RA_alloc_pdu.rv = 1;
RA_alloc_pdu.mcs = 4;
RA_alloc_pdu.harq_pid = 0;
RA_alloc_pdu.TPC = 1;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&RA_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
break;
*/
case 9:
DCI_pdu->Num_ue_spec_dci = 1;
//user 1
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD)
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_FDD_t ;
else
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0x1235;
DCI_pdu->dci_alloc[0].format = format0;
DCI_pdu->dci_alloc[0].ra_flag = 0;
UL_alloc_pdu.type = 0;
UL_alloc_pdu.hopping = 0;
UL_alloc_pdu.rballoc = computeRIV(25,2,openair_daq_vars.ue_ul_nb_rb);
UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs;
UL_alloc_pdu.ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
UL_alloc_pdu.TPC = 0;
UL_alloc_pdu.cshift = 0;
UL_alloc_pdu.dai = 0;
UL_alloc_pdu.cqi_req = 1;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
// user 2
/*
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format0;
DCI_pdu->dci_alloc[1].ra_flag = 0;
UL_alloc_pdu.type = 0;
UL_alloc_pdu.hopping = 0;
if (cooperation_flag==0)
UL_alloc_pdu.rballoc = computeRIV(25,2+openair_daq_vars.ue_ul_nb_rb,openair_daq_vars.ue_ul_nb_rb);
else
UL_alloc_pdu.rballoc = computeRIV(25,0,openair_daq_vars.ue_ul_nb_rb);
UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs;
UL_alloc_pdu.ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1;
UL_alloc_pdu.TPC = 0;
if ((cooperation_flag==0) || (cooperation_flag==1))
UL_alloc_pdu.cshift = 0;
else
UL_alloc_pdu.cshift = 1;
UL_alloc_pdu.dai = 0;
UL_alloc_pdu.cqi_req = 1;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
*/
break;
default:
break;
}
DCI_pdu->nCCE = 0;
for (i=0; iNum_common_dci+DCI_pdu->Num_ue_spec_dci; i++) {
DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L));
}
}
#ifdef EMOS
void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *phy_vars_eNB)
{
int i;
uint8_t cooperation_flag = phy_vars_eNB->cooperation_flag;
uint8_t transmission_mode = phy_vars_eNB->transmission_mode[0];
//uint32_t rballoc = 0x00F0;
//uint32_t rballoc2 = 0x000F;
/*
uint32_t rand = taus();
if ((subframe==8) || (subframe==9) || (subframe==0))
rand = (rand%5)+5;
else
rand = (rand%4)+5;
*/
DCI_pdu->Num_common_dci = 0;
DCI_pdu->Num_ue_spec_dci=0;
switch (subframe) {
case 5:
DCI_pdu->Num_ue_spec_dci = 1;
if (transmission_mode<3) {
//user 1
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_TDD_t;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0x1235;
DCI_pdu->dci_alloc[0].format = format1;
DCI_pdu->dci_alloc[0].ra_flag = 0;
DLSCH_alloc_pdu.rballoc = openair_daq_vars.ue_dl_rb_alloc;
DLSCH_alloc_pdu.TPC = 0;
DLSCH_alloc_pdu.dai = 0;
DLSCH_alloc_pdu.harq_pid = 1;
DLSCH_alloc_pdu.mcs = openair_daq_vars.target_ue_dl_mcs;
DLSCH_alloc_pdu.ndi = 1;
DLSCH_alloc_pdu.rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t));
/*
//user2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1;
DCI_pdu->dci_alloc[1].ra_flag = 0;
DLSCH_alloc_pdu.rballoc = rballoc2;
DLSCH_alloc_pdu.TPC = 0;
DLSCH_alloc_pdu.dai = 0;
DLSCH_alloc_pdu.harq_pid = 1;
DLSCH_alloc_pdu.mcs = openair_daq_vars.target_ue_dl_mcs;
DLSCH_alloc_pdu.ndi = 1;
DLSCH_alloc_pdu.rv = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t));
*/
} else if (transmission_mode==5) {
DCI_pdu->Num_ue_spec_dci = 2;
// user 1
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0x1235;
DCI_pdu->dci_alloc[0].format = format1E_2A_M10PRB;
DCI_pdu->dci_alloc[0].ra_flag = 0;
DLSCH_alloc_pdu1E.tpmi = 5; //5=use feedback
DLSCH_alloc_pdu1E.rv = 0;
DLSCH_alloc_pdu1E.ndi = 1;
DLSCH_alloc_pdu1E.mcs = openair_daq_vars.target_ue_dl_mcs;
DLSCH_alloc_pdu1E.harq_pid = 1;
DLSCH_alloc_pdu1E.dai = 0;
DLSCH_alloc_pdu1E.TPC = 0;
DLSCH_alloc_pdu1E.rballoc = openair_daq_vars.ue_dl_rb_alloc;
DLSCH_alloc_pdu1E.rah = 0;
DLSCH_alloc_pdu1E.dl_power_off = 0; //0=second user present
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
//user 2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format1E_2A_M10PRB;
DCI_pdu->dci_alloc[1].ra_flag = 0;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
// set the precoder of the second UE orthogonal to the first
phy_vars_eNB->eNB_UE_stats[1].DL_pmi_single = (phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single ^ 0x1555);
}
break;
case 7:
DCI_pdu->Num_common_dci = 1;
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0xbeef;
DCI_pdu->dci_alloc[0].format = format1A;
DCI_pdu->dci_alloc[0].ra_flag = 1;
RA_alloc_pdu.type = 1;
RA_alloc_pdu.vrb_type = 0;
RA_alloc_pdu.rballoc = computeRIV(25,12,3);
RA_alloc_pdu.ndi = 1;
RA_alloc_pdu.rv = 1;
RA_alloc_pdu.mcs = 4;
RA_alloc_pdu.harq_pid = 0;
RA_alloc_pdu.TPC = 1;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&RA_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
break;
case 9:
DCI_pdu->Num_ue_spec_dci = 1;
//user 1
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
DCI_pdu->dci_alloc[0].L = 2;
DCI_pdu->dci_alloc[0].rnti = 0x1235;
DCI_pdu->dci_alloc[0].format = format0;
DCI_pdu->dci_alloc[0].ra_flag = 0;
UL_alloc_pdu.type = 0;
UL_alloc_pdu.hopping = 0;
UL_alloc_pdu.rballoc = computeRIV(25,0,openair_daq_vars.ue_ul_nb_rb);
UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs;
UL_alloc_pdu.ndi = 1;
UL_alloc_pdu.TPC = 0;
UL_alloc_pdu.cshift = 0;
UL_alloc_pdu.dai = 0;
UL_alloc_pdu.cqi_req = 1;
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
/*
//user 2
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
DCI_pdu->dci_alloc[1].L = 2;
DCI_pdu->dci_alloc[1].rnti = 0x1236;
DCI_pdu->dci_alloc[1].format = format0;
DCI_pdu->dci_alloc[1].ra_flag = 0;
UL_alloc_pdu.type = 0;
UL_alloc_pdu.hopping = 0;
if (cooperation_flag==0)
UL_alloc_pdu.rballoc = computeRIV(25,2+openair_daq_vars.ue_ul_nb_rb,openair_daq_vars.ue_ul_nb_rb);
else
UL_alloc_pdu.rballoc = computeRIV(25,0,openair_daq_vars.ue_ul_nb_rb);
UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs;
UL_alloc_pdu.ndi = 1;
UL_alloc_pdu.TPC = 0;
if ((cooperation_flag==0) || (cooperation_flag==1))
UL_alloc_pdu.cshift = 0;
else
UL_alloc_pdu.cshift = 1;
UL_alloc_pdu.dai = 0;
UL_alloc_pdu.cqi_req = 1;
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
*/
break;
default:
break;
}
DCI_pdu->nCCE = 0;
for (i=0; iNum_common_dci+DCI_pdu->Num_ue_spec_dci; i++) {
DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L));
}
}
#endif //EMOS
#endif //OPENAIR2
#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
int QPSK[4]= {AMP_OVER_SQRT2|(AMP_OVER_SQRT2<<16),AMP_OVER_SQRT2|((65536-AMP_OVER_SQRT2)<<16),((65536-AMP_OVER_SQRT2)<<16)|AMP_OVER_SQRT2,((65536-AMP_OVER_SQRT2)<<16)|(65536-AMP_OVER_SQRT2)};
int QPSK2[4]= {AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),((65536-AMP_OVER_2)<<16)|AMP_OVER_2,((65536-AMP_OVER_2)<<16)|(65536-AMP_OVER_2)};
#if defined(ENABLE_ITTI)
# if ENABLE_RAL
extern PHY_MEASUREMENTS PHY_measurements;
void phy_eNB_lte_measurement_thresholds_test_and_report(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP, uint16_t valP)
{
MessageDef *message_p = NULL;
if (
(
((threshold_phy_pP->threshold.threshold_val < valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_ABOVE_THRESHOLD)) ||
((threshold_phy_pP->threshold.threshold_val > valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_BELOW_THRESHOLD))
) ||
(threshold_phy_pP->threshold.threshold_xdir == RAL_NO_THRESHOLD)
) {
message_p = itti_alloc_new_message(TASK_PHY_ENB , PHY_MEAS_REPORT_IND);
memset(&PHY_MEAS_REPORT_IND(message_p), 0, sizeof(PHY_MEAS_REPORT_IND(message_p)));
memcpy(&PHY_MEAS_REPORT_IND (message_p).threshold,
&threshold_phy_pP->threshold,
sizeof(PHY_MEAS_REPORT_IND (message_p).threshold));
memcpy(&PHY_MEAS_REPORT_IND (message_p).link_param,
&threshold_phy_pP->link_param,
sizeof(PHY_MEAS_REPORT_IND (message_p).link_param));
\
switch (threshold_phy_pP->link_param.choice) {
case RAL_LINK_PARAM_CHOICE_LINK_PARAM_VAL:
PHY_MEAS_REPORT_IND (message_p).link_param._union.link_param_val = valP;
break;
case RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL:
//PHY_MEAS_REPORT_IND (message_p).link_param._union.qos_param_val.
AssertFatal (1 == 0, "TO DO RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL\n");
break;
}
itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p);
}
}
void phy_eNB_lte_check_measurement_thresholds(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP)
{
unsigned int mod_id;
mod_id = instanceP;
switch (threshold_phy_pP->link_param.link_param_type.choice) {
case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) {
case RAL_LINK_PARAM_GEN_DATA_RATE:
phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
break;
case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH:
phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
break;
case RAL_LINK_PARAM_GEN_SINR:
phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
break;
case RAL_LINK_PARAM_GEN_THROUGHPUT:
break;
case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE:
break;
default:
;
}
break;
case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) {
case RAL_LINK_PARAM_LTE_UE_RSRP:
break;
case RAL_LINK_PARAM_LTE_UE_RSRQ:
break;
case RAL_LINK_PARAM_LTE_UE_CQI:
break;
case RAL_LINK_PARAM_LTE_AVAILABLE_BW:
break;
case RAL_LINK_PARAM_LTE_PACKET_DELAY:
break;
case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE:
break;
case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS:
break;
case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES:
break;
case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY:
break;
case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY:
break;
case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS:
break;
case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW:
break;
default:
;
}
break;
default:
;
}
}
# endif
#endif
void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,
relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn)
{
UNUSED(phy_vars_rn);
uint8_t *pbch_pdu=&phy_vars_eNB->pbch_pdu[0];
uint16_t input_buffer_length, re_allocated=0;
uint32_t i,aa;
uint8_t harq_pid;
DCI_PDU *DCI_pdu;
uint8_t *DLSCH_pdu=NULL;
#ifndef OPENAIR2
DCI_PDU DCI_pdu_tmp;
uint8_t DLSCH_pdu_tmp[768*8];
#endif
int8_t UE_id;
uint8_t num_pdcch_symbols=0;
uint8_t ul_subframe;
uint32_t ul_frame;
#ifdef Rel10
MCH_PDU *mch_pduP;
MCH_PDU mch_pdu;
// uint8_t sync_area=255;
#endif
#if defined(SMBV) && !defined(EXMIMO)
// counts number of allocations in subframe
// there is at least one allocation for PDCCH
uint8_t smbv_alloc_cnt = 1;
#endif
int frame = phy_vars_eNB->proc[sched_subframe].frame_tx;
int subframe = phy_vars_eNB->proc[sched_subframe].subframe_tx;
printf("PHY TX f/sf %d/%d sched_sf %d\n", frame, subframe, sched_subframe);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,1);
start_meas(&phy_vars_eNB->phy_proc_tx);
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[%s %"PRIu8"] Frame %d subframe %d : Doing phy_procedures_eNB_TX\n",
(r_type == multicast_relay) ? "RN/eNB" : "eNB",
phy_vars_eNB->Mod_id, frame, subframe);
#endif
for (i=0; ieNB_UE_stats[i].ulsch_consecutive_errors == ULSCH_max_consecutive_errors) {
LOG_W(PHY,"[eNB %d, CC %d] frame %d, subframe %d, UE %d: ULSCH consecutive error count reached %u, removing UE\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->CC_id,frame,subframe, i, phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors);
phy_vars_eNB->eNB_UE_stats[i].mode = PRACH;
remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag);
phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;
}
//#endif
}
#ifdef OPENAIR2
// Get scheduling info for next subframe
if (phy_vars_eNB->CC_id == 0)
mac_xface->eNB_dlsch_ulsch_scheduler(phy_vars_eNB->Mod_id,0,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);//,1);
#endif
if (abstraction_flag==0) {
// clear the transmit data array for the current subframe
for (aa=0; aalte_frame_parms.nb_antennas_tx_eNB; aa++) {
memset(&phy_vars_eNB->lte_eNB_common_vars.txdataF[0][aa][subframe*phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti)],
0,phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti)*sizeof(mod_sym_t));
}
}
if (is_pmch_subframe(phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,&phy_vars_eNB->lte_frame_parms)) {
if (abstraction_flag==0) {
// This is DL-Cell spec pilots in Control region
generate_pilots_slot(phy_vars_eNB,
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
subframe<<1,1);
}
#ifdef Rel10
// if mcch is active, send regardless of the node type: eNB or RN
// when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing
mch_pduP = mac_xface->get_mch_sdu(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,
subframe);
switch (r_type) {
case no_relay:
if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0
LOG_I(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->mcs,
phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3);
else {
LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->sync_area,
(mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment");
mch_pduP = NULL;
}
break;
case multicast_relay:
if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) {
LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
phy_vars_rn->Mod_id,phy_vars_rn->frame, subframe,
mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);
} else if (phy_vars_rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8
mch_pduP= &mch_pdu;
memcpy(&mch_pduP->payload, // could be a simple copy
phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b,
phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
mch_pduP->Pdu_size = (uint16_t) (phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
mch_pduP->mcs = phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs;
LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
phy_vars_rn->Mod_id,phy_vars_rn->frame, subframe,subframe%5,
phy_vars_rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size);
} else {
/* LOG_I(PHY,"[RN %d] Frame %d subframe %d: do not forward MCH pdu for MBSFN sync area %d (MCS %d, TBS %d)\n",
phy_vars_rn->Mod_id,phy_vars_rn->frame, next_slot>>1,
mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);*/
mch_pduP=NULL;
}
phy_vars_rn->mch_avtive[subframe]=0;
break;
default:
LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,r_type);
mch_pduP=NULL;
break;
}// switch
if (mch_pduP) {
fill_eNB_dlsch_MCH(phy_vars_eNB,mch_pduP->mcs,1,0, abstraction_flag);
// Generate PMCH
generate_mch(phy_vars_eNB,sched_subframe,(uint8_t*)mch_pduP->payload,abstraction_flag);
#ifdef DEBUG_PHY
for (i=0; iPdu_size; i++)
msg("%2"PRIx8".",(uint8_t)mch_pduP->payload[i]);
msg("\n");
#endif
} else {
LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
}
#endif
}
else {
// this is not a pmch subframe
if (abstraction_flag==0) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
generate_pilots_slot(phy_vars_eNB,
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
subframe<<1,0);
if (subframe_select(&phy_vars_eNB->lte_frame_parms,subframe) == SF_DL)
generate_pilots_slot(phy_vars_eNB,
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
(subframe<<1)+1,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0);
// First half of PSS/SSS (FDD)
if (subframe == 0) {
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
(phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
0);
generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
(phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4,
0);
}
}
}
}
if (subframe == 0) {
// generate PBCH (Physical Broadcast CHannel) info
if ((phy_vars_eNB->proc[sched_subframe].frame_tx&3) == 0) {
pbch_pdu[2] = 0;
// FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
case 6:
pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
break;
case 15:
pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
break;
case 25:
pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
break;
case 50:
pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
break;
case 75:
pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
break;
case 100:
pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
break;
default:
// FIXME if we get here, this should be flagged as an error, right?
pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
break;
}
pbch_pdu[2] = (pbch_pdu[2]&0xef) |
((phy_vars_eNB->lte_frame_parms.phich_config_common.phich_duration << 4)&0x10);
switch (phy_vars_eNB->lte_frame_parms.phich_config_common.phich_resource) {
case oneSixth:
pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
break;
case half:
pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
break;
case one:
pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
break;
case two:
pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
break;
default:
// unreachable
break;
}
pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((phy_vars_eNB->proc[sched_subframe].frame_tx>>8)&0x3);
pbch_pdu[1] = phy_vars_eNB->proc[sched_subframe].frame_tx&0xfc;
pbch_pdu[0] = 0;
}
/// First half of SSS (TDD)
if (abstraction_flag==0) {
if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
(phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
1);
}
}
#ifdef DEBUG_PHY_PROC
uint16_t frame_tx = (((int) (pbch_pdu[2]&0x3))<<8) + ((int) (pbch_pdu[1]&0xfc)) + phy_vars_eNB->proc[sched_subframe].frame_tx%4;
LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Generating PBCH, mode1_flag=%"PRIu8", frame_tx=%"PRIu16", pdu=%02"PRIx8"%02"PRIx8"%02"PRIx8"\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,
subframe,
phy_vars_eNB->lte_frame_parms.mode1_flag,
frame_tx,
pbch_pdu[2],
pbch_pdu[1],
pbch_pdu[0]);
#endif
if (abstraction_flag==0) {
generate_pbch(&phy_vars_eNB->lte_eNB_pbch,
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
pbch_pdu,
phy_vars_eNB->proc[sched_subframe].frame_tx&3);
}
#ifdef PHY_ABSTRACTION
else {
generate_pbch_emul(phy_vars_eNB,pbch_pdu);
}
#endif
}
if (subframe == 1) {
if (abstraction_flag==0) {
if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
// printf("Generating PSS (frame %d, subframe %d)\n",phy_vars_eNB->proc[sched_subframe].frame_tx,next_slot>>1);
generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
2,
2);
}
}
}
// Second half of PSS/SSS (FDD)
if (subframe == 5) {
if (abstraction_flag==0) {
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
(phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
10);
generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
(phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4,
10);
}
}
}
// Second-half of SSS (TDD)
if (subframe == 5) {
if (abstraction_flag==0) {
if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
(phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
11);
}
}
}
// Second half of PSS (TDD)
if (subframe == 6) {
if (abstraction_flag==0) {
if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) {
// printf("Generating PSS (frame %d, subframe %d)\n",phy_vars_eNB->proc[sched_subframe].frame_tx,next_slot>>1);
generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
&phy_vars_eNB->lte_frame_parms,
2,
12);
}
}
}
// sect_id=0;
#if defined(SMBV) && !defined(EXMIMO)
// PBCH takes one allocation
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
if (subframe==0)
smbv_alloc_cnt++;
}
#endif
#ifdef OPENAIR2
// Parse DCI received from MAC
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1);
DCI_pdu = mac_xface->get_dci_sdu(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,
subframe);
#else
DCI_pdu = &DCI_pdu_tmp;
#ifdef EMOS
/*
if (((phy_vars_eNB->proc[sched_subframe].frame_tx%1024)%3 == 0) && (next_slot == 0)) {
//openair_daq_vars.target_ue_dl_mcs = (openair_daq_vars.target_ue_dl_mcs+1)%28;
openair_daq_vars.target_ue_dl_mcs = taus()%28;
LOG_D(PHY,"[MYEMOS] frame %d, increasing MCS to %d\n",phy_vars_eNB->proc[sched_subframe].frame_tx,openair_daq_vars.target_ue_dl_mcs);
}
*/
/*
if (phy_vars_eNB->proc[sched_subframe].frame_tx > 28000) {
LOG_E(PHY,"More that 28000 frames reached! Exiting!\n");
}
*/
#endif
#ifdef EMOS_CHANNEL
fill_dci_emos(DCI_pdu,sched_subframe,phy_vars_eNB);
#else
fill_dci(DCI_pdu,sched_subframe,phy_vars_eNB);
#endif
#endif
// clear existing ulsch dci allocations before applying info from MAC (this is table
ul_subframe = pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe);
ul_frame = pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
if ((subframe_select(&phy_vars_eNB->lte_frame_parms,ul_subframe)==SF_UL) ||
(phy_vars_eNB->lte_frame_parms.frame_type == FDD)) {
harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,ul_frame,ul_subframe);
for (i=0; iulsch_eNB[i]) {
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc=0;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc=0;
}
}
#ifdef EMOS
//emos_dump_eNB.dci_cnt[next_slot>>1] = DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci; //nb_dci_common+nb_dci_ue_spec;
#endif
// clear previous allocation information for all UEs
for (i=0; idlsch_eNB[i][0]->subframe_tx[subframe] = 0;
}
// init_nCCE_table();
num_pdcch_symbols = DCI_pdu->num_pdcch_symbols;
/*get_num_pdcch_symbols(DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci,
DCI_pdu->dci_alloc,
&phy_vars_eNB->lte_frame_parms,
subframe);*/
/*
DCI_pdu->nCCE = get_nCCE(num_pdcch_symbols,
&phy_vars_eNB->lte_frame_parms,
get_mi(&phy_vars_eNB->lte_frame_parms,subframe));*/
LOG_D(PHY,"num_pdcch_symbols %"PRIu8", nCCE %u (dci commond %"PRIu8", dci uespec %"PRIu8"\n",num_pdcch_symbols,DCI_pdu->nCCE,
DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);
#if defined(SMBV) && !defined(EXMIMO)
// Sets up PDCCH and DCI table
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4) && ((DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci)>0)) {
msg("[SMBV] Frame %3d, SF %d PDCCH, number of DCIs %d\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[0]);
smbv_configure_pdcch(smbv_fname,(smbv_frame_cnt*10) + (subframe),num_pdcch_symbols,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
}
#endif
for (i=0; iNum_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
LOG_D(PHY,"[eNB] Subframe %d: DCI %d/%d : rnti %x, CCEind %d\n",subframe,i,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,DCI_pdu->dci_alloc[i].rnti,DCI_pdu->dci_alloc[i].firstCCE);
#ifdef DEBUG_PHY_PROC
if (DCI_pdu->dci_alloc[i].rnti != SI_RNTI) {
LOG_D(PHY,"[eNB] Subframe %d : Doing DCI index %"PRIu32"/%d\n",subframe,i,DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci);
dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]);
}
#endif
if (DCI_pdu->dci_alloc[i].rnti == SI_RNTI) {
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"] SI generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id);
#endif
generate_eNB_dlsch_params_from_dci(frame,
subframe,
&DCI_pdu->dci_alloc[i].dci_pdu[0],
DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].format,
&phy_vars_eNB->dlsch_eNB_SI,
&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->pdsch_config_dedicated,
SI_RNTI,
0,
P_RNTI,
phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single);
phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE;
LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI) => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe],DCI_pdu->nCCE);
#if defined(SMBV) && !defined(EXMIMO)
// configure SI DCI
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i);
smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "SI", &DCI_pdu->dci_alloc[i], i);
}
#endif
} else if (DCI_pdu->dci_alloc[i].ra_flag == 1) {
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"] RA generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id);
#endif
generate_eNB_dlsch_params_from_dci(frame,
subframe,
&DCI_pdu->dci_alloc[i].dci_pdu[0],
DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].format,
&phy_vars_eNB->dlsch_eNB_ra,
&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->pdsch_config_dedicated,
SI_RNTI,
DCI_pdu->dci_alloc[i].rnti,
P_RNTI,
phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single);
// mac_xface->macphy_exit("Transmitted RAR, exiting\n");
phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE;
LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA) => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe],DCI_pdu->nCCE);
#if defined(SMBV) && !defined(EXMIMO)
// configure RA DCI
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i);
smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "RA", &DCI_pdu->dci_alloc[i], i);
}
#endif
}
else if (DCI_pdu->dci_alloc[i].format != format0) { // this is a normal DLSCH allocation
#ifdef OPENAIR2
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB] Searching for RNTI %"PRIx16"\n",DCI_pdu->dci_alloc[i].rnti);
#endif
UE_id = find_ue((int16_t)DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB);
#else
UE_id = i;
#endif
if (UE_id>=0) {
// dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]);
#if defined(SMBV) && !defined(EXMIMO)
// Configure this user
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, SF %d (SMBV SF %d) Configuring user %d with RNTI %"PRIu16" in TM%"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1,
DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->transmission_mode[(uint8_t)UE_id]);
smbv_configure_user(smbv_fname,UE_id+1,phy_vars_eNB->transmission_mode[(uint8_t)UE_id],DCI_pdu->dci_alloc[i].rnti);
}
#endif
generate_eNB_dlsch_params_from_dci(frame,
subframe,
&DCI_pdu->dci_alloc[i].dci_pdu[0],
DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].format,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id],
&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->pdsch_config_dedicated,
SI_RNTI,
0,
P_RNTI,
phy_vars_eNB->eNB_UE_stats[(uint8_t)UE_id].DL_pmi_single);
LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
phy_vars_eNB->Mod_id,DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE;
LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16") => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe],DCI_pdu->nCCE);
#if defined(SMBV) && !defined(EXMIMO)
// configure UE-spec DCI
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i);
smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i);
}
#endif
#ifdef DEBUG_PHY_PROC
//if (phy_vars_eNB->proc[sched_subframe].frame_tx%100 == 0)
LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n",
phy_vars_eNB->Mod_id, DCI_pdu->dci_alloc[i].rnti,
phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,UE_id,
DCI_pdu->dci_alloc[i].format,
1<dci_alloc[i].L);
#endif
} else {
LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti);
}
}
}
// Apply physicalConfigDedicated if needed
phy_config_dedicated_eNB_step2(phy_vars_eNB);
for (i=0; iNum_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
if (DCI_pdu->dci_alloc[i].format == format0) { // this is a ULSCH allocation
harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,
pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe));
if (harq_pid==255) {
LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx);
//mac_exit_wrapper("Invalid harq_pid (255) detected");
return; // not reached
}
#ifdef OPENAIR2
UE_id = find_ue((int16_t)DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB);
#else
UE_id = i;
#endif
if (UE_id<0) {
LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Unknown UE_id for rnti %"PRIx16"\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti);
mac_exit_wrapper("Invalid UE id (< 0) detected");
return; // not reached
}
#ifdef DEBUG_PHY_PROC
//if (phy_vars_eNB->proc[sched_subframe].frame_tx%100 == 0)
LOG_D(PHY,
"[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8") (DCI pos %"PRIu32"/%d), aggregation %d\n",
phy_vars_eNB->Mod_id,
subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,
pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe)),
phy_vars_eNB->proc[sched_subframe].frame_tx,
subframe,
pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe),
DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].dci_pdu[0],
i,
DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci,
1<dci_alloc[i].L);
#endif
//dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]);
//LOG_D(PHY,"[eNB] cba generate_eNB_ulsch_params_from_dci for ue %d for dci rnti %x\n", UE_id, DCI_pdu->dci_alloc[i].rnti);
generate_eNB_ulsch_params_from_dci(&DCI_pdu->dci_alloc[i].dci_pdu[0],
DCI_pdu->dci_alloc[i].rnti,
sched_subframe,
format0,
UE_id,
phy_vars_eNB,
SI_RNTI,
0,
P_RNTI,
CBA_RNTI,
0); // do_srs
LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d/%u\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].firstCCE,DCI_pdu->nCCE);
#if defined(SMBV) && !defined(EXMIMO)
// configure UE-spec DCI for UL Grant
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i);
smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i);
}
#endif
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"][PUSCH %"PRIu8"] frame %d subframe %d Setting subframe_scheduling_flag for UE %"PRIu32" harq_pid %"PRIu8" (ul subframe %"PRIu8")\n",
phy_vars_eNB->Mod_id,harq_pid,
phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i,harq_pid,
pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe));
#endif
if ((DCI_pdu->dci_alloc[i].rnti >= CBA_RNTI) && (DCI_pdu->dci_alloc[i].rnti < P_RNTI))
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
else
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
}
}
// if we have DCI to generate do it now
if ((DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci)>0) {
} else { // for emulation!!
phy_vars_eNB->num_ue_spec_dci[(subframe)&1]=0;
phy_vars_eNB->num_common_dci[(subframe)&1]=0;
}
if (abstraction_flag == 0) {
//#ifdef DEBUG_PHY_PROC
if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0)
LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (common %"PRIu8",ue_spec %"PRIu8")\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,
DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);
//#endif
// for (sect_id=0;sect_idNum_ue_spec_dci,
DCI_pdu->Num_common_dci,
DCI_pdu->dci_alloc,
0,
AMP,
&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
subframe
#if FAPI
, DCI_pdu->num_pdcch_symbols
#endif
);
#ifdef DEBUG_PHY_PROC
// LOG_I(PHY,"[eNB %d] Frame %d, subframe %d: num_pdcch_symbols %d)\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot>>1,num_pdcch_symbols);
#endif
}
#ifdef PHY_ABSTRACTION // FIXME this ifdef seems suspicious
else {
LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top_emul\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe);
num_pdcch_symbols = generate_dci_top_emul(phy_vars_eNB,DCI_pdu->Num_ue_spec_dci,DCI_pdu->Num_common_dci,DCI_pdu->dci_alloc,subframe
#if FAPI
, DCI_pdu->num_pdcch_symbols
#endif
);
}
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0);
#ifdef DEBUG_PHY_PROC
//LOG_D(PHY,"[eNB %d] Frame %d, slot %d: num_pdcch_symbols=%d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot,num_pdcch_symbols);
#endif
// Check for SI activity
if (phy_vars_eNB->dlsch_eNB_SI->active == 1) {
input_buffer_length = phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->TBS/8;
#ifdef OPENAIR2
DLSCH_pdu = mac_xface->get_dlsch_sdu(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,
SI_RNTI,
0);
#else
DLSCH_pdu = DLSCH_pdu_tmp;
for (i=0; iproc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, Configuring SI payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), DLSCH_pdu, input_buffer_length);
}
#endif
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
//FIXME: The code below is commented as next_slot is not defined which results in failed compilation
/*
LOG_D(PHY,"[eNB %"PRIu8"][SI] Frame %d, slot %d: Calling generate_dlsch (SI) with input size = %"PRIu16", num_pdcch_symbols %"PRIu8"\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot, input_buffer_length,num_pdcch_symbols); // FIXME this code is broken (next_slot?)
for (i=0; idlsch_encoding_stats);
dlsch_encoding(DLSCH_pdu,
&phy_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
phy_vars_eNB->dlsch_eNB_SI,
phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
&phy_vars_eNB->dlsch_rate_matching_stats,
&phy_vars_eNB->dlsch_turbo_encoding_stats,
&phy_vars_eNB->dlsch_interleaving_stats);
stop_meas(&phy_vars_eNB->dlsch_encoding_stats);
start_meas(&phy_vars_eNB->dlsch_scrambling_stats);
dlsch_scrambling(&phy_vars_eNB->lte_frame_parms,
0,
phy_vars_eNB->dlsch_eNB_SI,
get_G(&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->nb_rb,
phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->rb_alloc,
get_Qm(phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->mcs),
1,
num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
0,
subframe<<1);
stop_meas(&phy_vars_eNB->dlsch_scrambling_stats);
start_meas(&phy_vars_eNB->dlsch_modulation_stats);
// for (sect_id=0;sect_idlte_eNB_common_vars.txdataF[0],
AMP,
subframe,
&phy_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
phy_vars_eNB->dlsch_eNB_SI,
(LTE_eNB_DLSCH_t *)NULL);
stop_meas(&phy_vars_eNB->dlsch_modulation_stats);
}
#ifdef PHY_ABSTRACTION
else {
start_meas(&phy_vars_eNB->dlsch_encoding_stats);
dlsch_encoding_emul(phy_vars_eNB,
DLSCH_pdu,
phy_vars_eNB->dlsch_eNB_SI);
stop_meas(&phy_vars_eNB->dlsch_encoding_stats);
}
#endif
phy_vars_eNB->dlsch_eNB_SI->active = 0;
}
// Check for RA activity
if (phy_vars_eNB->dlsch_eNB_ra->active == 1) {
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d, subframe %d, RA active, filling RAR:\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe);
#endif
input_buffer_length = phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->TBS/8;
#ifdef OPENAIR2
int16_t crnti = mac_xface->fill_rar(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,
dlsch_input_buffer,
phy_vars_eNB->lte_frame_parms.N_RB_UL,
input_buffer_length);
/*
for (i=0;imacphy_exit("[PHY][eNB] Max user count reached.\n");
mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,
crnti);
} else {
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].mode = RA_RESPONSE;
// Initialize indicator for first SR (to be cleared after ConnectionSetup is acknowledged)
phy_vars_eNB->first_sr[(uint32_t)UE_id] = 1;
generate_eNB_ulsch_params_from_rar(dlsch_input_buffer,
phy_vars_eNB->proc[sched_subframe].frame_tx,
(subframe),
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id],
&phy_vars_eNB->lte_frame_parms);
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 1;
get_Msg3_alloc(&phy_vars_eNB->lte_frame_parms,
subframe,
phy_vars_eNB->proc[sched_subframe].frame_tx,
&phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
&phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
LOG_I(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n",
phy_vars_eNB->proc[sched_subframe].frame_tx,
subframe,
UE_id,
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
#else
for (i=0; ieNB_UE_stats[0].UE_timing_offset)>>(2+4); // 7 MSBs of timing advance + divide by 4
dlsch_input_buffer[2] = ((phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset)<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
//LOG_I(PHY,"UE %d: timing_offset = %d\n",UE_id,phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset);
#endif
#if defined(SMBV) && !defined(EXMIMO)
// Configures the data source of allocation (allocation is configured by DCI)
if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, Configuring RA payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), dlsch_input_buffer, input_buffer_length);
}
#endif
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d, subframe %d: Calling generate_dlsch (RA) with input size = %"PRIu16",Msg3 frame %"PRIu32", Msg3 subframe %"PRIu8"\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,input_buffer_length,
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
#endif
if (abstraction_flag == 0) {
dlsch_encoding(dlsch_input_buffer,
&phy_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
phy_vars_eNB->dlsch_eNB_ra,
phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
&phy_vars_eNB->dlsch_rate_matching_stats,
&phy_vars_eNB->dlsch_turbo_encoding_stats,
&phy_vars_eNB->dlsch_interleaving_stats);
// phy_vars_eNB->dlsch_eNB_ra->rnti = RA_RNTI;
dlsch_scrambling(&phy_vars_eNB->lte_frame_parms,
0,
phy_vars_eNB->dlsch_eNB_ra,
get_G(&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->nb_rb,
phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->rb_alloc,
get_Qm(phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->mcs),
1,
num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
0,
subframe<<1);
// for (sect_id=0;sect_idlte_eNB_common_vars.txdataF[0],
AMP,
subframe,
&phy_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
phy_vars_eNB->dlsch_eNB_ra,
(LTE_eNB_DLSCH_t *)NULL);
}
#ifdef PHY_ABSTRACTION
else {
dlsch_encoding_emul(phy_vars_eNB,
dlsch_input_buffer,
phy_vars_eNB->dlsch_eNB_ra);
}
#endif
LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d subframe %d Deactivating DLSCH RA\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d, DLSCH (RA) re_allocated = %"PRIu16"\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, re_allocated);
#endif
#ifdef OPENAIR2
} //max user count
#endif
phy_vars_eNB->dlsch_eNB_ra->active = 0;
}
// Now scan UE specific DLSCH
for (UE_id=0; UE_iddlsch_eNB[(uint8_t)UE_id][0])&&
(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&&
(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 1)) {
harq_pid = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid;
input_buffer_length = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS/8;
//#ifdef DEBUG_PHY_PROC
LOG_D(PHY,
"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")\n",
phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti,harq_pid,
phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, input_buffer_length,
get_G(&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs,
pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc),
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rvidx,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round);
//#endif
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_TX_MESSAGE(
MSC_PHY_ENB,MSC_PHY_UE,
NULL,0,
"%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")",
phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,
input_buffer_length,
get_G(&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs,
pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc),
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rvidx,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round);
#endif
phy_vars_eNB->eNB_UE_stats[(uint8_t)UE_id].dlsch_sliding_cnt++;
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->harq_processes[harq_pid]->round == 0) {
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].dlsch_trials[harq_pid][0]++;
#ifdef OPENAIR2
DLSCH_pdu = mac_xface->get_dlsch_sdu(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
phy_vars_eNB->proc[sched_subframe].frame_tx,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti,
0);
phy_vars_eNB->eNB_UE_stats[UE_id].total_TBS_MAC += phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS;
#else
DLSCH_pdu = DLSCH_pdu_tmp;
for (i=0; iproc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
msg("[SMBV] Frame %3d, Configuring PDSCH payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
smbv_configure_datalist_for_user(smbv_fname, UE_id+1, DLSCH_pdu, input_buffer_length);
}
#endif
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
LOG_T(PHY,"eNB DLSCH SDU: \n");
for (i=0; idlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS>>3; i++)
LOG_T(PHY,"%"PRIx8".",DLSCH_pdu[i]);
LOG_T(PHY,"\n");
#endif
#endif
} else {
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].dlsch_trials[harq_pid][phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round]++;
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
LOG_D(PHY,"[eNB] This DLSCH is a retransmission\n");
#endif
#endif
}
if (abstraction_flag==0) {
// 36-212
start_meas(&phy_vars_eNB->dlsch_encoding_stats);
dlsch_encoding(DLSCH_pdu,
&phy_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0],
phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
&phy_vars_eNB->dlsch_rate_matching_stats,
&phy_vars_eNB->dlsch_turbo_encoding_stats,
&phy_vars_eNB->dlsch_interleaving_stats);
stop_meas(&phy_vars_eNB->dlsch_encoding_stats);
// 36-211
start_meas(&phy_vars_eNB->dlsch_scrambling_stats);
dlsch_scrambling(&phy_vars_eNB->lte_frame_parms,
0,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0],
get_G(&phy_vars_eNB->lte_frame_parms,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
0,
subframe<<1);
stop_meas(&phy_vars_eNB->dlsch_scrambling_stats);
start_meas(&phy_vars_eNB->dlsch_modulation_stats);
//for (sect_id=0;sect_idtransmission_mode[(uint8_t)UE_id] == 5) &&
(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->dl_power_off == 0))
amp = (int16_t)(((int32_t)AMP*(int32_t)ONE_OVER_SQRT2_Q15)>>15);
else*/
// amp = AMP;
// if (UE_id == 1)
// LOG_I(PHY,"[MYEMOS] MCS_i %d\n", phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs);
re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
subframe,
&phy_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0],
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][1]);
stop_meas(&phy_vars_eNB->dlsch_modulation_stats);
}
#ifdef PHY_ABSTRACTION
else {
start_meas(&phy_vars_eNB->dlsch_encoding_stats);
dlsch_encoding_emul(phy_vars_eNB,
DLSCH_pdu,
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]);
stop_meas(&phy_vars_eNB->dlsch_encoding_stats);
}
#endif
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active = 0;
//mac_xface->macphy_exit("first dlsch transmitted\n");
}
else if ((phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0])&&
(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&&
(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 0)) {
// clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->subframe_tx[subframe]=0;
#ifdef DEBUG_PHY_PROC
//LOG_D(PHY,"[eNB %d] DCI: Clearing subframe_tx for subframe %d, UE %d\n",phy_vars_eNB->Mod_id,subframe,UE_id);
#endif
}
}
// if we have PHICH to generate
// printf("[PHY][eNB] Frame %d subframe %d Checking for phich\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
if (is_phich_subframe(&phy_vars_eNB->lte_frame_parms,subframe))
{
#ifdef DEBUG_PHY_PROC
// LOG_D(PHY,"[eNB %d] Frame %d, subframe %d: Calling generate_phich_top\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe);
#endif
// for (sect_id=0;sect_idofdm_mod_stats);
do_OFDM_mod(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
phy_vars_eNB->lte_eNB_common_vars.txdata[0],
phy_vars_eNB->proc[sched_subframe].frame_tx,subframe<<1,
&phy_vars_eNB->lte_frame_parms);
do_OFDM_mod(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
phy_vars_eNB->lte_eNB_common_vars.txdata[0],
phy_vars_eNB->proc[sched_subframe].frame_tx,1+(subframe<<1),
&phy_vars_eNB->lte_frame_parms);
stop_meas(&phy_vars_eNB->ofdm_mod_stats);
}
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,0);
stop_meas(&phy_vars_eNB->phy_proc_tx);
}
void process_Msg3(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t UE_id, uint8_t harq_pid)
{
// this prepares the demodulation of the first PUSCH of a new user, containing Msg3
int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
LOG_D(PHY,"[eNB %d][RAPROC] frame %d : subframe %d : process_Msg3 UE_id %d (active %d, subframe %d, frame %d)\n",
phy_vars_eNB->Mod_id,
frame,subframe,
UE_id,phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active,
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe,
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame);
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 0;
if ((phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active == 1) &&
(phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe == subframe) &&
(phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame == (uint32_t)frame)) {
// harq_pid = 0;
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 0;
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 1;
phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag=1;
LOG_D(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Setting subframe_scheduling_flag (Msg3) for UE %d\n",
phy_vars_eNB->Mod_id,
frame,subframe,UE_id);
}
}
// This function retrieves the harq_pid of the corresponding DLSCH process
// and updates the error statistics of the DLSCH based on the received ACK
// info from UE along with the round index. It also performs the fine-grain
// rate-adaptation based on the error statistics derived from the ACK/NAK process
void process_HARQ_feedback(uint8_t UE_id,
uint8_t sched_subframe,
PHY_VARS_eNB *phy_vars_eNB,
uint8_t pusch_flag,
uint8_t *pucch_payload,
uint8_t pucch_sel,
uint8_t SR_payload)
{
uint8_t dl_harq_pid[8],dlsch_ACK[8],dl_subframe;
LTE_eNB_DLSCH_t *dlsch = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0];
LTE_eNB_UE_stats *ue_stats = &phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id];
LTE_DL_eNB_HARQ_t *dlsch_harq_proc;
uint8_t subframe_m4,M,m;
int mp;
int all_ACKed=1,nb_alloc=0,nb_ACK=0;
int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
int harq_pid = subframe2harq_pid( &phy_vars_eNB->lte_frame_parms,frame,subframe);
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { //FDD
subframe_m4 = (subframe<4) ? subframe+6 : subframe-4;
dl_harq_pid[0] = dlsch->harq_ids[subframe_m4];
M=1;
if (pusch_flag == 1) {
dlsch_ACK[0] = phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0];
if (dlsch->subframe_tx[subframe_m4]==1)
LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUSCH for subframe %d\n",phy_vars_eNB->Mod_id,
frame,dlsch_ACK[0],subframe_m4);
}
else {
dlsch_ACK[0] = pucch_payload[0];
LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUCCH for subframe %d\n",phy_vars_eNB->Mod_id,
frame,dlsch_ACK[0],subframe_m4);
/*
if (dlsch_ACK[0]==0)
AssertFatal(0,"Exiting on NAK on PUCCH\n");
*/
}
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_MESSAGE(
MSC_PHY_ENB,MSC_PHY_UE,
NULL,0,
"%05u:%02u %s received %s rnti %x harq id %u tx SF %u",
frame,subframe,
(pusch_flag == 1)?"PUSCH":"PUCCH",
(dlsch_ACK[0])?"ACK":"NACK",
dlsch->rnti,
dl_harq_pid[0],
subframe_m4
);
#endif
} else { // TDD Handle M=1,2 cases only
M=ul_ACK_subframe2_M(&phy_vars_eNB->lte_frame_parms,
subframe);
// Now derive ACK information for TDD
if (pusch_flag == 1) { // Do PUSCH ACK/NAK first
// detect missing DAI
//FK: this code is just a guess
//RK: not exactly, yes if scheduled from PHICH (i.e. no DCI format 0)
// otherwise, it depends on how many of the PDSCH in the set are scheduled, we can leave it like this,
// but we have to adapt the code below. For example, if only one out of 2 are scheduled, only 1 bit o_ACK is used
dlsch_ACK[0] = phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0];
dlsch_ACK[1] = (phy_vars_eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode == bundling)
?phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]:phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[1];
// printf("UE %d: ACK %d,%d\n",UE_id,dlsch_ACK[0],dlsch_ACK[1]);
}
else { // PUCCH ACK/NAK
if ((SR_payload == 1)&&(pucch_sel!=2)) { // decode Table 7.3 if multiplexing and SR=1
nb_ACK = 0;
if (M == 2) {
if ((pucch_payload[0] == 1) && (pucch_payload[1] == 1)) // b[0],b[1]
nb_ACK = 1;
else if ((pucch_payload[0] == 1) && (pucch_payload[1] == 0))
nb_ACK = 2;
} else if (M == 3) {
if ((pucch_payload[0] == 1) && (pucch_payload[1] == 1))
nb_ACK = 1;
else if ((pucch_payload[0] == 1) && (pucch_payload[1] == 0))
nb_ACK = 2;
else if ((pucch_payload[0] == 0) && (pucch_payload[1] == 1))
nb_ACK = 3;
}
} else if (pucch_sel == 2) { // bundling or M=1
// printf("*** (%d,%d)\n",pucch_payload[0],pucch_payload[1]);
dlsch_ACK[0] = pucch_payload[0];
dlsch_ACK[1] = pucch_payload[0];
} else { // multiplexing with no SR, this is table 10.1
if (M==1)
dlsch_ACK[0] = pucch_payload[0];
else if (M==2) {
if (((pucch_sel == 1) && (pucch_payload[0] == 1) && (pucch_payload[1] == 1)) ||
((pucch_sel == 0) && (pucch_payload[0] == 0) && (pucch_payload[1] == 1)))
dlsch_ACK[0] = 1;
else
dlsch_ACK[0] = 0;
if (((pucch_sel == 1) && (pucch_payload[0] == 1) && (pucch_payload[1] == 1)) ||
((pucch_sel == 1) && (pucch_payload[0] == 0) && (pucch_payload[1] == 0)))
dlsch_ACK[1] = 1;
else
dlsch_ACK[1] = 0;
}
}
}
}
// handle case where positive SR was transmitted with multiplexing
if ((SR_payload == 1)&&(pucch_sel!=2)&&(pusch_flag == 0)) {
nb_alloc = 0;
for (m=0; mlte_frame_parms,
subframe,
m);
if (dlsch->subframe_tx[dl_subframe]==1)
nb_alloc++;
}
if (nb_alloc == nb_ACK)
all_ACKed = 1;
else
all_ACKed = 0;
// printf("nb_alloc %d, all_ACKed %d\n",nb_alloc,all_ACKed);
}
for (m=0,mp=-1; mlte_frame_parms,
subframe,
m);
if (dlsch->subframe_tx[dl_subframe]==1) {
if (pusch_flag == 1)
mp++;
else
mp = m;
dl_harq_pid[m] = dlsch->harq_ids[dl_subframe];
if ((pucch_sel != 2)&&(pusch_flag == 0)) { // multiplexing
if ((SR_payload == 1)&&(all_ACKed == 1))
dlsch_ACK[m] = 1;
else
dlsch_ACK[m] = 0;
}
if (dl_harq_pid[m]Mdlharq) {
dlsch_harq_proc = dlsch->harq_processes[dl_harq_pid[m]];
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x/%d] subframe %d, status %d, round %d (mcs %d, rv %d, TBS %d)\n",phy_vars_eNB->Mod_id,
dlsch->rnti,dl_harq_pid[m],dl_subframe,
dlsch_harq_proc->status,dlsch_harq_proc->round,
dlsch->harq_processes[dl_harq_pid[m]]->mcs,
dlsch->harq_processes[dl_harq_pid[m]]->rvidx,
dlsch->harq_processes[dl_harq_pid[m]]->TBS);
if (dlsch_harq_proc->status==DISABLED)
LOG_E(PHY,"dlsch_harq_proc is disabled? \n");
#endif
if ((dl_harq_pid[m]Mdlharq) &&
(dlsch_harq_proc->status == ACTIVE)) {
#if FAPI
/* TODO: handle transport block != 0 */
printf("SEND ack %d harq pid %d rnti %d f/sf %d/%d\n", dlsch_ACK[mp], dl_harq_pid[m], dlsch->rnti, frame, subframe);
mac_xface->fapi_dl_ack_nack(dlsch->rnti, dl_harq_pid[m], 0 /* transport block */, dlsch_ACK[mp]);
#endif
// dl_harq_pid of DLSCH is still active
// msg("[PHY] eNB %d Process %d is active (%d)\n",phy_vars_eNB->Mod_id,dl_harq_pid[m],dlsch_ACK[m]);
if ( dlsch_ACK[mp]==0) {
// Received NAK
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x/%d] M = %d, m= %d, mp=%d NAK Received in round %d, requesting retransmission\n",phy_vars_eNB->Mod_id,
dlsch->rnti,dl_harq_pid[m],M,m,mp,dlsch_harq_proc->round);
#endif
if (dlsch_harq_proc->round == 0)
ue_stats->dlsch_NAK_round0++;
ue_stats->dlsch_NAK[dl_harq_pid[m]][dlsch_harq_proc->round]++;
// then Increment DLSCH round index
dlsch_harq_proc->round++;
if (dlsch_harq_proc->round == dlsch->Mdlharq) {
// This was the last round for DLSCH so reset round and increment l2_error counter
#ifdef DEBUG_PHY_PROC
LOG_W(PHY,"[eNB %d][PDSCH %x/%d] DLSCH retransmissions exhausted, dropping packet\n",phy_vars_eNB->Mod_id,
dlsch->rnti,dl_harq_pid[m]);
#endif
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_EVENT(MSC_PHY_ENB, "0 HARQ DLSCH Failed RNTI %"PRIx16" round %u",
dlsch->rnti,
dlsch_harq_proc->round);
#endif
dlsch_harq_proc->round = 0;
ue_stats->dlsch_l2_errors[dl_harq_pid[m]]++;
dlsch_harq_proc->status = SCH_IDLE;
put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;
}
} else {
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x/%d] ACK Received in round %d, resetting process\n",phy_vars_eNB->Mod_id,
dlsch->rnti,dl_harq_pid[m],dlsch_harq_proc->round);
#endif
ue_stats->dlsch_ACK[dl_harq_pid[m]][dlsch_harq_proc->round]++;
// Received ACK so set round to 0 and set dlsch_harq_pid IDLE
dlsch_harq_proc->round = 0;
dlsch_harq_proc->status = SCH_IDLE;
put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]);
dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq;
ue_stats->total_TBS = ue_stats->total_TBS +
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
/*
ue_stats->total_transmitted_bits = ue_stats->total_transmitted_bits +
phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
*/
}
// Do fine-grain rate-adaptation for DLSCH
if (ue_stats->dlsch_NAK_round0 > dlsch->error_threshold) {
if (ue_stats->dlsch_mcs_offset == 1)
ue_stats->dlsch_mcs_offset=0;
else
ue_stats->dlsch_mcs_offset=-1;
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[process_HARQ_feedback] Frame %d Setting round to %d for pid %d (subframe %d)\n",frame,
dlsch_harq_proc->round,dl_harq_pid[m],subframe);
#endif
// Clear NAK stats and adjust mcs offset
// after measurement window timer expires
if (ue_stats->dlsch_sliding_cnt == dlsch->ra_window_size) {
if ((ue_stats->dlsch_mcs_offset == 0) && (ue_stats->dlsch_NAK_round0 < 2))
ue_stats->dlsch_mcs_offset = 1;
if ((ue_stats->dlsch_mcs_offset == 1) && (ue_stats->dlsch_NAK_round0 > 2))
ue_stats->dlsch_mcs_offset = 0;
if ((ue_stats->dlsch_mcs_offset == 0) && (ue_stats->dlsch_NAK_round0 > 2))
ue_stats->dlsch_mcs_offset = -1;
if ((ue_stats->dlsch_mcs_offset == -1) && (ue_stats->dlsch_NAK_round0 < 2))
ue_stats->dlsch_mcs_offset = 0;
ue_stats->dlsch_NAK_round0 = 0;
ue_stats->dlsch_sliding_cnt = 0;
}
}
}
}
}
}
void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB,
uint8_t UE_id,
uint8_t sched_subframe,
int16_t *n1_pucch0,
int16_t *n1_pucch1,
int16_t *n1_pucch2,
int16_t *n1_pucch3)
{
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->lte_frame_parms;
uint8_t nCCE0,nCCE1;
int sf;
int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
if (frame_parms->frame_type == FDD ) {
sf = (subframe<4) ? (subframe+6) : (subframe-4);
// printf("n1_pucch_eNB: subframe %d, nCCE %d\n",sf,phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[sf]);
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[sf]>0) {
*n1_pucch0 = frame_parms->pucch_config_common.n1PUCCH_AN + phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[sf];
*n1_pucch1 = -1;
} else {
*n1_pucch0 = -1;
*n1_pucch1 = -1;
}
} else {
switch (frame_parms->tdd_config) {
case 1: // DL:S:UL:UL:DL:DL:S:UL:UL:DL
if (subframe == 2) { // ACK subframes 5 and 6
/* if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6];
*n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
}
else
*n1_pucch1 = -1;*/
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5];
*n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch0 = -1;
*n1_pucch1 = -1;
} else if (subframe == 3) { // ACK subframe 9
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9];
*n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch0 = -1;
*n1_pucch1 = -1;
} else if (subframe == 7) { // ACK subframes 0 and 1
//harq_ack[0].nCCE;
//harq_ack[1].nCCE;
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0];
*n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch0 = -1;
*n1_pucch1 = -1;
} else if (subframe == 8) { // ACK subframes 4
//harq_ack[4].nCCE;
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[4]>0) {
nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[4];
*n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch0 = -1;
*n1_pucch1 = -1;
} else {
LOG_D(PHY,"[eNB %d] frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
phy_vars_eNB->Mod_id,
frame,
subframe,frame_parms->tdd_config);
return;
}
break;
case 3: // DL:S:UL:UL:UL:DL:DL:DL:DL:DL
if (subframe == 2) { // ACK subframes 5,6 and 1 (S in frame-2), forget about n-11 for the moment (S-subframe)
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6];
*n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch1 = -1;
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5];
*n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch0 = -1;
} else if (subframe == 3) { // ACK subframes 7 and 8
LOG_D(PHY,"get_n1_pucch_eNB : subframe 3, subframe_tx[7] %d, subframe_tx[8] %d\n",
phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7],phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]);
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]>0) {
nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[8];
*n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
LOG_D(PHY,"nCCE1 %d, n1_pucch1 %d\n",nCCE1,*n1_pucch1);
} else
*n1_pucch1 = -1;
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7]>0) {
nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[7];
*n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
LOG_D(PHY,"nCCE0 %d, n1_pucch0 %d\n",nCCE0,*n1_pucch0);
} else
*n1_pucch0 = -1;
} else if (subframe == 4) { // ACK subframes 9 and 0
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0];
*n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch1 = -1;
if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9];
*n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
} else
*n1_pucch0 = -1;
} else {
LOG_D(PHY,"[eNB %d] Frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
phy_vars_eNB->Mod_id,frame,subframe,frame_parms->tdd_config);
return;
}
break;
} // switch tdd_config
// Don't handle the case M>2
*n1_pucch2 = -1;
*n1_pucch3 = -1;
}
}
void prach_procedures(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t abstraction_flag)
{
uint16_t preamble_energy_list[64],preamble_delay_list[64];
uint16_t preamble_max,preamble_energy_max;
uint16_t i;
int8_t UE_id;
int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
uint8_t CC_id = phy_vars_eNB->CC_id;
memset(&preamble_energy_list[0],0,64*sizeof(uint16_t));
memset(&preamble_delay_list[0],0,64*sizeof(uint16_t));
if (abstraction_flag == 0) {
LOG_D(PHY,"[eNB %d][RAPROC] Frame %d, Subframe %d : PRACH RX Signal Power : %d dBm\n",phy_vars_eNB->Mod_id,
frame,subframe,dB_fixed(signal_energy(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],512)) - phy_vars_eNB->rx_total_gain_eNB_dB);
// LOG_I(PHY,"[eNB %d][RAPROC] PRACH: rootSequenceIndex %d, prach_ConfigIndex %d, zeroCorrelationZoneConfig %d, highSpeedFlag %d, prach_FreqOffset %d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset);
rx_prach(phy_vars_eNB,
subframe,
preamble_energy_list,
preamble_delay_list,
frame,
0);
} else {
for (UE_id=0; UE_idgenerate_prach,
PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.prach_config_common.rootSequenceIndex,
phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex,
PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex);
if ((PHY_vars_UE_g[UE_id][CC_id]->generate_prach==1) &&
(PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.prach_config_common.rootSequenceIndex ==
phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex) ) {
preamble_energy_list[PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex] = 800;
preamble_delay_list[PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex] = 5;
}
}
}
preamble_energy_max = preamble_energy_list[0];
preamble_max = 0;
for (i=1; i<64; i++) {
if (preamble_energy_max < preamble_energy_list[i]) {
preamble_energy_max = preamble_energy_list[i];
preamble_max = i;
}
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[RAPROC] Most likely preamble %d, energy %d dB delay %d\n",
preamble_max,
preamble_energy_list[preamble_max],
preamble_delay_list[preamble_max]);
#endif
if (preamble_energy_list[preamble_max] > 580) {
/*
write_output("prach_ifft0.m","prach_t0",prach_ifft[0],2048,1,1);
write_output("prach_rx0.m","prach_rx0",&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],6144+792,1,1);
write_output("prach_rxF0.m","prach_rxF0",phy_vars_eNB->lte_eNB_prach_vars.rxsigF[0],24576,1,1);
mac_xface->macphy_exit("Exiting for PRACH debug\n");
*/
UE_id = find_next_ue_index(phy_vars_eNB);
if (UE_id>=0) {
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits
//phy_vars_eNb->eNB_UE_stats[(uint32_t)UE_id].mode = PRACH;
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].sector = 0;
LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
subframe,
UE_id,
preamble_max,
preamble_energy_max/10,
preamble_energy_max%10,
preamble_delay_list[preamble_max]);
#ifdef OPENAIR2
uint8_t update_TA=4;
switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
case 6:
update_TA = 16;
break;
case 25:
update_TA = 4;
break;
case 50:
update_TA = 2;
break;
case 100:
update_TA = 1;
break;
}
mac_xface->initiate_ra_proc(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
preamble_max,
preamble_delay_list[preamble_max]*update_TA,
0,subframe,0);
#endif
} else {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 RA Failed add user, too many");
LOG_I(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Unable to add user, max user count reached\n",
phy_vars_eNB->Mod_id,frame, subframe);
}
}
}
void ulsch_decoding_procedures(unsigned char subframe, unsigned int i, PHY_VARS_eNB *phy_vars_eNB, unsigned char abstraction_flag)
{
UNUSED(subframe);
UNUSED(i);
UNUSED(phy_vars_eNB);
UNUSED(abstraction_flag);
LOG_D(PHY,"ulsch_decoding_procedures not yet implemented. should not be called");
}
void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,const uint8_t abstraction_flag,const relaying_type_t r_type)
{
//RX processing
UNUSED(r_type);
uint32_t l, ret=0,i,j,k;
uint32_t sect_id=0;
uint32_t harq_pid, harq_idx, round;
uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0};
int16_t n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3;
uint8_t do_SR = 0;
uint8_t pucch_sel = 0;
int32_t metric0=0,metric1=0,metric0_SR=0;
ANFBmode_t bundling_flag;
PUCCH_FMT_t format;
uint8_t nPRS;
// uint8_t two_ues_connected = 0;
uint8_t pusch_active = 0;
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->lte_frame_parms;
int sync_pos;
uint16_t rnti=0;
uint8_t access_mode;
int num_active_cba_groups;
const int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
const int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
printf("PHY RX f/sf %d/%d sched_sf %d\n", frame, subframe, sched_subframe);
AssertFatal(sched_subframe < NUM_ENB_THREADS, "Bad sched_subframe %d", sched_subframe);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1);
start_meas(&phy_vars_eNB->phy_proc_rx);
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",phy_vars_eNB->Mod_id,frame, subframe);
#endif
/*
#ifdef OAI_USRP
for (aa=0;aalte_frame_parms.nb_antennas_rx;aa++)
rescale(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][aa][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],
phy_vars_eNB->lte_frame_parms.samples_per_tti);
#endif
*/
phy_vars_eNB->rb_mask_ul[0]=0;
phy_vars_eNB->rb_mask_ul[1]=0;
phy_vars_eNB->rb_mask_ul[2]=0;
phy_vars_eNB->rb_mask_ul[3]=0;
if (abstraction_flag == 0) {
remove_7_5_kHz(phy_vars_eNB,subframe<<1);
remove_7_5_kHz(phy_vars_eNB,(subframe<<1)+1);
}
// check if we have to detect PRACH first
if (is_prach_subframe(&phy_vars_eNB->lte_frame_parms,frame,subframe)>0) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
prach_procedures(phy_vars_eNB,sched_subframe,abstraction_flag);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
}
if (abstraction_flag == 0) {
start_meas(&phy_vars_eNB->ofdm_demod_stats);
for (l=0; llte_frame_parms.symbols_per_tti/2; l++) {
// for (sect_id=0;sect_idlte_frame_parms,
&phy_vars_eNB->lte_eNB_common_vars,
l,
subframe<<1,
0,
0
);
slot_fep_ul(&phy_vars_eNB->lte_frame_parms,
&phy_vars_eNB->lte_eNB_common_vars,
l,
(subframe<<1)+1,
0,
0
);
}
stop_meas(&phy_vars_eNB->ofdm_demod_stats);
}
sect_id = 0;
/*
for (UE_id=0;UE_ideNB_UE_stats[(uint32_t)UE_id].mode>PRACH) && (last_slot%2==1)) {
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] frame %d, slot %d: Doing SRS estimation and measurements for UE_id %d (UE_mode %d)\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->proc[sched_subframe].frame_tx, last_slot,
UE_id,phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].mode);
#endif
for (sect_id=0;sect_idlte_frame_parms,
&phy_vars_eNB->lte_eNB_common_vars,
&phy_vars_eNB->lte_eNB_srs_vars[(uint32_t)UE_id],
&phy_vars_eNB->soundingrs_ul_config_dedicated[(uint32_t)UE_id],
last_slot>>1,
sect_id);
lte_eNB_srs_measurements(phy_vars_eNB,
sect_id,
UE_id,
1);
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] frame %d, slot %d: UE_id %d, sect_id %d: RX RSSI %d (from SRS)\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->proc[sched_subframe].frame_tx, last_slot,
UE_id,sect_id,
phy_vars_eNB->PHY_measurements_eNB[sect_id].rx_rssi_dBm[(uint32_t)UE_id]);
#endif
}
sect_id=0;
#ifdef USER_MODE
//write_output("srs_est0.m","srsest0",phy_vars_eNB->lte_eNB_common_vars.srs_ch_estimates[0][0],512,1,1);
//write_output("srs_est1.m","srsest1",phy_vars_eNB->lte_eNB_common_vars.srs_ch_estimates[0][1],512,1,1);
#endif
//msg("timing advance in\n");
sync_pos = lte_est_timing_advance(&phy_vars_eNB->lte_frame_parms,
&phy_vars_eNB->lte_eNB_srs_vars[(uint32_t)UE_id],
§_id,
phy_vars_eNB->first_run_timing_advance[(uint32_t)UE_id],
number_of_cards,
24576);
//msg("timing advance out\n");
//phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = sync_pos - phy_vars_eNB->lte_frame_parms.nb_prefix_samples/8;
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = 0;
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].sector = sect_id;
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] frame %d, slot %d: user %d in sector %d: timing_advance = %d\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->proc[sched_subframe].frame_tx, last_slot,
UE_id, sect_id,
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset);
#endif
}
}
else {
}
*/
// Check for active processes in current subframe
harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,
frame,subframe);
pusch_active = 0;
// reset the cba flag used for collision detection
for (i=0; i < NUM_MAX_CBA_GROUP; i++) {
phy_vars_eNB->cba_last_reception[i]=0;
}
// LOG_I(PHY,"subframe %d: nPRS %d\n",last_slot>>1,phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[last_slot-1]);
for (i=0; icooperation_flag > 0) && (two_ues_connected == 1))
break;
*/
#ifdef OPENAIR2
if (phy_vars_eNB->eNB_UE_stats[i].mode == RA_RESPONSE)
process_Msg3(phy_vars_eNB,sched_subframe,i,harq_pid);
#endif
/*
#ifdef DEBUG_PHY_PROC
if (phy_vars_eNB->ulsch_eNB[i]) {
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d, subframe %d rnti %x, alloc %d, Msg3 %d\n",phy_vars_eNB->Mod_id,
harq_pid,frame,subframe,
(phy_vars_eNB->ulsch_eNB[i]->rnti),
(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag),
(phy_vars_eNB->ulsch_eNB[i]->Msg3_flag)
);
}
#endif
*/
if ((phy_vars_eNB->ulsch_eNB[i]) &&
(phy_vars_eNB->ulsch_eNB[i]->rnti>0) &&
(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag==1)) {
pusch_active = 1;
round = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round;
for (int rb=0;
rb<=phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb;
rb++) {
int rb2 = rb+phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb;
phy_vars_eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Scheduling PUSCH/ULSCH Reception for rnti %x (UE_id %d)\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,phy_vars_eNB->ulsch_eNB[i]->rnti,i);
#endif
#ifdef DEBUG_PHY_PROC
if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for Msg3 in Sector %d\n",
phy_vars_eNB->Mod_id,
frame,
subframe,
phy_vars_eNB->eNB_UE_stats[i].sector);
} else {
LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d Mode %s sect_id %d\n",
phy_vars_eNB->Mod_id,
frame,
subframe,
i,
mode_string[phy_vars_eNB->eNB_UE_stats[i].mode],
phy_vars_eNB->eNB_UE_stats[i].sector);
}
#endif
nPRS = phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
phy_vars_eNB->ulsch_eNB[i]->cyclicShift = (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2 + phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
nPRS)%12;
if (frame_parms->frame_type == FDD ) {
int sf = (subframe<4) ? (subframe+6) : (subframe-4);
if (phy_vars_eNB->dlsch_eNB[i][0]->subframe_tx[sf]>0) { // we have downlink transmission
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 1;
} else {
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 0;
}
}
//#ifdef DEBUG_PHY_PROC
LOG_D(PHY,
"[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, mcs %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n",
phy_vars_eNB->Mod_id,harq_pid,frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->mcs,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rvidx,
phy_vars_eNB->ulsch_eNB[i]->cyclicShift,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2,
phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
nPRS,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK);
//#endif
start_meas(&phy_vars_eNB->ulsch_demodulation_stats);
if (abstraction_flag==0) {
rx_ulsch(phy_vars_eNB,
sched_subframe,
phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id
i,
phy_vars_eNB->ulsch_eNB,
0);
}
#ifdef PHY_ABSTRACTION
else {
rx_ulsch_emul(phy_vars_eNB,
subframe,
phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id
i);
}
#endif
stop_meas(&phy_vars_eNB->ulsch_demodulation_stats);
start_meas(&phy_vars_eNB->ulsch_decoding_stats);
if (abstraction_flag == 0) {
ret = ulsch_decoding(phy_vars_eNB,
i,
sched_subframe,
0, // control_only_flag
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->V_UL_DAI,
0);
}
#ifdef PHY_ABSTRACTION
else {
ret = ulsch_decoding_emul(phy_vars_eNB,
sched_subframe,
i,
&rnti);
}
#endif
stop_meas(&phy_vars_eNB->ulsch_decoding_stats);
//#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
ret);
//#endif //DEBUG_PHY_PROC
/*
if ((two_ues_connected==1) && (phy_vars_eNB->cooperation_flag==2)) {
for (j=0;jlte_frame_parms.nb_antennas_rx;j++) {
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[j] = dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_0[j])
- phy_vars_eNB->rx_total_gain_eNB_dB;
phy_vars_eNB->eNB_UE_stats[i+1].UL_rssi[j] = dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_1[j])
- phy_vars_eNB->rx_total_gain_eNB_dB;
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] Frame %d subframe %d: ULSCH %d RX power UE0 (%d,%d) dB RX power UE1 (%d,%d)\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,last_slot>>1,i,
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_0[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_0[1]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_1[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_1[1]));
#endif
}
else {
*/
//compute the expected ULSCH RX power (for the stats)
phy_vars_eNB->ulsch_eNB[(uint32_t)i]->harq_processes[harq_pid]->delta_TF =
get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
//dump_ulsch(phy_vars_eNB, sched_subframe, i);
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d Clearing subframe_scheduling_flag\n",
phy_vars_eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid);
#endif
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag=0;
if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status == 1) {
#ifdef DEBUG_PHY_PROC
//if (((phy_vars_eNB->proc[sched_subframe].frame_tx%10) == 0) || (phy_vars_eNB->proc[sched_subframe].frame_tx < 50))
print_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,0,phy_vars_eNB->lte_frame_parms.N_RB_DL);
#endif
extract_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,
&phy_vars_eNB->eNB_UE_stats[i],
phy_vars_eNB->lte_frame_parms.N_RB_DL,
&rnti, &access_mode);
phy_vars_eNB->eNB_UE_stats[i].rank = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_RI[0];
}
if (ret == (1+MAX_TURBO_ITERATIONS)) {
/*
if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round>0) {
dump_ulsch(phy_vars_eNB, sched_subframe, i);
mac_xface->macphy_exit("retransmission in error");
}
*/
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 0;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round++;
#if FAPI
mac_xface->fapi_ul_ack_nack(frame, subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, 0);
#endif
LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round);
if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
LOG_I(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d/%d\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,subframe, i,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1,
phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx-1);
LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
ret);
if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round ==
phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx) {
LOG_I(PHY,"[eNB %d][RAPROC] maxHARQ_Msg3Tx reached, abandoning RA procedure for UE %d\n",
phy_vars_eNB->Mod_id, i);
phy_vars_eNB->eNB_UE_stats[i].mode = PRACH;
#ifdef OPENAIR2
mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
phy_vars_eNB->eNB_UE_stats[i].crnti);
#endif
remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag);
phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0;
//phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 0;
} else {
// activate retransmission for Msg3 (signalled to UE PHY by PHICH (not MAC/DCI)
phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 1;
get_Msg3_alloc_ret(&phy_vars_eNB->lte_frame_parms,
subframe,
frame,
&phy_vars_eNB->ulsch_eNB[i]->Msg3_frame,
&phy_vars_eNB->ulsch_eNB[i]->Msg3_subframe);
}/*
LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
for (j=0;julsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++)
printf("%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]);
printf("\n");
*/
// dump_ulsch(phy_vars_eNB,sched_subframe,i);
//#ifndef EXMIMO_IOT
LOG_W(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i);
//#else
//mac_exit_wrapper("Msg3 error");
//#endif
} // This is Msg3 error
else { //normal ULSCH
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe, i,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1,
phy_vars_eNB->ulsch_eNB[i]->Mdlharq,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1]);
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_DISCARDED_MESSAGE(
MSC_PHY_ENB,MSC_PHY_UE,
NULL,0,
"%05u:%02u ULSCH received rnti %x harq id %u round %d",
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,harq_pid,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1
);
#endif
/*
LOG_T(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:\n",frame,subframe,
harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0]!=NULL){
for (j=0;julsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++)
LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]);
LOG_T(PHY,"\n");
}
*/
// dump_ulsch(phy_vars_eNB,sched_subframe,i);
//mac_exit_wrapper("ULSCH error");
if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round== phy_vars_eNB->ulsch_eNB[i]->Mdlharq) {
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d ULSCH Mdlharq %d reached\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe, i,
phy_vars_eNB->ulsch_eNB[i]->Mdlharq);
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round=0;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active=0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[harq_pid]++;
phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors++;
//dump_ulsch(phy_vars_eNB, sched_subframe, i);
}
}
} // ulsch in error
else {
if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe);
LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
ret);
}
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_MESSAGE(
MSC_PHY_ENB,MSC_PHY_UE,
NULL,0,
"%05u:%02u ULSCH received rnti %x harq id %u",
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,harq_pid
);
#endif
for (j=0; jlte_frame_parms.nb_antennas_rx; j++)
//this is the RSSI per RB
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[j] =
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[j]*
(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb*12)/
phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) -
phy_vars_eNB->rx_total_gain_eNB_dB -
hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 -
get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0)/100;
/*
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[j]*phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb) -
phy_vars_eNB->rx_total_gain_eNB_dB -
hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 -
get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0)/100;*/
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round = 0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors = 0;
#if FAPI
mac_xface->fapi_ul_ack_nack(frame, subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, 1);
#endif
if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
#ifdef OPENAIR2
//#ifdef DEBUG_PHY_PROC
LOG_I(PHY,"[eNB %d][RAPROC] Frame %d Terminating ra_proc for harq %d, UE %d\n",
phy_vars_eNB->Mod_id,
frame,harq_pid,i);
//#endif
mac_xface->rx_sdu(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
harq_pid,
&phy_vars_eNB->ulsch_eNB[i]->Msg3_flag);
// one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI)
if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 0 ) {
phy_vars_eNB->eNB_UE_stats[i].mode = PRACH;
mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
phy_vars_eNB->eNB_UE_stats[i].crnti);
remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag);
phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0;
}
/*
mac_xface->terminate_ra_proc(phy_vars_eNB->Mod_id,
frame,
phy_vars_eNB->ulsch_eNB[i]->rnti,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
*/
#endif
phy_vars_eNB->eNB_UE_stats[i].mode = PUSCH;
phy_vars_eNB->ulsch_eNB[i]->Msg3_flag = 0;
//#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][RAPROC] Frame %d : RX Subframe %d Setting UE %d mode to PUSCH\n",phy_vars_eNB->Mod_id,frame,subframe,i);
//#endif //DEBUG_PHY_PROC
for (k=0; k<8; k++) { //harq_processes
for (j=0; jdlsch_eNB[i][0]->Mdlharq; j++) {
phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK[k][j]=0;
phy_vars_eNB->eNB_UE_stats[i].dlsch_ACK[k][j]=0;
phy_vars_eNB->eNB_UE_stats[i].dlsch_trials[k][j]=0;
}
phy_vars_eNB->eNB_UE_stats[i].dlsch_l2_errors[k]=0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[k]=0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;
for (j=0; julsch_eNB[i]->Mdlharq; j++) {
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[k][j]=0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[k][j]=0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[k][j]=0;
}
}
phy_vars_eNB->eNB_UE_stats[i].dlsch_sliding_cnt=0;
phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK_round0=0;
phy_vars_eNB->eNB_UE_stats[i].dlsch_mcs_offset=0;
//mac_xface->macphy_exit("Mode PUSCH. Exiting.\n");
} else {
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
for (j=0; julsch_eNB[i]->harq_processes[harq_pid]->TBS>>3; j++)
LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b[j]);
LOG_T(PHY,"\n");
#endif
#endif
//dump_ulsch(phy_vars_eNB,sched_subframe,i);
#ifdef OPENAIR2
// if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->calibration_flag == 0) {
mac_xface->rx_sdu(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
harq_pid,
NULL);
//}
/*
else {
// Retrieve calibration information and do whatever
LOG_D(PHY,"[eNB][Auto-Calibration] Frame %d, Subframe %d : ULSCH PDU (RX) %d bytes\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
}
*/
#ifdef LOCALIZATION
start_meas(&phy_vars_eNB->localization_stats);
aggregate_eNB_UE_localization_stats(phy_vars_eNB,
i,
frame,
subframe,
get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 1)/100);
stop_meas(&phy_vars_eNB->localization_stats);
#endif
#endif
}
// estimate timing advance for MAC
if (abstraction_flag == 0) {
sync_pos = lte_est_timing_advance_pusch(phy_vars_eNB,i,sched_subframe);
phy_vars_eNB->eNB_UE_stats[i].timing_advance_update = sync_pos - phy_vars_eNB->lte_frame_parms.nb_prefix_samples/4; //to check
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] frame %d, subframe %d: user %d in sector %d: timing advance = %d\n",
phy_vars_eNB->Mod_id,
frame, subframe,
i, sect_id,
phy_vars_eNB->eNB_UE_stats[i].timing_advance_update);
#endif
} // ulsch not in error
// process HARQ feedback
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d, Processing HARQ feedback for UE %d (after PUSCH)\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->dlsch_eNB[i][0]->rnti,
frame,subframe,
i);
#endif
process_HARQ_feedback(i,
sched_subframe,
phy_vars_eNB,
1, // pusch_flag
0,
0,
0);
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] Frame %d subframe %d, sect %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n",
phy_vars_eNB->Mod_id,frame,subframe,
phy_vars_eNB->eNB_UE_stats[i].sector,
harq_pid,
i,
ret,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[harq_pid],
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
#endif
}
#ifdef PUCCH
else if ((phy_vars_eNB->dlsch_eNB[i][0]) &&
(phy_vars_eNB->dlsch_eNB[i][0]->rnti>0)) { // check for PUCCH
// check SR availability
do_SR = is_SR_subframe(phy_vars_eNB,i,sched_subframe);
// do_SR = 0;
// Now ACK/NAK
// First check subframe_tx flag for earlier subframes
get_n1_pucch_eNB(phy_vars_eNB,
i,
sched_subframe,
&n1_pucch0,
&n1_pucch1,
&n1_pucch2,
&n1_pucch3);
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d, subframe %d Checking for PUCCH (%d,%d,%d,%d) SR %d\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->dlsch_eNB[i][0]->rnti,
frame,subframe,
n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,do_SR);
if ((n1_pucch0==-1) && (n1_pucch1==-1) && (do_SR==0)) { // no TX PDSCH that have to be checked and no SR for this UE_id
} else {
// otherwise we have some PUCCH detection to do
// Null out PUCCH PRBs for noise measurement
switch(phy_vars_eNB->lte_frame_parms.N_RB_UL) {
case 6:
phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<5)); //position 5
break;
case 15:
phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<14)); // position 14
break;
case 25:
phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<24)); // position 24
break;
case 50:
phy_vars_eNB->rb_mask_ul[0] |= 0x1;
phy_vars_eNB->rb_mask_ul[1] |= (1<<17); // position 49 (49-32)
break;
case 75:
phy_vars_eNB->rb_mask_ul[0] |= 0x1;
phy_vars_eNB->rb_mask_ul[2] |= (1<<10); // position 74 (74-64)
break;
case 100:
phy_vars_eNB->rb_mask_ul[0] |= 0x1;
phy_vars_eNB->rb_mask_ul[3] |= (1<<3); // position 99 (99-96)
break;
default:
LOG_E(PHY,"Unknown number for N_RB_UL %d\n",phy_vars_eNB->lte_frame_parms.N_RB_UL);
break;
}
if (do_SR == 1) {
phy_vars_eNB->eNB_UE_stats[i].sr_total++;
if (abstraction_flag == 0)
metric0_SR = rx_pucch(phy_vars_eNB,
pucch_format1,
i,
phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,
0, // n2_pucch
0, // shortened format, should be use_srs flag, later
&SR_payload,
subframe,
PUCCH1_THRES);
#ifdef PHY_ABSTRACTION
else {
metric0_SR = rx_pucch_emul(phy_vars_eNB,
i,
pucch_format1,
0,
&SR_payload,
sched_subframe);
LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR (UE SR %d/%d)\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe,SR_payload,phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex);
}
#endif
if (SR_payload == 1) {
LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe);
phy_vars_eNB->eNB_UE_stats[i].sr_received++;
if (phy_vars_eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4
/* is this test necessary? */
if (phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status != SCH_IDLE)
put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], 0);
phy_vars_eNB->first_sr[i] = 0;
phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->round=0;
phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status=SCH_IDLE;
LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe);
}
#ifdef OPENAIR2
mac_xface->SR_indication(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
phy_vars_eNB->dlsch_eNB[i][0]->rnti,subframe);
#endif
}
}// do_SR==1
if ((n1_pucch0==-1) && (n1_pucch1==-1)) { // just check for SR
} else if (phy_vars_eNB->lte_frame_parms.frame_type==FDD) { // FDD
// if SR was detected, use the n1_pucch from SR, else use n1_pucch0
// n1_pucch0 = (SR_payload==1) ? phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex:n1_pucch0;
LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,SR_payload);
if (abstraction_flag == 0) {
metric0 = rx_pucch(phy_vars_eNB,
pucch_format1a,
i,
(uint16_t)n1_pucch0,
0, //n2_pucch
0, // shortened format
pucch_payload0,
subframe,
PUCCH1a_THRES);
if (metric0 < metric0_SR)
metric0=rx_pucch(phy_vars_eNB,
pucch_format1a,
i,
phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,
0, //n2_pucch
0, // shortened format
pucch_payload0,
subframe,
PUCCH1a_THRES);
}
else {
#ifdef PHY_ABSTRACTION
metric0 = rx_pucch_emul(phy_vars_eNB,i,
pucch_format1a,
0,
pucch_payload0,
subframe);
#endif
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->dlsch_eNB[i][0]->rnti,
frame,subframe,
pucch_payload0[0],metric0);
#endif
process_HARQ_feedback(i,sched_subframe,phy_vars_eNB,
0,// pusch_flag
pucch_payload0,
2,
SR_payload);
} // FDD
else { //TDD
bundling_flag = phy_vars_eNB->pucch_config_dedicated[i].tdd_AckNackFeedbackMode;
// fix later for 2 TB case and format1b
if ((frame_parms->frame_type==FDD) ||
(bundling_flag==bundling) ||
((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe!=2)||(subframe!=7)))) {
format = pucch_format1a;
// msg("PUCCH 1a\n");
} else {
format = pucch_format1b;
// msg("PUCCH 1b\n");
}
// if SR was detected, use the n1_pucch from SR
if (SR_payload==1) {
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->dlsch_eNB[i][0]->rnti,
frame,subframe,
n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
#endif
if (abstraction_flag == 0)
metric0_SR = rx_pucch(phy_vars_eNB,
format,
i,
phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,
0, //n2_pucch
0, // shortened format
pucch_payload0,
subframe,
PUCCH1a_THRES);
else {
#ifdef PHY_ABSTRACTION
metric0 = rx_pucch_emul(phy_vars_eNB,i,
format,
0,
pucch_payload0,
subframe);
#endif
}
} else { //using n1_pucch0/n1_pucch1 resources
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->dlsch_eNB[i][0]->rnti,
frame,subframe,
n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
#endif
metric0=0;
metric1=0;
// Check n1_pucch0 metric
if (n1_pucch0 != -1) {
if (abstraction_flag == 0)
metric0 = rx_pucch(phy_vars_eNB,
format,
i,
(uint16_t)n1_pucch0,
0, // n2_pucch
0, // shortened format
pucch_payload0,
subframe,
PUCCH1a_THRES);
else {
#ifdef PHY_ABSTRACTION
metric0 = rx_pucch_emul(phy_vars_eNB,i,
format,
0,
pucch_payload0,
subframe);
#endif
}
}
// Check n1_pucch1 metric
if (n1_pucch1 != -1) {
if (abstraction_flag == 0)
metric1 = rx_pucch(phy_vars_eNB,
format,
i,
(uint16_t)n1_pucch1,
0, //n2_pucch
0, // shortened format
pucch_payload1,
subframe,
PUCCH1a_THRES);
else {
#ifdef PHY_ABSTRACTION
metric1 = rx_pucch_emul(phy_vars_eNB,i,
format,
1,
pucch_payload1,
subframe);
#endif
}
}
}
if (SR_payload == 1) {
pucch_payload = pucch_payload0;
if (bundling_flag == bundling)
pucch_sel = 2;
} else if (bundling_flag == multiplexing) { // multiplexing + no SR
pucch_payload = (metric1>metric0) ? pucch_payload1 : pucch_payload0;
pucch_sel = (metric1>metric0) ? 1 : 0;
} else { // bundling + no SR
if (n1_pucch1 != -1)
pucch_payload = pucch_payload1;
else if (n1_pucch0 != -1)
pucch_payload = pucch_payload0;
pucch_sel = 2; // indicate that this is a bundled ACK/NAK
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",phy_vars_eNB->Mod_id,
phy_vars_eNB->dlsch_eNB[i][0]->rnti,
frame,subframe,
metric0,metric1,pucch_sel,pucch_payload[0],pucch_payload[1]);
#endif
process_HARQ_feedback(i,sched_subframe,phy_vars_eNB,
0,// pusch_flag
pucch_payload,
pucch_sel,
SR_payload);
}
}
} // PUCCH processing
#endif //PUCCH
if ((frame % 100 == 0) && (subframe == 4)) {
for (harq_idx=0; harq_idx<8; harq_idx++) {
for (round=0; roundulsch_eNB[i]->Mdlharq; round++) {
if ((phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]) != 0) {
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] =
(100*(phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round] -
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round]))/
(phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]);
} else {
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] = 0;
}
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round] =
phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round];
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round] =
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round];
}
}
}
if ((frame % 100 == 0) && (subframe==4)) {
phy_vars_eNB->eNB_UE_stats[i].dlsch_bitrate = (phy_vars_eNB->eNB_UE_stats[i].total_TBS -
phy_vars_eNB->eNB_UE_stats[i].total_TBS_last);
phy_vars_eNB->eNB_UE_stats[i].total_TBS_last = phy_vars_eNB->eNB_UE_stats[i].total_TBS;
}
num_active_cba_groups = phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups;
/*if (num_active_cba_groups > 0 )
LOG_D(PHY,"[eNB] last slot %d trying cba transmission decoding UE %d num_grps %d rnti %x flag %d\n",
last_slot, i, num_active_cba_groups,phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag );
*/
if ((phy_vars_eNB->ulsch_eNB[i]) &&
(num_active_cba_groups > 0) &&
(phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups]>0) &&
(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag==1)) {
rnti=0;
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Checking PUSCH/ULSCH CBA Reception for UE %d with cba rnti %x mode %s\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,
i, (uint16_t)phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups],mode_string[phy_vars_eNB->eNB_UE_stats[i].mode]);
#endif
if (abstraction_flag==0) {
rx_ulsch(phy_vars_eNB,
sched_subframe,
phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id
i,
phy_vars_eNB->ulsch_eNB,
0);
}
#ifdef PHY_ABSTRACTION
else {
rx_ulsch_emul(phy_vars_eNB,
subframe,
phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id
i);
}
#endif
if (abstraction_flag == 0) {
ret = ulsch_decoding(phy_vars_eNB,
i,
sched_subframe,
0, // control_only_flag
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->V_UL_DAI,
0);
}
#ifdef PHY_ABSTRACTION
else {
ret = ulsch_decoding_emul(phy_vars_eNB,
sched_subframe,
i,
&rnti);
}
#endif
if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status == 1) {
#ifdef DEBUG_PHY_PROC
//if (((phy_vars_eNB->proc[sched_subframe].frame_tx%10) == 0) || (phy_vars_eNB->proc[sched_subframe].frame_tx < 50))
print_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,0,phy_vars_eNB->lte_frame_parms.N_RB_DL);
#endif
access_mode = UNKNOWN_ACCESS;
extract_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,
&phy_vars_eNB->eNB_UE_stats[i],
phy_vars_eNB->lte_frame_parms.N_RB_DL,
&rnti, &access_mode);
phy_vars_eNB->eNB_UE_stats[i].rank = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_RI[0];
}
/* LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d resetting the sched_subframeuling_flag, total cba groups %d %d\n",
phy_vars_eNB->Mod_id,harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i,harq_pid,
phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups,num_active_cba_groups);
*/
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=0;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->status= SCH_IDLE;
if ((num_active_cba_groups > 0) &&
// (i % num_active_cba_groups == 0) && // this ue is used a a template for the CBA
(i + num_active_cba_groups < NUMBER_OF_UE_MAX) &&
(phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->cba_rnti[i%num_active_cba_groups] > 0 ) &&
(phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->num_active_cba_groups> 0)) {
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d resetting the subframe_scheduling_flag for Ue %d cba groups %d members\n",
phy_vars_eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid,
i+num_active_cba_groups, i%phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups);
#endif
phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=1;
phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->status= CBA_ACTIVE;
phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->TBS=phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS;
}
if (ret == (1+MAX_TURBO_ITERATIONS)) {
phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 0;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round++;
#if FAPI
mac_xface->fapi_ul_ack_nack(frame, subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, 0);
#endif
} // ulsch in error
else {
LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe);
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1;
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round = 0;
phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors = 0;
#if FAPI
mac_xface->fapi_ul_ack_nack(frame, subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, 1);
#endif
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_ULSCH
LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",
frame,subframe,
harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3);
for (j=0; julsch_eNB[i]->harq_processes[harq_pid]->TBS>>3; j++)
LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b[j]);
LOG_T(PHY,"\n");
#endif
#endif
if (access_mode > UNKNOWN_ACCESS) {
LOG_D(PHY,"[eNB %d] Frame %d, Subframe %d : received ULSCH SDU from CBA transmission, UE (%d,%x), CBA (group %d, rnti %x)\n",
phy_vars_eNB->Mod_id, frame,subframe,
i, phy_vars_eNB->ulsch_eNB[i]->rnti,
i % phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups, phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups]);
// detect if there is a CBA collision
if (phy_vars_eNB->cba_last_reception[i%num_active_cba_groups] == 0 ) {
mac_xface->rx_sdu(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
harq_pid,
NULL);
phy_vars_eNB->cba_last_reception[i%num_active_cba_groups]+=1;//(subframe);
} else {
if (phy_vars_eNB->cba_last_reception[i%num_active_cba_groups] == 1 )
LOG_N(PHY,"[eNB%d] Frame %d subframe %d : first CBA collision detected \n ",
phy_vars_eNB->Mod_id,frame,subframe);
LOG_N(PHY,"[eNB%d] Frame %d subframe %d : CBA collision set SR for UE %d in group %d \n ",
phy_vars_eNB->Mod_id,frame,subframe,
phy_vars_eNB->cba_last_reception[i%num_active_cba_groups],i%num_active_cba_groups );
phy_vars_eNB->cba_last_reception[i%num_active_cba_groups]+=1;
mac_xface->SR_indication(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
phy_vars_eNB->dlsch_eNB[i][0]->rnti,subframe);
}
}
} // ULSCH CBA not in error
}
} // loop i=0 ... NUMBER_OF_UE_MAX-1
// if (pusch_active == 0) {
if (abstraction_flag == 0) {
// LOG_D(PHY,"[eNB] Frame %d, subframe %d Doing I0_measurements\n",
// (((subframe)==9)?-1:0) + phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
lte_eNB_I0_measurements(phy_vars_eNB,
subframe,
0,
phy_vars_eNB->first_run_I0_measurements);
phy_vars_eNB->first_run_I0_measurements = 0;
}
#ifdef PHY_ABSTRACTION
else {
lte_eNB_I0_measurements_emul(phy_vars_eNB,
sect_id);
}
#endif
//}
#ifdef EMOS
phy_procedures_emos_eNB_RX(subframe,phy_vars_eNB);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,0);
stop_meas(&phy_vars_eNB->phy_proc_rx);
}
#undef DEBUG_PHY_PROC
#ifdef Rel10
int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type)
{
int do_proc=0;// do nothing
switch(r_type) {
case no_relay:
do_proc= no_relay; // perform the normal eNB operation
break;
case multicast_relay:
if (((next_slot >>1) < 6) || ((next_slot >>1) > 8))
do_proc = 0; // do nothing
else // SF#6, SF#7 and SF#8
do_proc = multicast_relay; // do PHY procedures eNB TX
break;
default: // should'not be here
LOG_W(PHY,"Not supported relay type %d, do nothing\n", r_type);
do_proc=0;
break;
}
return do_proc;
}
#endif
void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t abstraction_flag,
relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn)
{
#if defined(ENABLE_ITTI)
MessageDef *msg_p;
const char *msg_name;
instance_t instance;
unsigned int Mod_id;
int result;
#endif
int CC_id=0;
/*
if (phy_vars_eNB->proc[sched_subframe].frame_tx >= 1000)
mac_xface->macphy_exit("Exiting after 1000 Frames\n");
*/
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, phy_vars_eNB[0]->proc[subframe].frame_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,1);
start_meas(&phy_vars_eNB[0]->phy_proc);
#if defined(ENABLE_ITTI)
do {
// Checks if a message has been sent to PHY sub-task
itti_poll_msg (TASK_PHY_ENB, &msg_p);
if (msg_p != NULL) {
msg_name = ITTI_MSG_NAME (msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
Mod_id = instance;
switch (ITTI_MSG_ID(msg_p)) {
# if ENABLE_RAL
case TIMER_HAS_EXPIRED:
// check if it is a measurement timer
{
hashtable_rc_t hashtable_rc;
hashtable_rc = hashtable_is_key_exists(PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_timed, (uint64_t)(TIMER_HAS_EXPIRED(msg_p).timer_id));
if (hashtable_rc == HASH_TABLE_OK) {
phy_eNB_lte_check_measurement_thresholds(instance, (ral_threshold_phy_t*)TIMER_HAS_EXPIRED(msg_p).arg);
}
}
break;
case PHY_MEAS_THRESHOLD_REQ:
#warning "TO DO LIST OF THRESHOLDS"
LOG_D(PHY, "[ENB %d] Received %s\n", Mod_id, msg_name);
{
ral_threshold_phy_t* threshold_phy_p = NULL;
int index, res;
long timer_id;
hashtable_rc_t hashtable_rc;
switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action) {
case RAL_TH_ACTION_CANCEL_THRESHOLD:
break;
case RAL_TH_ACTION_SET_NORMAL_THRESHOLD:
case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD:
for (index = 0; index < PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.num_thresholds; index++) {
threshold_phy_p = calloc(1, sizeof(ral_threshold_phy_t));
threshold_phy_p->th_action = PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action;
memcpy(&threshold_phy_p->link_param.link_param_type,
&PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type,
sizeof(ral_link_param_type_t));
memcpy(&threshold_phy_p->threshold,
&PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.thresholds[index],
sizeof(ral_threshold_t));
switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice) {
case RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL:
switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice) {
case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
SLIST_INSERT_HEAD(
&PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_gen_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_gen],
threshold_phy_p,
ral_thresholds);
break;
case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
SLIST_INSERT_HEAD(
&PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_lte_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_lte],
threshold_phy_p,
ral_thresholds);
break;
default:
LOG_E(PHY, "[ENB %d] BAD PARAMETER cfg_param.link_param_type.choice %d in %s\n",
Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice, msg_name);
}
break;
case RAL_LINK_CFG_PARAM_CHOICE_TIMER:
res = timer_setup(
(uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval/1000),//uint32_t interval_sec,
(uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval%1000),//uint32_t interval_us,
TASK_PHY_ENB,
instance,
TIMER_PERIODIC,
threshold_phy_p,
&timer_id);
if (res == 0) {
hashtable_rc = hashtable_insert(PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_timed, (uint64_t )timer_id, (void*)threshold_phy_p);
if (hashtable_rc == HASH_TABLE_OK) {
threshold_phy_p->timer_id = timer_id;
} else {
LOG_E(PHY, "[ENB %d] %s: Error in hashtable. Could not configure threshold index %d \n",
Mod_id, msg_name, index);
}
} else {
LOG_E(PHY, "[ENB %d] %s: Could not configure threshold index %d because of timer initialization failure\n",
Mod_id, msg_name, index);
}
break;
default: // already checked in RRC, should not happen here
LOG_E(PHY, "[ENB %d] BAD PARAMETER cfg_param.union_choice %d in %s\n",
Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice, msg_name);
}
}
break;
default:
LOG_E(PHY, "[ENB %d] BAD PARAMETER th_action value %d in %s\n",
Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action, msg_name);
}
}
break;
# endif
/* Messages from eNB app */
case PHY_CONFIGURATION_REQ:
LOG_I(PHY, "[eNB %d] Received %s\n", instance, msg_name);
/* TODO */
break;
default:
LOG_E(PHY, "[ENB %d] Received unexpected message %s\n", Mod_id, msg_name);
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
} while(msg_p != NULL);
#endif
for (CC_id=0; CC_idlte_frame_parms.frame_type == TDD)&&
(subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_tx)==SF_DL))||
(phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == FDD))) {
#ifdef Rel10
if (phy_procedures_RN_eNB_TX(phy_vars_eNB[CC_id]->proc[subframe].subframe_rx, phy_vars_eNB[CC_id]->proc[subframe].subframe_tx, r_type) != 0 )
#endif
phy_procedures_eNB_TX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type,phy_vars_rn);
}
if ((((phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == TDD )&&
(subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_rx)==SF_UL)) ||
(phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == FDD))) {
phy_procedures_eNB_RX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type);
}
if (subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_tx)==SF_S) {
#ifdef Rel10
if (phy_procedures_RN_eNB_TX(subframe, subframe, r_type) != 0 )
#endif
phy_procedures_eNB_TX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type,phy_vars_rn);
}
if ((subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_rx)==SF_S)) {
phy_procedures_eNB_S_RX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type);
}
phy_vars_eNB[CC_id]->proc[subframe].frame_tx++;
phy_vars_eNB[CC_id]->proc[subframe].frame_rx++;
if (phy_vars_eNB[CC_id]->proc[subframe].frame_tx>=MAX_FRAME_NUMBER) // defined in impl_defs_top.h
phy_vars_eNB[CC_id]->proc[subframe].frame_tx-=MAX_FRAME_NUMBER;
if (phy_vars_eNB[CC_id]->proc[subframe].frame_rx>=MAX_FRAME_NUMBER)
phy_vars_eNB[CC_id]->proc[subframe].frame_rx-=MAX_FRAME_NUMBER;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0);
stop_meas(&phy_vars_eNB[0]->phy_proc);
}