Commit 5b93cd38 authored by Ting-An Lin's avatar Ting-An Lin

Create NB-IoT PHY struct

parent 302159fc
...@@ -1223,6 +1223,7 @@ set(PHY_SRC ...@@ -1223,6 +1223,7 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dlsch_scrambling_NB_IoT.c ${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dlsch_scrambling_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/lte_mcs_NB_IoT.c ${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/lte_mcs_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/ulsch_demodulation_NB_IoT.c ${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/ulsch_demodulation_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/ulsch_decoding_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/lte_Isc_NB_IoT.c ${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/lte_Isc_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/nprach_NB_IoT.c ${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/nprach_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/nsss_NB_IoT.c ${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/nsss_NB_IoT.c
...@@ -2116,6 +2117,7 @@ add_executable(lte-softmodem ...@@ -2116,6 +2117,7 @@ add_executable(lte-softmodem
${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
${OPENAIR_TARGETS}/RT/USER/ru_control.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c
${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
${OPENAIR_TARGETS}/RT/USER/init_lte.c
${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define CRC8 3 #define CRC8 3
#define MAX_TURBO_ITERATIONS_MBSFN 8 #define MAX_TURBO_ITERATIONS_MBSFN 8
#define MAX_TURBO_ITERATIONS max_turbo_iterations #define MAX_TURBO_ITERATIONS 4
typedef struct { typedef struct {
unsigned short nb_bits; unsigned short nb_bits;
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
*/ */
#ifndef __TRANSPORT_UE__H__ #ifndef __TRANSPORT_UE__H__
#define __TRANSPORT_UE__H__ #define __TRANSPORT_UE__H__
#include "PHY/defs_UE.h"
#include "PHY/impl_defs_lte.h" #include "PHY/impl_defs_lte.h"
#include "../LTE_TRANSPORT/dci.h" #include "../LTE_TRANSPORT/dci.h"
#include "../LTE_TRANSPORT/mdci.h" #include "../LTE_TRANSPORT/mdci.h"
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/ulsch_decoding.c
* \brief Top-level routines for decoding the ULSCH transport channel from 36.212 V8.6 2009-03
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
/*! \file PHY/LTE_TRANSPORT/ulsch_decoding.c
* \brief Top-level routines for decoding the ULSCH transport channel from 36.212 V8.6 2009-03
* \author V. Savaux
* \date 2017
* \version 0.1
* \company b<>com
* \email: vincent.savaux@b-com.com
* \note
* \warning
*/
//#include "defs.h"
//#include "PHY/defs.h"
#include "defs_NB_IoT.h"
#include "extern_NB_IoT.h"
#include "vars_NB_IoT.h"
#include "../CODING/defs_NB_IoT.h"
#include "../CODING/lte_interleaver2.h"
#include "../extern_NB_IoT.h"
//#include "extern_NB_IoT.h"
//#include "SCHED/extern.h"
/*
#ifdef OPENAIR2
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern_NB_IoT.h"
#include "RRC/LITE/extern.h"
#include "PHY_INTERFACE/extern.h"
#endif
#ifdef PHY_ABSTRACTION
#include "UTIL/OCG/OCG.h"
#include "UTIL/OCG/OCG_extern.h"
#endif
*/
//#include "UTIL/LOG/vcd_signal_dumper.h"
//#define DEBUG_ULSCH_DECODING
/////////////////////////////////////////////////// NB-IoT testing ////////////////////////////////////////
void free_eNB_ulsch_NB_IoT(NB_IoT_eNB_NULSCH_t *ulsch)
{
int r;
if (ulsch) {
if (ulsch->harq_process) {
if (ulsch->harq_process->b) {
free16(ulsch->harq_process->b,MAX_ULSCH_PAYLOAD_BYTES);
ulsch->harq_process->b = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
free16(ulsch->harq_process->c[r],((r==0)?8:0) + 768);
ulsch->harq_process->c[r] = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++)
if (ulsch->harq_process->d[r]) {
free16(ulsch->harq_process->d[r],((3*8*6144)+12+96)*sizeof(short));
ulsch->harq_process->d[r] = NULL;
}
free16(ulsch->harq_process,sizeof(NB_IoT_UL_eNB_HARQ_t));
ulsch->harq_process = NULL;
}
free16(ulsch,sizeof(NB_IoT_eNB_NULSCH_t));
ulsch = NULL;
}
}
NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag)
{
NB_IoT_eNB_NULSCH_t *ulsch;
uint8_t exit_flag = 0,r;
unsigned char bw_scaling =1;
switch (N_RB_UL) {
case 6:
bw_scaling =16;
break;
case 25:
bw_scaling =4;
break;
case 50:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
ulsch = (NB_IoT_eNB_NULSCH_t *)malloc16(sizeof(NB_IoT_eNB_NULSCH_t));
if (ulsch) {
memset(ulsch,0,sizeof(NB_IoT_eNB_NULSCH_t));
ulsch->max_turbo_iterations = max_turbo_iterations;
ulsch->Mlimit = 4;
// printf("new_ue_ulsch: Harq process %d\n",i);
ulsch->harq_process = (NB_IoT_UL_eNB_HARQ_t *)malloc16(sizeof(NB_IoT_UL_eNB_HARQ_t));
if (ulsch->harq_process) {
memset(ulsch->harq_process,0,sizeof(NB_IoT_UL_eNB_HARQ_t));
ulsch->harq_process->b = (uint8_t*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_process->b)
memset(ulsch->harq_process->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
else
exit_flag=3;
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS/bw_scaling; r++) {
ulsch->harq_process->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+768);
if (ulsch->harq_process->c[r])
memset(ulsch->harq_process->c[r],0,((r==0)?8:0) + 3+768);
else
exit_flag=2;
ulsch->harq_process->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short));
if (ulsch->harq_process->d[r])
memset(ulsch->harq_process->d[r],0,((3*8*6144)+12+96)*sizeof(short));
else
exit_flag=2;
}
ulsch->harq_process->subframe_scheduling_flag = 0;
}
} else {
exit_flag=1;
}
if (exit_flag==0)
return(ulsch);
}
LOG_E(PHY,"new_ue_ulsch: exit_flag = %d\n",exit_flag);
free_eNB_ulsch_NB_IoT(ulsch);
return(NULL);
}
void clean_eNb_ulsch_NB_IoT(NB_IoT_eNB_NULSCH_t *ulsch)
{
// unsigned char i;
//ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if (ulsch) {
ulsch->rnti = 0;
if (ulsch->harq_process) {
// ulsch->harq_processes[i]->Ndi = 0;
ulsch->harq_process->status = 0;
ulsch->harq_process->subframe_scheduling_flag = 0;
//ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
ulsch->harq_process->phich_ACK = 0;
ulsch->harq_process->round = 0;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch)
{
int i,r;
if (ulsch) {
for (i=0; i<8; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->b = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 768);
ulsch->harq_processes[i]->c[r] = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++)
if (ulsch->harq_processes[i]->d[r]) {
free16(ulsch->harq_processes[i]->d[r],((3*8*6144)+12+96)*sizeof(short));
ulsch->harq_processes[i]->d[r] = NULL;
}
free16(ulsch->harq_processes[i],sizeof(LTE_UL_eNB_HARQ_t));
ulsch->harq_processes[i] = NULL;
}
}
free16(ulsch,sizeof(LTE_eNB_ULSCH_t));
ulsch = NULL;
}
}
LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag)
{
LTE_eNB_ULSCH_t *ulsch;
uint8_t exit_flag = 0,i,r;
unsigned char bw_scaling =1;
switch (N_RB_UL) {
case 6:
bw_scaling =16;
break;
case 25:
bw_scaling =4;
break;
case 50:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if (ulsch) {
memset(ulsch,0,sizeof(LTE_eNB_ULSCH_t));
ulsch->max_turbo_iterations = max_turbo_iterations;
ulsch->Mlimit = 4;
for (i=0; i<8; i++) {
// printf("new_ue_ulsch: Harq process %d\n",i);
ulsch->harq_processes[i] = (LTE_UL_eNB_HARQ_t *)malloc16(sizeof(LTE_UL_eNB_HARQ_t));
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i]->b)
memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
else
exit_flag=3;
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS/bw_scaling; r++) {
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+768);
if (ulsch->harq_processes[i]->c[r])
memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768);
else
exit_flag=2;
ulsch->harq_processes[i]->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short));
if (ulsch->harq_processes[i]->d[r])
memset(ulsch->harq_processes[i]->d[r],0,((3*8*6144)+12+96)*sizeof(short));
else
exit_flag=2;
}
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
}
} else {
exit_flag=1;
}
}
if (exit_flag==0)
return(ulsch);
}
LOG_E(PHY,"new_ue_ulsch: exit_flag = %d\n",exit_flag);
free_eNB_ulsch(ulsch);
return(NULL);
}
///
NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB(uint8_t abstraction_flag)
{
NB_IoT_eNB_NULSCH_t *ulsch;
uint8_t exit_flag = 0,i,r;
unsigned char bw_scaling =1;
// switch (N_RB_UL) {
// case 6:
// bw_scaling =16;
// break;
//
// case 25:
// bw_scaling =4;
// break;
//
// case 50:
// bw_scaling =2;
// break;
//
// default:
// bw_scaling =1;
// break;
// }
ulsch = (NB_IoT_eNB_NULSCH_t *)malloc16(sizeof(NB_IoT_eNB_NULSCH_t));
if (ulsch) {
memset(ulsch,0,sizeof(LTE_eNB_ULSCH_t));
//MP: add some parameters in npusch structure for convolutional coding to be set
ulsch->Mlimit = 4;
ulsch->harq_process = (LTE_UL_eNB_HARQ_t *)malloc16(sizeof(LTE_UL_eNB_HARQ_t));
if (ulsch->harq_process) {
memset(ulsch->harq_process,0,sizeof(LTE_UL_eNB_HARQ_t));
ulsch->harq_process->b = (uint8_t*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_process->b)
memset(ulsch->harq_process->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
else
exit_flag=3;
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS/bw_scaling; r++) {
ulsch->harq_process->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+768);
if (ulsch->harq_process->c[r])
memset(ulsch->harq_process->c[r],0,((r==0)?8:0) + 3+768);
else
exit_flag=2;
ulsch->harq_process->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short));
if (ulsch->harq_process->d[r])
memset(ulsch->harq_process->d[r],0,((3*8*6144)+12+96)*sizeof(short));
else
exit_flag=2;
}
ulsch->harq_process->subframe_scheduling_flag = 0;
}
} else {
exit_flag=1;
}
if (exit_flag==0)
return(ulsch);
}
LOG_E(PHY,"new_ue_ulsch: exit_flag = %d\n",exit_flag);
free_eNB_ulsch(ulsch);
return(NULL);
}
void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
{
unsigned char i;
//ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if (ulsch) {
ulsch->rnti = 0;
for (i=0; i<8; i++) {
if (ulsch->harq_processes[i]) {
// ulsch->harq_processes[i]->Ndi = 0;
ulsch->harq_processes[i]->status = 0;
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
//ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
ulsch->harq_processes[i]->phich_ACK = 0;
ulsch->harq_processes[i]->round = 0;
}
}
}
}
*/
uint8_t extract_cqi_crc_NB_IoT(uint8_t *cqi,uint8_t CQI_LENGTH)
{
uint8_t crc;
crc = cqi[CQI_LENGTH>>3];
// printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7);
crc = (crc<<(CQI_LENGTH&0x7));
// clear crc bits
// ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7));
// printf("crc2: %x, cqi0 %x\n",crc,cqi[1+(CQI_LENGTH>>3)]);
crc |= (cqi[1+(CQI_LENGTH>>3)])>>(8-(CQI_LENGTH&0x7));
// clear crc bits
//(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0;
// printf("crc : %x\n",crc);
return(crc);
}
/*
int ulsch_decoding_data_2thread0(td_params* tdp) {
PHY_VARS_eNB *eNB = tdp->eNB;
int UE_id = tdp->UE_id;
int harq_pid = tdp->harq_pid;
int llr8_flag = tdp->llr8_flag;
unsigned int r,r_offset=0,Kr,Kr_bytes,iind;
uint8_t crc_type;
int offset = 0;
int ret = 1;
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int Q_m = get_Qm_ul(ulsch_harq->mcs);
int G = ulsch_harq->G;
uint32_t E;
uint32_t Gp,GpmodC,Nl=1;
uint32_t C = ulsch_harq->C;
uint8_t (*tc)(int16_t *y,
uint8_t *,
uint16_t,
uint16_t,
uint16_t,
uint8_t,
uint8_t,
uint8_t,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *);
if (llr8_flag == 0)
tc = phy_threegpplte_turbo_decoder16;
else
tc = phy_threegpplte_turbo_decoder8;
// go through first half of segments to get r_offset
for (r=0; r<(ulsch_harq->C/2); r++) {
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
// This is stolen from rate-matching algorithm to get the value of E
Gp = G/Nl/Q_m;
GpmodC = Gp%C;
if (r < (C-(GpmodC)))
E = Nl*Q_m * (Gp/C);
else
E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C));
r_offset += E;
if (r==0) {
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
} else {
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
}
}
// go through second half of segments
for (; r<(ulsch_harq->C); r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
#ifdef DEBUG_ULSCH_DECODING
printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? ulsch_harq->F : 0);
#endif
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
#ifdef DEBUG_ULSCH_DECODING
printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n",
r, G,
Kr*3,
Q_m,
nb_rb,
ulsch_harq->Nl);
#endif
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G,
ulsch_harq->w[r],
(uint8_t*) &dummy_w[r][0],
ulsch_harq->e+r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
1,
ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear
get_Qm_ul(ulsch_harq->mcs),
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
}
r_offset += E;
sub_block_deinterleaving_turbo(4+Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
if (ulsch_harq->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
ret = tc(&ulsch_harq->d[r][96],
ulsch_harq->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
&eNB->ulsch_tc_gamma_stats,
&eNB->ulsch_tc_ext_stats,
&eNB->ulsch_tc_intl1_stats,
&eNB->ulsch_tc_intl2_stats);
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
memcpy(ulsch_harq->b+offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
} else {
break;
}
}
return(ret);
}
extern int oai_exit;
void *td_thread(void *param) {
pthread_setname_np( pthread_self(), "td processing");
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
eNB_proc_t *proc = &eNB->proc;
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break;
((td_params*)param)->ret = ulsch_decoding_data_2thread0((td_params*)param);
if (release_thread(&proc->mutex_td,&proc->instance_cnt_td,"td thread")<0) break;
if (pthread_cond_signal(&proc->cond_td) != 0) {
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return(NULL);
}
}
return(NULL);
}
int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
eNB_proc_t *proc = &eNB->proc;
unsigned int r,r_offset=0,Kr,Kr_bytes,iind;
uint8_t crc_type;
int offset = 0;
int ret = 1;
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
//int Q_m = get_Qm_ul(ulsch_harq->mcs);
int G = ulsch_harq->G;
unsigned int E;
int Cby2;
uint8_t (*tc)(int16_t *y,
uint8_t *,
uint16_t,
uint16_t,
uint16_t,
uint8_t,
uint8_t,
uint8_t,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *);
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
if (llr8_flag == 0)
tc = phy_threegpplte_turbo_decoder16;
else
tc = phy_threegpplte_turbo_decoder8;
if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment
if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) {
printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td);
exit_fun( "error locking mutex_fep" );
return -1;
}
if (proc->instance_cnt_td==0) {
printf("[eNB] TD thread busy\n");
exit_fun("TD thread busy");
pthread_mutex_unlock( &proc->mutex_td );
return -1;
}
++proc->instance_cnt_td;
proc->tdp.eNB = eNB;
proc->tdp.UE_id = UE_id;
proc->tdp.harq_pid = harq_pid;
proc->tdp.llr8_flag = llr8_flag;
// wakeup worker to do second half segments
if (pthread_cond_signal(&proc->cond_td) != 0) {
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return (1+ulsch->max_turbo_iterations);
}
pthread_mutex_unlock( &proc->mutex_td );
Cby2 = ulsch_harq->C/2;
}
else {
Cby2 = 1;
}
// go through first half of segments in main thread
for (r=0; r<Cby2; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
#ifdef DEBUG_ULSCH_DECODING
printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? ulsch_harq->F : 0);
#endif
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
#ifdef DEBUG_ULSCH_DECODING
printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n",
r, G,
Kr*3,
Q_m,
nb_rb,
ulsch_harq->Nl);
#endif
start_meas(&eNB->ulsch_rate_unmatching_stats);
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G,
ulsch_harq->w[r],
(uint8_t*) &dummy_w[r][0],
ulsch_harq->e+r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
1,
ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear
get_Qm_ul(ulsch_harq->mcs),
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
}
stop_meas(&eNB->ulsch_rate_unmatching_stats);
r_offset += E;
start_meas(&eNB->ulsch_deinterleaving_stats);
sub_block_deinterleaving_turbo(4+Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
stop_meas(&eNB->ulsch_deinterleaving_stats);
if (ulsch_harq->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
start_meas(&eNB->ulsch_turbo_decoding_stats);
ret = tc(&ulsch_harq->d[r][96],
ulsch_harq->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
&eNB->ulsch_tc_gamma_stats,
&eNB->ulsch_tc_ext_stats,
&eNB->ulsch_tc_intl1_stats,
&eNB->ulsch_tc_intl2_stats);
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (r==0) {
memcpy(ulsch_harq->b,
&ulsch_harq->c[0][(ulsch_harq->F>>3)],
Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
} else {
memcpy(ulsch_harq->b+offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
}
} else {
break;
}
stop_meas(&eNB->ulsch_turbo_decoding_stats);
}
// wait for worker to finish
wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread");
return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret );
}
*/
// NB_IoT: functions in ulsch_decoding_data_NB_IoT must be defined
int ulsch_decoding_data_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,int UE_id,int harq_pid,int llr8_flag) {
unsigned int r,r_offset=0,Kr,Kr_bytes,iind;
uint8_t crc_type;
int offset = 0;
int ret = 1;
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS_NB_IoT][3*(6144+64)];
NB_IoT_eNB_NULSCH_t *ulsch = eNB->ulsch_NB_IoT[UE_id];
// NB_IoT_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_process[harq_pid];
NB_IoT_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_process;
//int Q_m = get_Qm_ul(ulsch_harq->mcs);
int G = ulsch_harq->G;
unsigned int E;
uint8_t (*tc)(int16_t *y,
uint8_t *,
uint16_t,
uint16_t,
uint16_t,
uint8_t,
uint8_t,
uint8_t,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *);
if (llr8_flag == 0)
tc = phy_threegpplte_turbo_decoder16;
else
tc = phy_threegpplte_turbo_decoder8;
for (r=0; r<ulsch_harq->C; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
#ifdef DEBUG_ULSCH_DECODING
printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? ulsch_harq->F : 0);
#endif
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
#ifdef DEBUG_ULSCH_DECODING
printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n",
r, G,
Kr*3,
Q_m,
nb_rb,
ulsch_harq->Nl);
#endif
//start_meas(&eNB->ulsch_rate_unmatching_stats);
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G,
ulsch_harq->w[r],
(uint8_t*) &dummy_w[r][0],
ulsch_harq->e+r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
1,
ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear
get_Qm_ul(ulsch_harq->mcs),
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
}
// stop_meas(&eNB->ulsch_rate_unmatching_stats);
r_offset += E;
// start_meas(&eNB->ulsch_deinterleaving_stats);
sub_block_deinterleaving_turbo(4+Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
// stop_meas(&eNB->ulsch_deinterleaving_stats);
if (ulsch_harq->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
// start_meas(&eNB->ulsch_turbo_decoding_stats);
ret = tc(&ulsch_harq->d[r][96],
ulsch_harq->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
&eNB->ulsch_tc_gamma_stats,
&eNB->ulsch_tc_ext_stats,
&eNB->ulsch_tc_intl1_stats,
&eNB->ulsch_tc_intl2_stats);
// stop_meas(&eNB->ulsch_turbo_decoding_stats);
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (r==0) {
memcpy(ulsch_harq->b,
&ulsch_harq->c[0][(ulsch_harq->F>>3)],
Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
} else {
memcpy(ulsch_harq->b+offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
}
} else {
break;
}
}
return(ret);
}
// NB_IoT: functions in ulsch_decoding_data_NB_IoT must be defined :ulsch_decoding_data_NB_IoT (defined in this file)
static inline unsigned int lte_gold_unscram_NB_IoT(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
static inline unsigned int lte_gold_unscram_NB_IoT(unsigned int *x1, unsigned int *x2, unsigned char reset)
{
int n;
if (reset) {
*x1 = 1+ (1<<31);
*x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
// skip first 50 double words (1600 bits)
// printf("n=0 : x1 %x, x2 %x\n",x1,x2);
for (n=1; n<50; n++) {
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
}
}
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
return(*x1^*x2);
// printf("n=%d : c %x\n",n,x1^x2);
}
/*
unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
uint8_t UE_id,
uint8_t control_only_flag,
uint8_t Nbundled,
uint8_t llr8_flag)
{
//MAC_xface_NB_IoT *mac_xface_NB_IoT; //test_xface
int16_t *ulsch_llr = eNB->pusch_vars[UE_id]->llr;
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
NB_IoT_eNB_NULSCH_t *ulsch = eNB->ulsch_NB_IoT[UE_id];
NB_IoT_UL_eNB_HARQ_t *ulsch_harq;
uint8_t harq_pid;
//unsigned short nb_rb;
unsigned int A;
uint8_t Q_m;
unsigned int i,i2,j,j2;
// unsigned int q;
int iprime;
unsigned int ret = 0;
int r,Kr;
// uint8_t *columnset;
unsigned int sumKr=0;
//unsigned int Qprime,L,O_RCC;
unsigned int G,Q_CQI,Q_RI=0,H,Hprime,Hpp,Cmux,Rmux_prime;
//unsigned int Qprime_ACK,Qprime_RI,len_ACK=0,len_RI=0;
// int metric,metric_new;
//uint8_t o_flip[8];
uint32_t x1, x2, s=0;
//int16_t ys;
int16_t c;
//uint32_t wACK_idx;
//uint8_t dummy_w_cc[3*(MAX_CQI_BITS+8+32)];
int16_t y[6*14*1200] __attribute__((aligned(32)));
uint8_t ytag[14*1200];
int16_t cseq[6*14*1200];
//int off;
int subframe = proc->subframe_rx;
harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1);
// x1 is set in lte_gold_generic
// x2 should not reinitialized each subframe
// x2 should be reinitialized according to 36.211 Sections 10.1.3.1 and 10.1.3.6
x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + (((uint32_t)proc->frame_rx%2)<<13) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 10.1.3.1
ulsch_harq = ulsch->harq_process;
if (harq_pid==255) {
LOG_E(PHY, "FATAL ERROR: illegal harq_pid, returning\n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0);
return -1;
}
if (ulsch_harq->Nsymb_pusch == 0) {
LOG_E(PHY, "FATAL ERROR: harq_pid %d, Nsymb 0!\n",harq_pid);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0);
return 1+ulsch->max_turbo_iterations;
}
*/
/* ----------------------- Segmentation */
/*
// nb_rb = ulsch_harq->nb_rb; // nb_rb set but not used ??
//nb_rb = 1; // nb_rb set but not used ??
A = ulsch_harq->TBS;
Q_m = get_Qm_ul_NB_IoT(ulsch_harq->mcs,ulsch_harq->N_sc_RU);
//G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
G = (ulsch_harq->N_sc_RU * Q_m) * ulsch_harq->Nsymb_UL * ulsch_harq->Nslot_UL; // see 36.212, Section 5.1.4.1.2
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
frame_parms->Nid_cell,ulsch->rnti,x2,
ulsch_harq->round,
ulsch_harq->rvidx,
ulsch_harq->mcs,
ulsch_harq->O_RI,
ulsch_harq->O_ACK,
G,
subframe);
#endif
if (ulsch_harq->round == 0) {
// This is a new packet, so compute quantities regarding segmentation
ulsch_harq->B = A+24;
lte_segmentation_NB_IoT(NULL,
NULL,
ulsch_harq->B,
&ulsch_harq->C,
&ulsch_harq->Cplus,
&ulsch_harq->Cminus,
&ulsch_harq->Kplus,
&ulsch_harq->Kminus,
&ulsch_harq->F);
// CLEAR LLR's HERE for first packet in process
}
// printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]);
sumKr = 0;
for (r=0; r<ulsch_harq->C; r++) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
sumKr += Kr;
}
if (sumKr==0) {
LOG_N(PHY,"[eNB %d] ulsch_decoding.c: FATAL sumKr is 0!\n",eNB->Mod_id);
LOG_D(PHY,"ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
frame_parms->Nid_cell,ulsch->rnti,x2,
harq_pid,
ulsch_harq->round,
ulsch_harq->rvidx,
ulsch_harq->mcs,
ulsch_harq->O_RI,
ulsch_harq->O_ACK,
G,
subframe);
//mac_xface_NB_IoT->macphy_exit("ulsch_decoding.c: FATAL sumKr is 0!");
return(-1);
}
*/
// No control information in NB-IoT
// Compute Q_ri
// Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
// if (Qprime > 0 ) {
// if ((Qprime % (8*sumKr)) > 0)
// Qprime = 1+(Qprime/(8*sumKr));
// else
// Qprime = Qprime/(8*sumKr);
// if (Qprime > 4*nb_rb * 12)
// Qprime = 4*nb_rb * 12;
// }
// Q_RI = Q_m*Qprime;
// Qprime_RI = Qprime;
// // Compute Q_ack
// Qprime = ulsch_harq->O_ACK*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8;
// if (Qprime > 0) {
// if ((Qprime % (8*sumKr)) > 0)
// Qprime = 1+(Qprime/(8*sumKr));
// else
// Qprime = Qprime/(8*sumKr);
// if (Qprime > (4*nb_rb * 12))
// Qprime = 4*nb_rb * 12;
// }
// // Q_ACK = Qprime * Q_m;
// Qprime_ACK = Qprime;
// #ifdef DEBUG_ULSCH_DECODING
// printf("ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d\n",
// Qprime_ACK,ulsch_harq->Msc_initial,ulsch_harq->Nsymb_initial,sumKr);
// #endif
// // Compute Q_cqi
// if (ulsch_harq->Or1 < 12)
// L=0;
// else
// L=8;
// // NOTE: we have to handle the case where we have a very small number of bits (condition on pg. 26 36.212)
// if (ulsch_harq->Or1 > 0)
// Qprime = (ulsch_harq->Or1 + L) * ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_cqi_times8;
// else
// Qprime=0;
// if (Qprime > 0) { // check if ceiling is larger than floor in Q' expression
// if ((Qprime % (8*sumKr)) > 0)
// Qprime = 1+(Qprime/(8*sumKr));
// else
// Qprime = Qprime/(8*sumKr);
// }
// G = nb_rb * (12 * Q_m) * (ulsch_harq->Nsymb_pusch);
// Q_CQI = Q_m * Qprime;
// #ifdef DEBUG_ULSCH_DECODING
// printf("ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d\n",G,Q_RI,Q_CQI,L,ulsch_harq->Or1,ulsch_harq->O_ACK);
// #endif
// G = G - Q_RI - Q_CQI;
/* ulsch_harq->G = G;
if ((int)G < 0) {
LOG_E(PHY,"FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI);
return(-1);
}
//H = G + Q_CQI;
H = G ;
Hprime = H/Q_m;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
//start_meas_NB_IoT(&eNB->ulsch_demultiplexing_stats);
//Hpp = Hprime + Qprime_RI;
Hpp = Hprime;
// Cmux = ulsch_harq->Nsymb_pusch;
// unsigned int Nsymb_UL, Nslot_UL; // NB_IoT: these parameters should included in ulsch_harq
// Cmux = (Nsymb_UL-1)*Nslot_UL;
// Cmux = (ulsch_harq->Nsymb_UL-1)*ulsch_harq->Nslot_UL; // see definition in 36.212, Section 6.3.2, but not consistent with definition
// of RU in 36.211, Section 10.1.2.3. Maybe prefer the following:
Cmux = (ulsch_harq->Nsymb_UL)*ulsch_harq->Nslot_UL;
Rmux_prime = Hpp/Cmux;
// Clear "tag" interleaving matrix to allow for CQI/DATA identification
memset(ytag,0,Cmux*Rmux_prime);
i = 0;
memset(y,LTE_NULL_NB_IoT,Q_m*Hpp);
// read in buffer and unscramble llrs for everything but placeholder bits
// llrs stored per symbol correspond to columns of interleaving matrix
s = lte_gold_unscram_NB_IoT(&x1, &x2, 1);
i2 = 0;*/
// for (i=0; i<((Hpp*Q_m)>>5); i++) {
/*
for (j=0; j<32; j++) {
cseq[i2++] = (int16_t)((((s>>j)&1)<<1)-1);
}
*/
/* #if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut_NB_IoT)[(s&65535)<<1];
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut_NB_IoT)[1+((s&65535)<<1)];
s>>=16;
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut_NB_IoT)[(s&65535)<<1];
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut_NB_IoT)[1+((s&65535)<<1)];
#else
((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut_NB_IoT)[s&65535];
((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut_NB_IoT)[(s>>16)&65535];
#endif
#elif defined(__arm__)
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut_NB_IoT)[(s&65535)<<1];
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut_NB_IoT)[1+((s&65535)<<1)];
s>>=16;
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut_NB_IoT)[(s&65535)<<1];
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut_NB_IoT)[1+((s&65535)<<1)];
#endif
s = lte_gold_unscram_NB_IoT(&x1, &x2, 0);
}
*/
// printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
// if (frame_parms->Ncp == 0)
// columnset = cs_ri_normal_NB_IoT;
// else
// columnset = cs_ri_extended_NB_IoT;
// j = 0;
// for (i=0; i<Qprime_RI; i++) {
// r = Rmux_prime - 1 - (i>>2);
// /*
// for (q=0;q<Q_m;q++)
// ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_RI[(q+(Q_m*i))%len_RI];
// */
// off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
// cseq[off+1] = cseq[off]; // PUSCH_y
// for (q=2; q<Q_m; q++)
// cseq[off+q] = -1; // PUSCH_x
// j = (j+3)&3;
// }
// // printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0]);
// // HARQ-ACK Bits (Note these overwrite some bits)
// if (frame_parms->Ncp == 0)
// columnset = cs_ack_normal_NB_IoT;
// else
// columnset = cs_ack_extended_NB_IoT;
// j = 0;
// for (i=0; i<Qprime_ACK; i++) {
// r = Rmux_prime - 1 - (i>>2);
// off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
// if (ulsch_harq->O_ACK == 1) {
// if (ulsch->bundling==0)
// cseq[off+1] = cseq[off]; // PUSCH_y
// for (q=2; q<Q_m; q++)
// cseq[off+q] = -1; // PUSCH_x
// } else if (ulsch_harq->O_ACK == 2) {
// for (q=2; q<Q_m; q++)
// cseq[off+q] = -1; // PUSCH_x
// }
// #ifdef DEBUG_ULSCH_DECODING
// printf("ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d\n",i,r,j,columnset[j]);
// #endif
// j=(j+3)&3;
// }
/*
i = 0;
switch (Q_m) {
case 1:
for (j=0; j<Cmux; j++) {
y[j] = cseq[j]*ulsch_llr[j];
}
break;
case 2:
for (j=0; j<Cmux; j++) {
i2 = j<<1;
for (r=0; r<Rmux_prime; r++) {
c = cseq[i];
// printf("ulsch %d: %d * ",i,c);
y[i2++] = c*ulsch_llr[i++];
// printf("%d\n",ulsch_llr[i-1]);
c = cseq[i];
// printf("ulsch %d: %d * ",i,c);
y[i2] = c*ulsch_llr[i++];
// printf("%d\n",ulsch_llr[i-1]);
i2 =(i2+(Cmux<<1)-1);
}
}
break;
*/
// case 4:
// for (j=0; j<Cmux; j++) {
// i2 = j<<2;
// for (r=0; r<Rmux_prime; r++) {
// /*
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2] = c*ulsch_llr[i++];
// i2=(i2+(Cmux<<2)-3);
// */
// // slightly more optimized version (equivalent to above) for 16QAM to improve computational performance
// *(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64*)&ulsch_llr[i],*(__m64*)&cseq[i]);i+=4;i2+=(Cmux<<2);
// }
// }
// break;
// case 6:
// for (j=0; j<Cmux; j++) {
// i2 = j*6;
// for (r=0; r<Rmux_prime; r++) {
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2++] = c*ulsch_llr[i++];
// c = cseq[i];
// y[i2] = c*ulsch_llr[i++];
// i2 =(i2+(Cmux*6)-5);
// }
// }
// break;
// }
// if (i!=(H+Q_RI))
// if (i!=(H))
// LOG_D(PHY,"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)\n",i,H+Q_RI);
// HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR)
// if (frame_parms->Ncp == 0)
// columnset = cs_ack_normal_NB_IoT;
// else
// columnset = cs_ack_extended_NB_IoT;
// j=0;
// if (ulsch_harq->O_ACK == 1) {
// switch (Q_m) {
// case 2:
// len_ACK = 2;
// break;
// case 4:
// len_ACK = 4;
// break;
// case 6:
// len_ACK = 6;
// break;
// }
// }
// if (ulsch_harq->O_ACK == 2) {
// switch (Q_m) {
// case 2:
// len_ACK = 6;
// break;
// case 4:
// len_ACK = 12;
// break;
// case 6:
// len_ACK = 18;
// break;
// }
// }
// if (ulsch_harq->O_ACK > 2) {
// LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n");
// return(-1);
// }
// for (i=0; i<len_ACK; i++)
// ulsch_harq->q_ACK[i] = 0;
// for (i=0; i<Qprime_ACK; i++) {
// r = Rmux_prime -1 - (i>>2);
// for (q=0; q<Q_m; q++) {
// if (y[q+(Q_m*((r*Cmux) + columnset[j]))]!=0)
// ulsch_harq->q_ACK[(q+(Q_m*i))%len_ACK] += y[q+(Q_m*((r*Cmux) + columnset[j]))];
// y[q+(Q_m*((r*Cmux) + columnset[j]))] = 0; // NULL LLRs in ACK positions
// }
// j = (j+3)&3;
// }
// // printf("after ACKNAK c[%d] = %p\n",0,ulsch_harq->c[0]);
// // RI BITS
// if (ulsch_harq->O_RI == 1) {
// switch (Q_m) {
// case 2:
// len_RI = 2;
// break;
// case 4:
// len_RI = 4;
// break;
// case 6:
// len_RI = 6;
// break;
// }
// }
// if (ulsch_harq->O_RI > 1) {
// LOG_E(PHY,"ulsch_decoding: FATAL, RI cannot be more than 1 bit yet\n");
// return(-1);
// }
// for (i=0; i<len_RI; i++)
// ulsch_harq->q_RI[i] = 0;
// if (frame_parms->Ncp == 0)
// columnset = cs_ri_normal_NB_IoT;
// else
// columnset = cs_ri_extended_NB_IoT;
// j=0;
// for (i=0; i<Qprime_RI; i++) {
// r = Rmux_prime -1 - (i>>2);
// for (q=0; q<Q_m; q++)
// ulsch_harq->q_RI[(q+(Q_m*i))%len_RI] += y[q+(Q_m*((r*Cmux) + columnset[j]))];
// ytag[(r*Cmux) + columnset[j]] = LTE_NULL_NB_IoT;
// j = (j+3)&3;
// }
// printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]);
// CQI and Data bits
// j = 0;
// j2 = 0;
// r=0;
// if (Q_RI>0) {
// for (i=0; i<(Q_CQI/Q_m); i++) {
// while (ytag[j]==LTE_NULL_NB_IoT) {
// j++;
// j2+=Q_m;
// }
// for (q=0; q<Q_m; q++) {
// ys = y[q+j2];
// if (ys>127)
// ulsch_harq->q[q+(Q_m*i)] = 127;
// else if (ys<-128)
// ulsch_harq->q[q+(Q_m*i)] = -128;
// else
// ulsch_harq->q[q+(Q_m*i)] = ys;
// }
// j2+=Q_m;
// }
// switch (Q_m) {
// case 2:
// for (iprime=0; iprime<G;) {
// while (ytag[j]==LTE_NULL_NB_IoT) {
// j++;
// j2+=2;
// }
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// }
// break;
// case 4:
// for (iprime=0; iprime<G;) {
// while (ytag[j]==LTE_NULL_NB_IoT) {
// j++;
// j2+=4;
// }
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// }
// break;
// case 6:
// for (iprime=0; iprime<G;) {
// while (ytag[j]==LTE_NULL_NB_IoT) {
// j++;
// j2+=6;
// }
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// ulsch_harq->e[iprime++] = y[j2++];
// }
// break;
// }
// } // Q_RI>0
// else {
// for (i=0; i<(Q_CQI/Q_m); i++) {
// for (q=0; q<Q_m; q++) {
// ys = y[q+j2];
// if (ys>127)
// ulsch_harq->q[q+(Q_m*i)] = 127;
// else if (ys<-128)
// ulsch_harq->q[q+(Q_m*i)] = -128;
// else
// ulsch_harq->q[q+(Q_m*i)] = ys;
// }
// j2+=Q_m;
// }
/* To be improved according to alignment of j2
#if defined(__x86_64__)||defined(__i386__)
#ifndef __AVX2__
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((__m128i *)&ulsch_harq->e[iprime]) = *((__m128i *)&y[j2]);
#else
for (iprime=0; iprime<G;iprime+=16,j2+=16)
*((__m256i *)&ulsch_harq->e[iprime]) = *((__m256i *)&y[j2]);
#endif
#elif defined(__arm__)
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((int16x8_t *)&ulsch_harq->e[iprime]) = *((int16x8_t *)&y[j2]);
#endif
*/
// int16_t *yp,*ep;
/* for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0];
iprime<G;
iprime+=8,j2+=8,ep+=8,yp+=8) {
ep[0] = yp[0];
ep[1] = yp[1];
ep[2] = yp[2];
ep[3] = yp[3];
ep[4] = yp[4];
ep[5] = yp[5];
ep[6] = yp[6];
ep[7] = yp[7];
}
*/
//stop_meas_NB_IoT(&eNB->ulsch_demultiplexing_stats);
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G);
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC
/*
// HARQ-ACK
wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3);
if (ulsch_harq->O_ACK == 1) {
ulsch_harq->q_ACK[0] *= wACK_RX_NB_IoT[wACK_idx][0];
ulsch_harq->q_ACK[0] += (ulsch->bundling==0) ? ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] : ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][1];
if (ulsch_harq->q_ACK[0] < 0)
ulsch_harq->o_ACK[0] = 0;
else
ulsch_harq->o_ACK[0] = 1;
}
if (ulsch_harq->O_ACK == 2) {
switch (Q_m) {
case 2:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[3]*wACK_RX_NB_IoT[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[4]*wACK_RX_NB_IoT[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[2]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX_NB_IoT[wACK_idx][1];
break;
// case 4:
// ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX_NB_IoT[wACK_idx][1];
// ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[8]*wACK_RX_NB_IoT[wACK_idx][1];
// ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[4]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[9]*wACK_RX_NB_IoT[wACK_idx][1];
// break;
// case 6:
// ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[7]*wACK_RX_NB_IoT[wACK_idx][1];
// ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[12]*wACK_RX_NB_IoT[wACK_idx][1];
// ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[6]*wACK_RX_NB_IoT[wACK_idx][0] + ulsch_harq->q_ACK[13]*wACK_RX_NB_IoT[wACK_idx][1];
// break;
}
ulsch_harq->o_ACK[0] = 1;
ulsch_harq->o_ACK[1] = 1;
metric = ulsch_harq->q_ACK[0]+ulsch_harq->q_ACK[1]-ulsch_harq->q_ACK[2];
metric_new = -ulsch_harq->q_ACK[0]+ulsch_harq->q_ACK[1]+ulsch_harq->q_ACK[2];
if (metric_new > metric) {
ulsch_harq->o_ACK[0]=0;
ulsch_harq->o_ACK[1]=1;
metric = metric_new;
}
metric_new = ulsch_harq->q_ACK[0]-ulsch_harq->q_ACK[1]+ulsch_harq->q_ACK[2];
if (metric_new > metric) {
ulsch_harq->o_ACK[0] = 1;
ulsch_harq->o_ACK[1] = 0;
metric = metric_new;
}
metric_new = -ulsch_harq->q_ACK[0]-ulsch_harq->q_ACK[1]-ulsch_harq->q_ACK[2];
if (metric_new > metric) {
ulsch_harq->o_ACK[0] = 0;
ulsch_harq->o_ACK[1] = 0;
metric = metric_new;
}
}
// RI
// rank 1
if ((ulsch_harq->O_RI == 1) && (Qprime_RI > 0)) {
ulsch_harq->o_RI[0] = ((ulsch_harq->q_RI[0] + ulsch_harq->q_RI[Q_m/2]) > 0) ? 0 : 1;
}
// CQI
// printf("before cqi c[%d] = %p\n",0,ulsch_harq->c[0]);
ulsch_harq->cqi_crc_status = 0;
if (Q_CQI>0) {
memset((void *)&dummy_w_cc[0],0,3*(ulsch_harq->Or1+8+32));
O_RCC = generate_dummy_w_cc_NB_IoT(ulsch_harq->Or1+8,
&dummy_w_cc[0]);
lte_rate_matching_cc_rx_NB_IoT(O_RCC,
Q_CQI,
ulsch_harq->o_w,
dummy_w_cc,
ulsch_harq->q);
sub_block_deinterleaving_cc_NB_IoT((unsigned int)(ulsch_harq->Or1+8),
&ulsch_harq->o_d[96],
&ulsch_harq->o_w[0]);
memset(o_flip,0,1+((8+ulsch_harq->Or1)/8));
phy_viterbi_lte_sse2_NB_IoT(ulsch_harq->o_d+96,o_flip,8+ulsch_harq->Or1);
if (extract_cqi_crc_NB_IoT(o_flip,ulsch_harq->Or1) == (crc8_NB_IoT(o_flip,ulsch_harq->Or1)>>24))
ulsch_harq->cqi_crc_status = 1;
if (ulsch->harq_process->Or1<=32) {
ulsch_harq->o[3] = o_flip[0] ;
ulsch_harq->o[2] = o_flip[1] ;
ulsch_harq->o[1] = o_flip[2] ;
ulsch_harq->o[0] = o_flip[3] ;
} else {
ulsch_harq->o[7] = o_flip[0] ;
ulsch_harq->o[6] = o_flip[1] ;
ulsch_harq->o[5] = o_flip[2] ;
ulsch_harq->o[4] = o_flip[3] ;
ulsch_harq->o[3] = o_flip[4] ;
ulsch_harq->o[2] = o_flip[5] ;
ulsch_harq->o[1] = o_flip[6] ;
ulsch_harq->o[0] = o_flip[7] ;
}
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding: Or1=%d\n",ulsch_harq->Or1);
for (i=0; i<1+((8+ulsch_harq->Or1)/8); i++)
printf("ulsch_decoding: O[%d] %d\n",i,ulsch_harq->o[i]);
if (ulsch_harq->cqi_crc_status == 1)
printf("RX CQI CRC OK (%x)\n",extract_cqi_crc_NB_IoT(o_flip,ulsch_harq->Or1));
else
printf("RX CQI CRC NOT OK (%x)\n",extract_cqi_crc_NB_IoT(o_flip,ulsch_harq->Or1));
#endif
}
*/
// Do ULSCH Decoding for data portion
/*
ret = eNB->td(eNB,UE_id,harq_pid,llr8_flag);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0);
return(ret);
}
*/
/*
#ifdef PHY_ABSTRACTION
#ifdef PHY_ABSTRACTION_UL
int ulsch_abstraction(double* sinr_dB, uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb)
{
int index,ii;
double sinr_eff = 0;
int rb_count = 0;
int offset;
double bler = 0;
TM = TM-1;
sinr_eff = sinr_dB[frb]; //the single sinr_eff value we calculated with MMSE FDE formula in init_snr_up function
sinr_eff *= 10;
sinr_eff = floor(sinr_eff);
sinr_eff /= 10;
LOG_D(PHY,"[ABSTRACTION] sinr_eff after rounding = %f\n",sinr_eff);
for (index = 0; index < 16; index++) {
if(index == 0) {
if (sinr_eff < sinr_bler_map_up[mcs][0][index]) {
bler = 1;
break;
}
}
if (sinr_eff == sinr_bler_map_up[mcs][0][index]) {
bler = sinr_bler_map_up[mcs][1][index];
}
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) {
LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(0);
} else {
LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(1);
}
#endif
}
int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb)
{
int index;
double sinr_eff = 0;
double sinr_db1 = 0;
double sinr_db2 = 0;
double SI=0;
double RBIR=0;
int rb_count = 0;
int offset, M=0;
double bler = 0;
int start,middle,end;
TM = TM-1;
for (offset = frb; offset <= (frb + nrb -1); offset++) {
rb_count++;
//we need to do the table lookups here for the mutual information corresponding to the certain sinr_dB.
sinr_db1 = sinr_dB[offset*2];
sinr_db2 = sinr_dB[offset*2+1];
printf("sinr_db1=%f\n,sinr_db2=%f\n",sinr_db1,sinr_db2);
//rounding up for the table lookup
sinr_db1 *= 10;
sinr_db2 *= 10;
sinr_db1 = floor(sinr_db1);
sinr_db2 = floor(sinr_db2);
if ((int)sinr_db1%2) {
sinr_db1 += 1;
}
if ((int)sinr_db2%2) {
sinr_db2 += 1;
}
sinr_db1 /= 10;
sinr_db2 /= 10;
if(mcs<10) {
//for sinr_db1
for (index = 0; index < 162; index++) {
if (sinr_db1 < MI_map_4qam[0][0]) {
SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=2;
break;
}
if (sinr_db1 > MI_map_4qam[0][161]) {
SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]);
M +=2;
break;
}
if (sinr_db1 == MI_map_4qam[0][index]) {
SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=2;
break;
}
}
//for sinr_db2
for (index = 0; index < 162; index++) {
if (sinr_db2 < MI_map_4qam[0][0]) {
SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=2;
break;
}
if (sinr_db2 > MI_map_4qam[0][161]) {
SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]);
M +=2;
break;
}
if (sinr_db2 == MI_map_4qam[0][index]) {
SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=2;
break;
}
}
} else if(mcs>9 && mcs<17) {
//for sinr_db1
for (index = 0; index < 197; index++) {
if (sinr_db1 < MI_map_16qam[0][0]) {
SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
if (sinr_db1 > MI_map_16qam[0][196]) {
SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
if (sinr_db1 == MI_map_16qam[0][index]) {
SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
}
//for sinr_db2
for (index = 0; index < 197; index++) {
if (sinr_db2 < MI_map_16qam[0][0]) {
SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
if (sinr_db2 > MI_map_16qam[0][196]) {
SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
if (sinr_db2 == MI_map_16qam[0][index]) {
SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
}
} else if(mcs>16 && mcs<22) {
//for sinr_db1
for (index = 0; index < 227; index++) {
if (sinr_db1 < MI_map_64qam[0][0]) {
SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db1 > MI_map_64qam[0][226]) {
SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db1 == MI_map_64qam[0][index]) {
SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
}
//for sinr_db2
for (index = 0; index < 227; index++) {
if (sinr_db2 < MI_map_64qam[0][0]) {
SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db2 > MI_map_64qam[0][226]) {
SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db2 == MI_map_64qam[0][index]) {
SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
}
}
}
// }
RBIR = SI/M;
//Now RBIR->SINR_effective Mapping
//binary search method is performed here
if(mcs<10) {
start = 0;
end = 161;
middle = end/2;
if (RBIR <= MI_map_4qam[2][start]) {
sinr_eff = MI_map_4qam[0][start];
} else {
if (RBIR >= MI_map_4qam[2][end])
sinr_eff = MI_map_4qam[0][end];
else {
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_4qam[2][middle]) {
end = middle;
middle = end/2;
} else {
start = middle;
middle = (end-middle)/2;
}
}
for (; end>start; end--) {
if ((RBIR < MI_map_4qam[2][end]) && (RBIR > MI_map_4qam[2][end-2])) {
sinr_eff = MI_map_4qam[0][end-1];
break;
}
}
}
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
}
else if (mcs>9 && mcs<17) {
start = 0;
end = 196;
middle = end/2;
if (RBIR <= MI_map_16qam[2][start]) {
sinr_eff = MI_map_16qam[0][start];
} else {
if (RBIR >= MI_map_16qam[2][end])
sinr_eff = MI_map_16qam[0][end];
else {
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_16qam[2][middle]) {
end = middle;
middle = end/2;
} else {
start = middle;
middle = (end-middle)/2;
}
}
for (; end>start; end--) {
if ((RBIR < MI_map_16qam[2][end]) && (RBIR > MI_map_16qam[2][end-2])) {
sinr_eff = MI_map_16qam[0][end-1];
break;
}
}
}
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
} else if (mcs>16) {
start = 0;
end = 226;
middle = end/2;
if (RBIR <= MI_map_64qam[2][start]) {
sinr_eff = MI_map_64qam[0][start];
} else {
if (RBIR >= MI_map_64qam[2][end])
sinr_eff = MI_map_64qam[0][end];
else {
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_64qam[2][middle]) {
end = middle;
middle = end/2;
} else {
start = middle;
middle = (end-middle)/2;
}
}
for (; end>start; end--) {
if ((RBIR < MI_map_64qam[2][end]) && (RBIR > MI_map_64qam[2][end-2])) {
sinr_eff = MI_map_64qam[0][end-1];
break;
}
}
}
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
}
printf("SINR_Eff = %e\n",sinr_eff);
sinr_eff *= 10;
sinr_eff = floor(sinr_eff);
// if ((int)sinr_eff%2) {
// sinr_eff += 1;
// }
sinr_eff /= 10;
printf("sinr_eff after rounding = %f\n",sinr_eff);
for (index = 0; index < 16; index++) {
if(index == 0) {
if (sinr_eff < sinr_bler_map_up[mcs][0][index]) {
bler = 1;
break;
}
}
if (sinr_eff == sinr_bler_map_up[mcs][0][index]) {
bler = sinr_bler_map_up[mcs][1][index];
}
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) {
printf("abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(0);
} else {
printf("abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(1);
}
#endif
}
#endif
uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
uint8_t UE_index,
uint16_t *crnti)
{
uint8_t UE_id;
uint16_t rnti;
int subframe = proc->subframe_rx;
uint8_t harq_pid;
uint8_t CC_id = eNB->CC_id;
harq_pid = subframe2harq_pid(&eNB->frame_parms,proc->frame_rx,subframe);
rnti = eNB->ulsch[UE_index]->rnti;
#ifdef DEBUG_PHY
LOG_D(PHY,"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x\n",eNB->Mod_id,subframe,UE_index,harq_pid,rnti);
#endif
for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe & 0x1][0]->crnti)
break;
}
if (UE_id==NB_UE_INST) {
LOG_W(PHY,"[eNB %d] ulsch_decoding_emul: FATAL, didn't find UE with rnti %x (UE index %d)\n",
eNB->Mod_id, rnti, UE_index);
return(1+eNB->ulsch[UE_id]->max_turbo_iterations);
} else {
LOG_D(PHY,"[eNB %d] Found UE with rnti %x => UE_id %d\n",eNB->Mod_id, rnti, UE_id);
}
if (PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status == CBA_ACTIVE) {
*crnti = rnti;
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status=IDLE;
} else
*crnti = 0x0;
// Do abstraction here to determine if packet it in error
/// if (ulsch_abstraction_MIESM(eNB->sinr_dB_eNB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb) == 1)
flag = 1;
else flag = 0;///
//SINRdbPost = eNB->sinr_dB_eNB;
mcsPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,
nrbPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb;
frbPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb;
if(nrbPost > 0)
{
SINRdbPost = eNB->sinr_dB_eNB;
ULflag1 = 1;
}
else
{
SINRdbPost = NULL ;
ULflag1 = 0 ;
}//
//
// write_output("postprocSINR.m","SINReNB",eNB->sinr_dB,301,1,7);
//Yazdir buraya her frame icin 300 eNb
// fprintf(SINRrx,"%e,%e,%e,%e;\n",SINRdbPost);
//fprintf(SINRrx,"%e\n",SINRdbPost);
// fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
// if (ulsch_abstraction(eNB->sinr_dB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb) == 1) {
if (1) {
LOG_D(PHY,"ulsch_decoding_emul abstraction successful\n");
memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->b,
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->b,
eNB->ulsch[UE_index]->harq_processes[harq_pid]->TBS>>3);
// get local ue's ack
if ((UE_index >= oai_emulation.info.first_ue_local) ||(UE_index <(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local))) {
get_ack(&eNB->frame_parms,
PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0][0]->harq_ack,
proc->subframe_tx,
proc->subframe_rx,
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0);
} else { // get remote UEs' ack
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0];
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[1];
}
// Do abstraction of PUSCH feedback
#ifdef DEBUG_PHY
LOG_D(PHY,"[eNB %d][EMUL] ue index %d UE_id %d: subframe %d : o_ACK (%d %d), cqi (val %d, len %d)\n",
eNB->Mod_id,UE_index, UE_id, subframe,eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0],
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1],
((HLC_subband_cqi_rank1_2A_5MHz *)PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o)->cqi1,
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O);
#endif
eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or1 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O;
eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or2 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O;
eNB->ulsch[UE_index]->harq_processes[harq_pid]->uci_format = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->uci_format;
memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o,MAX_CQI_BYTES);
memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_RI,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_RI,2);
eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 1;
return(1);
} else {
LOG_W(PHY,"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d\n",eNB->Mod_id,UE_index);
eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 0;
// retransmission
return(1+eNB->ulsch[UE_index]->max_turbo_iterations);
}
}
#endif
*/
...@@ -119,7 +119,6 @@ enum transmission_access_mode { ...@@ -119,7 +119,6 @@ enum transmission_access_mode {
SCHEDULED_ACCESS, SCHEDULED_ACCESS,
CBA_ACCESS}; CBA_ACCESS};
typedef enum { typedef enum {
eNodeB_3GPP=0, // classical eNodeB function eNodeB_3GPP=0, // classical eNodeB function
eNodeB_3GPP_BBU, // eNodeB with NGFI IF5 eNodeB_3GPP_BBU, // eNodeB with NGFI IF5
...@@ -129,7 +128,6 @@ typedef enum { ...@@ -129,7 +128,6 @@ typedef enum {
NGFI_RRU_IF4p5 // NGFI_RRU (NGFI remote radio-unit,IF4p5) NGFI_RRU_IF4p5 // NGFI_RRU (NGFI remote radio-unit,IF4p5)
} eNB_func_t; } eNB_func_t;
typedef enum { typedef enum {
synch_to_ext_device=0, // synch to RF or Ethernet device synch_to_ext_device=0, // synch to RF or Ethernet device
synch_to_other // synch to another source (timer, other CC_id) synch_to_other // synch to another source (timer, other CC_id)
...@@ -748,6 +746,11 @@ typedef struct PHY_VARS_eNB_NB_IoT_s { ...@@ -748,6 +746,11 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
} PHY_VARS_eNB_NB_IoT; } PHY_VARS_eNB_NB_IoT;
typedef struct{
PHY_VARS_eNB *eNB;
PHY_VARS_eNB_NB_IoT *eNB_NB_IoT;
} eNBs_t;
//#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg //#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg
/// Top-level PHY Data Structure for UE /// Top-level PHY Data Structure for UE
......
...@@ -59,12 +59,12 @@ ...@@ -59,12 +59,12 @@
#include "defs_common.h" #include "defs_common.h"
#include "impl_defs_top.h" #include "impl_defs_top.h"
#include "LTE_UE_TRANSPORT/transport_ue.h"
#include "PHY/TOOLS/time_meas.h" #include "PHY/TOOLS/time_meas.h"
#include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_defs.h"
#include "PHY/TOOLS/tools_defs.h" #include "PHY/TOOLS/tools_defs.h"
#include "platform_types.h" #include "platform_types.h"
#include "PHY/LTE_UE_TRANSPORT/transport_ue.h" #include "LTE_UE_TRANSPORT/transport_ue.h"
#include "PHY/LTE_TRANSPORT/transport_eNB.h" // for SIC #include "PHY/LTE_TRANSPORT/transport_eNB.h" // for SIC
#include <pthread.h> #include <pthread.h>
#include "assertions.h" #include "assertions.h"
......
...@@ -73,7 +73,6 @@ ...@@ -73,7 +73,6 @@
#include "openair2/PHY_INTERFACE/IF_Module.h" #include "openair2/PHY_INTERFACE/IF_Module.h"
typedef struct RU_proc_t_s { typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor /// Pointer to associated RU descriptor
struct RU_t_s *ru; struct RU_t_s *ru;
...@@ -764,6 +763,7 @@ typedef struct { ...@@ -764,6 +763,7 @@ typedef struct {
pthread_mutex_t mutex_RUs; pthread_mutex_t mutex_RUs;
} L1_rxtx_proc_t; } L1_rxtx_proc_t;
typedef struct { typedef struct {
struct PHY_VARS_eNB_s *eNB; struct PHY_VARS_eNB_s *eNB;
int UE_id; int UE_id;
......
...@@ -109,7 +109,7 @@ ...@@ -109,7 +109,7 @@
#include "defs_eNB.h" #include "defs_eNB.h"
#include "types.h" #include "types.h"
#include "LTE_UE_TRANSPORT/transport_ue.h"
/** @addtogroup _PHY_STRUCTURES_ /** @addtogroup _PHY_STRUCTURES_
...@@ -270,6 +270,20 @@ typedef struct { ...@@ -270,6 +270,20 @@ typedef struct {
int *RX_DMA_BUFFER[2]; int *RX_DMA_BUFFER[2];
} TX_RX_VARS; } TX_RX_VARS;
/// Top-level PHY Data Structure for RN
typedef struct {
/// Module ID indicator for this instance
uint8_t Mod_id;
uint32_t frame;
// phy_vars_eNB
// phy_vars ue
// cuurently only used to store and forward the PMCH
uint8_t mch_avtive[10];
uint8_t sync_area[10]; // num SF
LTE_UE_DLSCH_t *dlsch_rn_MCH[10];
} PHY_VARS_RN;
/// Measurement Variables /// Measurement Variables
//#define NUMBER_OF_SUBBANDS_MAX 13 //#define NUMBER_OF_SUBBANDS_MAX 13
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "nfapi_vnf.h" #include "nfapi_vnf.h"
#include "nfapi_pnf.h" #include "nfapi_pnf.h"
#include "../../openair1/PHY/defs_L1_NB_IoT.h"
#include "L1_paramdef.h" #include "L1_paramdef.h"
#include "MACRLC_paramdef.h" #include "MACRLC_paramdef.h"
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
...@@ -112,6 +112,7 @@ void RCconfig_L1(void) { ...@@ -112,6 +112,7 @@ void RCconfig_L1(void) {
if (RC.eNB == NULL) { if (RC.eNB == NULL) {
RC.eNB = (PHY_VARS_eNB ** *)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **)); RC.eNB = (PHY_VARS_eNB ** *)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **));
RC.L1_NB_IoT = (PHY_VARS_eNB_NB_IoT **)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB_NB_IoT *));//Ann
LOG_I(PHY,"RC.eNB = %p\n",RC.eNB); LOG_I(PHY,"RC.eNB = %p\n",RC.eNB);
memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **)); memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB **));
RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int));
...@@ -120,6 +121,14 @@ void RCconfig_L1(void) { ...@@ -120,6 +121,14 @@ void RCconfig_L1(void) {
config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL);
if (L1_ParamList.numelt > 0) { if (L1_ParamList.numelt > 0) {
for (j = 0; j < RC.nb_nb_iot_L1_inst; j++) {//Ann
if (RC.L1_NB_IoT[j] == NULL) {
RC.L1_NB_IoT[j] = (PHY_VARS_eNB_NB_IoT *)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB_NB_IoT ));
LOG_I(PHY,"RC.L1_NB_IoT[%d] = %p\n",j,RC.L1_NB_IoT[j]);
memset(RC.L1_NB_IoT[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB_NB_IoT));
}
}
for (j = 0; j < RC.nb_L1_inst; j++) { for (j = 0; j < RC.nb_L1_inst; j++) {
RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr);
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include "init_lte.h"
//#include "PHY/extern.h"
//#include "../../../openair2/LAYER2/MAC/defs.h"
//#include "../../../openair2/LAYER2/MAC/extern.h"
//#include "UTIL/LOG/log_if.h"
//#include "PHY_INTERFACE/extern.h"
#include "../../../openair1/PHY/defs_eNB.h"
#include "../../../openair1/PHY/defs_common.h"
PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint16_t Nid_cell,
node_function_t node_function,
uint8_t abstraction_flag)
{
int i,j;
PHY_VARS_eNB* PHY_vars_eNB = malloc(sizeof(PHY_VARS_eNB));
memset(PHY_vars_eNB,0,sizeof(PHY_VARS_eNB));
PHY_vars_eNB->Mod_id=eNB_id;
PHY_vars_eNB->cooperation_flag=0;//cooperation_flag;
memcpy(&(PHY_vars_eNB->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS));
PHY_vars_eNB->frame_parms.Nid_cell = Nid_cell; ///////((Nid_cell/3)*3)+((eNB_id+Nid_cell)%3);
PHY_vars_eNB->frame_parms.nushift = PHY_vars_eNB->frame_parms.Nid_cell%6;
// for NB-IoT testing
// PHY_vars_eNB->ndlsch_SIB.content_sib1.si_rnti = 0xffff;
// PHY_vars_eNB->ndlsch_SIB.content_sib23.si_rnti = 0xffff;
////////////////////////////
phy_init_lte_eNB(PHY_vars_eNB,0,abstraction_flag);
LOG_I(PHY,"init eNB: Node Function %d\n",node_function);
LOG_I(PHY,"init eNB: Nid_cell %d\n", frame_parms->Nid_cell);
LOG_I(PHY,"init eNB: frame_type %d,tdd_config %d\n", frame_parms->frame_type,frame_parms->tdd_config);
LOG_I(PHY,"init eNB: number of ue max %d number of enb max %d number of harq pid max %d\n",
NUMBER_OF_UE_MAX, NUMBER_OF_eNB_MAX, NUMBER_OF_HARQ_PID_MAX);
LOG_I(PHY,"init eNB: N_RB_DL %d\n", frame_parms->N_RB_DL);
LOG_I(PHY,"init eNB: prach_config_index %d\n", frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex);
if (node_function >= NGFI_RRU_IF5)
// For RRU, don't allocate DLSCH/ULSCH Transport channel buffers
return (PHY_vars_eNB);
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
PHY_vars_eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL,abstraction_flag,frame_parms);
if (!PHY_vars_eNB->dlsch[i][j]) {
LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
exit(-1);
} else {
LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,PHY_vars_eNB->dlsch[i][j]);
PHY_vars_eNB->dlsch[i][j]->rnti=0;
}
}
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n", i);
PHY_vars_eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,frame_parms->N_RB_UL, abstraction_flag);
//////////////// NB-IoT testing ////////////////////////////
PHY_vars_eNB->ulsch_NB_IoT[1+i] = new_eNB_ulsch_NB_IoT(MAX_TURBO_ITERATIONS,frame_parms->N_RB_UL, abstraction_flag);
//////////////////////////////////////////////////////////////
if (!PHY_vars_eNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
// this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
PHY_vars_eNB->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2;
#ifdef LOCALIZATION
PHY_vars_eNB->ulsch[1+i]->aggregation_period_ms = 5000; // 5000 milliseconds // could be given as an argument (TBD))
struct timeval ts;
gettimeofday(&ts, NULL);
PHY_vars_eNB->ulsch[1+i]->reference_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
int j;
for (j=0; j<10; j++) {
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rss_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rssi_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_subcarrier_rss_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_advance_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_update_list[j]);
}
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rss_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rssi_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_subcarrier_rss_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_timing_advance_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_timing_update_list);
#endif
}
// ULSCH for RA
PHY_vars_eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, frame_parms->N_RB_UL, abstraction_flag);
//////////////// NB-IoT testing ////////////////////////////
PHY_vars_eNB->ulsch_NB_IoT[0] = new_eNB_ulsch_NB_IoT(MAX_TURBO_ITERATIONS, frame_parms->N_RB_UL, abstraction_flag);
////////////////////////////////////////////////////////////
if (!PHY_vars_eNB->ulsch[0]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
if (!PHY_vars_eNB->ulsch_NB_IoT[0]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
PHY_vars_eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
LOG_D(PHY,"eNB %d : SI %p\n",eNB_id,PHY_vars_eNB->dlsch_SI);
PHY_vars_eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
LOG_D(PHY,"eNB %d : RA %p\n",eNB_id,PHY_vars_eNB->dlsch_ra);
PHY_vars_eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, 0, frame_parms);
LOG_D(PHY,"eNB %d : MCH %p\n",eNB_id,PHY_vars_eNB->dlsch_MCH);
///// NB-IoT ////////////
PHY_vars_eNB->ndlsch_SIB1 = new_eNB_dlsch_NB_IoT(1,frame_parms); // frame_parms is not used , to be removed is not used in futur
PHY_vars_eNB->ndlsch_SIB23 = new_eNB_dlsch_NB_IoT(1,frame_parms);
PHY_vars_eNB->ndlsch_RAR = new_eNB_dlsch_NB_IoT(1,frame_parms);
PHY_vars_eNB->npdcch_DCI = new_eNB_dlcch_NB_IoT(frame_parms);
PHY_vars_eNB->UL_INFO.nrach_ind.nrach_pdu_list = (nfapi_nrach_indication_pdu_t *)malloc16(sizeof(nfapi_nrach_indication_pdu_t));
PHY_vars_eNB->UL_INFO.crc_ind.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc16(sizeof(nfapi_crc_indication_pdu_t));
PHY_vars_eNB->UL_INFO.RX_NPUSCH.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc16(sizeof(nfapi_rx_indication_pdu_t));
PHY_vars_eNB->UL_INFO.RX_NPUSCH.rx_pdu_list[0].data = (unsigned char*)malloc(300);
PHY_vars_eNB->UL_INFO.nb_harq_ind.nb_harq_indication_body.nb_harq_pdu_list = (nfapi_nb_harq_indication_pdu_t*)malloc16(sizeof(nfapi_nb_harq_indication_pdu_t));
//nfapi_nb_harq_indication_t nb_harq_ind
PHY_vars_eNB->ndlsch_SIB1->rnti = 0xffff;
PHY_vars_eNB->ndlsch_SIB23->rnti = 0xffff;
PHY_vars_eNB->rx_total_gain_dB=130;
for(i=0; i<NUMBER_OF_UE_MAX; i++)
PHY_vars_eNB->mu_mimo_mode[i].dl_pow_off = 2;
PHY_vars_eNB->check_for_total_transmissions = 0;
PHY_vars_eNB->check_for_MUMIMO_transmissions = 0;
PHY_vars_eNB->FULL_MUMIMO_transmissions = 0;
PHY_vars_eNB->check_for_SUMIMO_transmissions = 0;
PHY_vars_eNB->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
return (PHY_vars_eNB);
}
PHY_VARS_eNB_NB_IoT* init_lte_eNB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t Nid_cell,
eNB_func_NB_IoT_t node_function,
uint8_t abstraction_flag)
{
//int i;
PHY_VARS_eNB_NB_IoT* PHY_vars_eNB = malloc(sizeof(PHY_VARS_eNB_NB_IoT));
memset(PHY_vars_eNB,0,sizeof(PHY_VARS_eNB_NB_IoT));
PHY_vars_eNB->Mod_id=eNB_id;
PHY_vars_eNB->cooperation_flag=0;//cooperation_flag;
memcpy(&(PHY_vars_eNB->frame_parms), frame_parms, sizeof(NB_IoT_DL_FRAME_PARMS));
//PHY_vars_eNB->frame_parms.Nid_cell = ((Nid_cell/3)*3)+((eNB_id+Nid_cell)%3);
//PHY_vars_eNB->frame_parms.nushift = PHY_vars_eNB->frame_parms.Nid_cell%6;
PHY_vars_eNB->frame_parms.Nid_cell = Nid_cell; ///////((Nid_cell/3)*3)+((eNB_id+Nid_cell)%3);
PHY_vars_eNB->frame_parms.nushift = PHY_vars_eNB->frame_parms.Nid_cell%6;
phy_init_lte_eNB_NB_IoT(PHY_vars_eNB,0,abstraction_flag);
// for NB-IoT testing
// PHY_vars_eNB->ndlsch_SIB.content_sib1.si_rnti = 0xffff;
// PHY_vars_eNB->ndlsch_SIB.content_sib23.si_rnti = 0xffff;
////////////////////////////
/*LOG_I(PHY,"init eNB: Node Function %d\n",node_function);
LOG_I(PHY,"init eNB: Nid_cell %d\n", frame_parms->Nid_cell);
LOG_I(PHY,"init eNB: frame_type %d,tdd_config %d\n", frame_parms->frame_type,frame_parms->tdd_config);
LOG_I(PHY,"init eNB: number of ue max %d number of enb max %d number of harq pid max %d\n",
NUMBER_OF_UE_MAX, NUMBER_OF_eNB_MAX, NUMBER_OF_HARQ_PID_MAX);
LOG_I(PHY,"init eNB: N_RB_DL %d\n", frame_parms->N_RB_DL);
LOG_I(PHY,"init eNB: prach_config_index %d\n", frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex);
*/
/*
if (node_function >= NGFI_RRU_IF5)
// For RRU, don't allocate DLSCH/ULSCH Transport channel buffers
return (PHY_vars_eNB);
*/
/*
for (i=0; i<NUMBER_OF_UE_MAX_NB_IoT; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
PHY_vars_eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL,abstraction_flag,frame_parms);
if (!PHY_vars_eNB->dlsch[i][j]) {
LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
exit(-1);
} else {
LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,PHY_vars_eNB->dlsch[i][j]);
PHY_vars_eNB->dlsch[i][j]->rnti=0;
}
}
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n", i);
PHY_vars_eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,frame_parms->N_RB_UL, abstraction_flag);
if (!PHY_vars_eNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
*/
// this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
PHY_vars_eNB->transmission_mode[0] = 1 ;
/*#ifdef LOCALIZATION
PHY_vars_eNB->ulsch[1+i]->aggregation_period_ms = 5000; // 5000 milliseconds // could be given as an argument (TBD))
struct timeval ts;
gettimeofday(&ts, NULL);
PHY_vars_eNB->ulsch[1+i]->reference_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
int j;
for (j=0; j<10; j++) {
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rss_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rssi_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_subcarrier_rss_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_advance_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_update_list[j]);
}
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rss_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rssi_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_subcarrier_rss_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_timing_advance_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_timing_update_list);
#endif*/
// }
/*
// ULSCH for RA
PHY_vars_eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, frame_parms->N_RB_UL, abstraction_flag);
if (!PHY_vars_eNB->ulsch[0]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
PHY_vars_eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
LOG_D(PHY,"eNB %d : SI %p\n",eNB_id,PHY_vars_eNB->dlsch_SI);
PHY_vars_eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
LOG_D(PHY,"eNB %d : RA %p\n",eNB_id,PHY_vars_eNB->dlsch_ra);
PHY_vars_eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, 0, frame_parms);
LOG_D(PHY,"eNB %d : MCH %p\n",eNB_id,PHY_vars_eNB->dlsch_MCH);
*/
PHY_vars_eNB->rx_total_gain_dB=130;
/* for(i=0; i<NUMBER_OF_UE_MAX; i++)
PHY_vars_eNB->mu_mimo_mode[i].dl_pow_off = 2;
PHY_vars_eNB->check_for_total_transmissions = 0;
PHY_vars_eNB->check_for_MUMIMO_transmissions = 0;
PHY_vars_eNB->FULL_MUMIMO_transmissions = 0;
PHY_vars_eNB->check_for_SUMIMO_transmissions = 0;
PHY_vars_eNB->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
*/
return (PHY_vars_eNB);
}
/*this is a function just for initialization of NB-IoT stuff*/
/*
void init_lte_eNB_NB(
PHY_VARS_eNB *PHY_vars_eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t Nid_cell,
eNB_func_t node_function,
int8_t abstraction_flag)
{
int i,j;
memset(PHY_vars_eNB,0,sizeof(PHY_VARS_eNB));
PHY_vars_eNB->Mod_id=eNB_id;
PHY_vars_eNB->cooperation_flag=0;//cooperation_flag;
memcpy(&(PHY_vars_eNB->frame_parms_nb_iot), frame_parms, sizeof(NB_IoT_DL_FRAME_PARMS));
PHY_vars_eNB->frame_parms_nb_iot.Nid_cell = ((Nid_cell/3)*3)+((eNB_id+Nid_cell)%3); //XXX NB_IoT ????
PHY_vars_eNB->frame_parms_nb_iot.nushift = PHY_vars_eNB->frame_parms.Nid_cell%6;
phy_init_lte_eNB(PHY_vars_eNB,0,abstraction_flag);
LOG_I(PHY,"init eNB NB_IoT: Node Function %d\n",node_function);
LOG_I(PHY,"init eNB NB_IoT: Nid_cell %d\n", frame_parms->Nid_cell);
LOG_I(PHY,"init eNB NB_IoT: number of ue max %d number of enb max %d \n",
NUMBER_OF_UE_MAX, NUMBER_OF_eNB_MAX);
//LOG_I(PHY,"init eNB NB_IoT: N_RB_DL %d\n", frame_parms->N_RB_DL);
//LOG_I(PHY,"init eNB NB_IoT: prach_config_index %d\n", frame_parms->nprach_config_common.prach_ConfigInfo.prach_ConfigIndex);
if (node_function >= NGFI_RRU_IF5)
// For RRU, don't allocate DLSCH/ULSCH Transport channel buffers
return;
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_I(PHY,"[NB-IoT] Allocating Transport Channel Buffers for NDLSCH, UE %d\n",i);
PHY_vars_eNB->ndlsch[i] = new_eNB_dlsch_NB_IoT(NSOFT,abstraction_flag,frame_parms);
if (!PHY_vars_eNB->ndlsch[i]) {
LOG_E(PHY,"Can't get eNB ndlsch structures for UE %d \n", i);
exit(-1);
} else {
LOG_D(PHY,"dlsch[%d] => %p\n",i,PHY_vars_eNB->ndlsch[i]);
PHY_vars_eNB->ndlsch[i]->rnti=0;
}
LOG_I(PHY," [NB-IoT] Allocating Transport Channel Buffer for ULSCH, UE %d\n", i);
PHY_vars_eNB->nulsch[1+i] = new_eNB_ulsch_NB(abstraction_flag);
if (!PHY_vars_eNB->nulsch[1+i]) {
LOG_E(PHY,"Can't get eNB nulsch structures\n");
exit(-1);
}
}
// ULSCH for RA
PHY_vars_eNB->nulsch[0] = new_eNB_ulsch_NB(abstraction_flag);
if (!PHY_vars_eNB->nulsch[0]) {
LOG_E(PHY,"Can't get eNB nulsch structures\n");
exit(-1);
}
PHY_vars_eNB->dlsch_SI_NB = new_eNB_dlsch_NB_IoT(NSOFT, abstraction_flag, frame_parms);
LOG_D(PHY,"[NB-IoT] eNB %d : SI %p\n",eNB_id,PHY_vars_eNB->dlsch_SI_NB);
PHY_vars_eNB->dlsch_ra_NB = new_eNB_dlsch_NB_IoT(NSOFT, abstraction_flag, frame_parms);
LOG_D(PHY,"[NB-IoT] eNB %d : RA %p\n",eNB_id,PHY_vars_eNB->dlsch_ra_NB);
//already set in the LTE function version
//PHY_vars_eNB->rx_total_gain_dB=130;
// for(i=0; i<NUMBER_OF_UE_MAX; i++)
// PHY_vars_eNB->mu_mimo_mode[i].dl_pow_off = 2;
//
// PHY_vars_eNB->check_for_total_transmissions = 0;
//
// PHY_vars_eNB->check_for_MUMIMO_transmissions = 0;
//
// PHY_vars_eNB->FULL_MUMIMO_transmissions = 0;
//
// PHY_vars_eNB->check_for_SUMIMO_transmissions = 0;
//
// PHY_vars_eNB->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
return;
}
*/
PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag)
{
int i,j;
PHY_VARS_UE* PHY_vars_UE = malloc(sizeof(PHY_VARS_UE));
memset(PHY_vars_UE,0,sizeof(PHY_VARS_UE));
PHY_vars_UE->Mod_id=UE_id;
memcpy(&(PHY_vars_UE->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS));
phy_init_lte_ue(PHY_vars_UE,1,abstraction_flag);
for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
for (j=0; j<2; j++) { // 2CWs
for (int l=0; l<2; l++){ // 2Threads
PHY_vars_UE->dlsch[l][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag);
if (!PHY_vars_UE->dlsch[l][i][j]) {
LOG_E(PHY,"Can't get ue dlsch structures\n");
exit(-1);
} else
LOG_D(PHY,"dlsch[%d][%d] => %p\n",UE_id,i,PHY_vars_UE->dlsch[l][i][j]);
}
}
PHY_vars_UE->ulsch[i] = new_ue_ulsch(frame_parms->N_RB_UL, abstraction_flag);
if (!PHY_vars_UE->ulsch[i]) {
LOG_E(PHY,"Can't get ue ulsch structures\n");
exit(-1);
}
PHY_vars_UE->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag);
PHY_vars_UE->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag);
PHY_vars_UE->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2;
}
PHY_vars_UE->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
PHY_vars_UE->dlsch_MCH[0] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,frame_parms->N_RB_DL,0);
return (PHY_vars_UE);
}
PHY_VARS_RN* init_lte_RN(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t RN_id,
uint8_t eMBMS_active_state)
{
int i;
PHY_VARS_RN* PHY_vars_RN = malloc(sizeof(PHY_VARS_RN));
memset(PHY_vars_RN,0,sizeof(PHY_VARS_RN));
PHY_vars_RN->Mod_id=RN_id;
if (eMBMS_active_state == multicast_relay) {
for (i=0; i < 10 ; i++) { // num SF in a frame
PHY_vars_RN->dlsch_rn_MCH[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,frame_parms->N_RB_DL, 0);
LOG_D(PHY,"eNB %d : MCH[%d] %p\n",RN_id,i,PHY_vars_RN->dlsch_rn_MCH[i]);
}
} else {
PHY_vars_RN->dlsch_rn_MCH[0] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, 0);
LOG_D(PHY,"eNB %d : MCH[0] %p\n",RN_id,PHY_vars_RN->dlsch_rn_MCH[0]);
}
return (PHY_vars_RN);
}
void init_lte_vars(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs],
uint8_t frame_type,
uint8_t tdd_config,
uint8_t tdd_config_S,
uint8_t extended_prefix_flag,
uint8_t N_RB_DL,
uint16_t Nid_cell,
uint8_t cooperation_flag,
uint8_t nb_antenna_ports,
uint8_t abstraction_flag,
int nb_antennas_rx,
int nb_antennas_tx,
int nb_antennas_rx_ue,
uint8_t eMBMS_active_state)
{
uint8_t eNB_id,UE_id,RN_id,CC_id;
mac_xface = malloc(sizeof(MAC_xface));
memset(mac_xface, 0, sizeof(MAC_xface));
LOG_I(PHY,"init lte parms: Nid_cell %d, Frame type %d, N_RB_DL %d\n",Nid_cell,frame_type,N_RB_DL);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id] = calloc(1, sizeof(LTE_DL_FRAME_PARMS));
(frame_parms[CC_id])->frame_type = frame_type;
(frame_parms[CC_id])->tdd_config = tdd_config;
(frame_parms[CC_id])->tdd_config_S = tdd_config_S;
(frame_parms[CC_id])->N_RB_DL = N_RB_DL;
(frame_parms[CC_id])->N_RB_UL = (frame_parms[CC_id])->N_RB_DL;
(frame_parms[CC_id])->phich_config_common.phich_resource = oneSixth;
(frame_parms[CC_id])->phich_config_common.phich_duration = normal;
(frame_parms[CC_id])->Ncp = extended_prefix_flag;
(frame_parms[CC_id])->Ncp_UL = extended_prefix_flag;
(frame_parms[CC_id])->Nid_cell = Nid_cell;
(frame_parms[CC_id])->nushift = (Nid_cell%6);
(frame_parms[CC_id])->nb_antennas_tx = nb_antennas_tx;
(frame_parms[CC_id])->nb_antennas_rx = nb_antennas_rx;
(frame_parms[CC_id])->nb_antenna_ports_eNB = nb_antenna_ports;
(frame_parms[CC_id])->mode1_flag = (frame_parms[CC_id])->nb_antenna_ports_eNB==1 ? 1 : 0;
init_frame_parms(frame_parms[CC_id],1);
(frame_parms[CC_id])->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
(frame_parms[CC_id])->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
(frame_parms[CC_id])->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
(frame_parms[CC_id])->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
init_ul_hopping(frame_parms[CC_id]);
}
// phy_init_top(frame_parms[0]);
phy_init_lte_top(frame_parms[0]);
PHY_vars_eNB_g = (PHY_VARS_eNB***)malloc(NB_eNB_INST*sizeof(PHY_VARS_eNB**));
for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
PHY_vars_eNB_g[eNB_id] = (PHY_VARS_eNB**) malloc(MAX_NUM_CCs*sizeof(PHY_VARS_eNB*));
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_eNB_g[eNB_id][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,eNodeB_3GPP,abstraction_flag);
PHY_vars_eNB_g[eNB_id][CC_id]->Mod_id=eNB_id;
PHY_vars_eNB_g[eNB_id][CC_id]->CC_id=CC_id;
}
}
PHY_vars_UE_g = (PHY_VARS_UE***)malloc(NB_UE_INST*sizeof(PHY_VARS_UE**));
for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
PHY_vars_UE_g[UE_id] = (PHY_VARS_UE**) malloc(MAX_NUM_CCs*sizeof(PHY_VARS_UE*));
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
(frame_parms[CC_id])->nb_antennas_tx = 1;
(frame_parms[CC_id])->nb_antennas_rx = nb_antennas_rx_ue;
PHY_vars_UE_g[UE_id][CC_id] = init_lte_UE(frame_parms[CC_id], UE_id,abstraction_flag);
PHY_vars_UE_g[UE_id][CC_id]->Mod_id=UE_id;
PHY_vars_UE_g[UE_id][CC_id]->CC_id=CC_id;
}
}
if (NB_RN_INST > 0) {
PHY_vars_RN_g = malloc(NB_RN_INST*sizeof(PHY_VARS_RN*));
for (RN_id=0; RN_id<NB_RN_INST; RN_id++) {
PHY_vars_RN_g[RN_id] = init_lte_RN(*frame_parms,RN_id,eMBMS_active_state);
}
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "PHY/types.h"
#include "PHY/defs_L1_NB_IoT.h"
#include "PHY/defs_common.h"
#include "PHY/defs_eNB.h"
#include "PHY/impl_defs_top.h"
PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint16_t Nid_cell,
node_function_t node_function,
uint8_t abstraction_flag);
PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag);
PHY_VARS_RN* init_lte_RN(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t RN_id,
uint8_t eMBMS_active_state);
void init_lte_vars(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs],
uint8_t frame_type,
uint8_t tdd_config,
uint8_t tdd_config_S,
uint8_t extended_prefix_flag,
uint8_t N_RB_DL,
uint16_t Nid_cell,
uint8_t cooperation_flag,
uint8_t nb_antenna_ports,
uint8_t abstraction_flag,
int nb_antennas_rx,
int nb_antennas_tx,
int nb_antennas_rx_ue,
uint8_t eMBMS_active_state);
// for NB-IoT testing
PHY_VARS_eNB_NB_IoT* init_lte_eNB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t Nid_cell,
eNB_func_NB_IoT_t node_function,
uint8_t abstraction_flag);
\ No newline at end of file
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#include "PHY/INIT/phy_init.h" #include "PHY/INIT/phy_init.h"
#include "PHY/defs_eNB.h" #include "PHY/defs_eNB.h"
#include "PHY/defs_L1_NB_IoT.h"
#include "SCHED/sched_eNB.h" #include "SCHED/sched_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h" #include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h"
...@@ -748,8 +749,11 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { ...@@ -748,8 +749,11 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
*/ */
static void *eNB_thread_prach( void *param ) { static void *eNB_thread_prach( void *param ) {
static int eNB_thread_prach_status; static int eNB_thread_prach_status;
PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; eNBs_t *eNBs= (eNBs_t *)param;
L1_proc_t *proc = &eNB->proc; PHY_VARS_eNB *eNB= &eNBs->eNB;
PHY_VARS_eNB_NB_IoT *eNB_NB_IoT= &eNBs->eNB_NB_IoT;//Ann
L1_proc_t *proc = &eNBs->eNB->proc;
// set default return value // set default return value
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
thread_top_init("eNB_thread_prach",1,500000,1000000,20000000); thread_top_init("eNB_thread_prach",1,500000,1000000,20000000);
...@@ -768,7 +772,7 @@ static void *eNB_thread_prach( void *param ) { ...@@ -768,7 +772,7 @@ static void *eNB_thread_prach( void *param ) {
#endif #endif
); );
prach_procedures_NB_IoT(eNB); prach_procedures_NB_IoT(eNB_NB_IoT);//Ann
if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
} }
...@@ -854,6 +858,8 @@ void init_eNB_proc(int inst) { ...@@ -854,6 +858,8 @@ void init_eNB_proc(int inst) {
/*int i=0;*/ /*int i=0;*/
int CC_id; int CC_id;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
// PHY_VARS_eNB_NB_IoT *eNB_NB_IoT;//Ann
eNBs_t *eNBs;//Ann
L1_proc_t *proc; L1_proc_t *proc;
L1_rxtx_proc_t *L1_proc, *L1_proc_tx; L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL;
...@@ -861,9 +867,10 @@ void init_eNB_proc(int inst) { ...@@ -861,9 +867,10 @@ void init_eNB_proc(int inst) {
pthread_attr_t *attr_prach_br=NULL; pthread_attr_t *attr_prach_br=NULL;
#endif #endif
LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]); LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]);
eNBs->eNB_NB_IoT = RC.L1_NB_IoT[inst];//[CC_id];//Ann
for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) { for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
eNB = RC.eNB[inst][CC_id]; eNBs->eNB = RC.eNB[inst][CC_id];
#ifndef OCP_FRAMEWORK #ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id); LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
#endif #endif
...@@ -943,7 +950,7 @@ void init_eNB_proc(int inst) { ...@@ -943,7 +950,7 @@ void init_eNB_proc(int inst) {
} }
if (NFAPI_MODE!=NFAPI_MODE_VNF) { if (NFAPI_MODE!=NFAPI_MODE_VNF) {
pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNBs );
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
#endif #endif
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "PHY/types.h" #include "PHY/types.h"
#include "PHY/defs_eNB.h" #include "PHY/defs_eNB.h"
#include "PHY/defs_common.h"
#include "common/ran_context.h" #include "common/ran_context.h"
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h" #include "common/utils/load_module_shlib.h"
...@@ -93,7 +94,7 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -93,7 +94,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "lte-softmodem.h" #include "lte-softmodem.h"
#include "NB_IoT_interface.h" #include "NB_IoT_interface.h"
#include "PHY/vars_NB_IoT.h"
pthread_cond_t nfapi_sync_cond; pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex; pthread_mutex_t nfapi_sync_mutex;
...@@ -156,6 +157,25 @@ int otg_enabled; ...@@ -156,6 +157,25 @@ int otg_enabled;
uint8_t exit_missed_slots=1; uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots uint64_t num_missed_slots=0; // counter for the number of missed slots
static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
node_function_t node_function[MAX_NUM_CCs];
node_timing_t node_timing[MAX_NUM_CCs];
////////////////////////////////////// NB-IoT //////////////////////////////////////////////
static NB_IoT_DL_FRAME_PARMS *frame_parms_NB_IoT[MAX_NUM_CCs]; // this will be still inside the PHY_VARS of LTE
eNB_func_NB_IoT_t node_function_NB_IoT[MAX_NUM_CCs];
eNB_timing_NB_IoT_t node_timing_NB_IoT[MAX_NUM_CCs];
/////////////////////////////////////////END/////////////////////////////////////////////////
int16_t node_synch_ref[MAX_NUM_CCs];
uint32_t target_dl_mcs = 28; //maximum allowed mcs
uint32_t target_ul_mcs = 20;
uint32_t timing_advance = 0;
int phy_test = 0;
uint8_t abstraction_flag=0;
extern void reset_opp_meas(void); extern void reset_opp_meas(void);
extern void print_opp_meas(void); extern void print_opp_meas(void);
...@@ -521,10 +541,11 @@ static void wait_nfapi_init(char *thread_name) { ...@@ -521,10 +541,11 @@ static void wait_nfapi_init(char *thread_name) {
} }
int main( int argc, char **argv ) { int main( int argc, char **argv ) {
int i; int i,j,k,aa,re;
int CC_id = 0; int CC_id;
int ru_id; int ru_id;
int node_type = ngran_eNB; int node_type = ngran_eNB;
uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
if ( load_configmodule(argc,argv,0) == NULL) { if ( load_configmodule(argc,argv,0) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
...@@ -611,6 +632,112 @@ int main( int argc, char **argv ) { ...@@ -611,6 +632,112 @@ int main( int argc, char **argv ) {
RCconfig_L1(); RCconfig_L1();
} }
/////////////////////////////////////////////////// this is eNB /////////////////////////////////////////////////////////////
PHY_vars_eNB_g = malloc(sizeof(PHY_VARS_eNB**)); //global PHY_vars --> is a matrix
PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*));
///////////////////////// for NB-IoT testing ////////////////////////
PHY_vars_eNB_NB_IoT_g = malloc(sizeof(PHY_VARS_eNB_NB_IoT*)); //global PHY_vars --> is a matrix
PHY_vars_eNB_NB_IoT_g[0] = malloc(sizeof(PHY_VARS_eNB_NB_IoT));
///////////////////////////// END //////////////////////////////////
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
//we initialiaze DL/UL buffer and HARQ (inside the LTE_eNB_DLSCH)
PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,node_function[CC_id],abstraction_flag);
// for NB-IoT testing
PHY_vars_eNB_NB_IoT_g[0] = init_lte_eNB_NB_IoT(frame_parms_NB_IoT,0,frame_parms_NB_IoT->Nid_cell,node_function_NB_IoT,abstraction_flag);
//this is a complementary function for just initialize manage NB_ioT stuff inside the PHY_Vars
#ifdef NB_IOT
//init_lte_eNB_NB(PHY_vars_eNB_g[0][CC_id],frame_parms_NB_IoT[CC_id], 0, frame_parms_NB_IoT[CC_id]->Nid_cell,node_function[CC_id],abstraction_flag);
#endif
PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc=0x1fff;
PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs=target_dl_mcs;
PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6;
PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs;
// initialization for phy-test
for (k=0; k<NUMBER_OF_UE_MAX; k++) {
PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode;
if (transmission_mode==7)
lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k],frame_parms[CC_id]->Nid_cell,0x1235+k);
}
if ((transmission_mode==1) || (transmission_mode==7)) {
for (j=0; j<frame_parms[CC_id]->nb_antennas_tx; j++)
for (re=0; re<frame_parms[CC_id]->ofdm_symbol_size; re++)
PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff/frame_parms[CC_id]->nb_antennas_tx;
}
if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0;
else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1;
if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI;
PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i;
PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3);
PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
}
}
// for NB-IoT testing
if (phy_test==1) PHY_vars_eNB_NB_IoT_g[0]->mac_enabled = 0;
else PHY_vars_eNB_NB_IoT_g[0]->mac_enabled = 1;
if (PHY_vars_eNB_NB_IoT_g[0]->mac_enabled == 0) { //set default parameters for testing mode
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
PHY_vars_eNB_NB_IoT_g[0]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
PHY_vars_eNB_NB_IoT_g[0]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI;
PHY_vars_eNB_NB_IoT_g[0]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
PHY_vars_eNB_NB_IoT_g[0]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i;
PHY_vars_eNB_NB_IoT_g[0]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3);
PHY_vars_eNB_NB_IoT_g[0]->scheduling_request_config[i].dsr_TransMax = sr_n4;
}
}
// No need to do for NB-IoT
compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common,
PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type,
PHY_vars_eNB_g[0][CC_id]->X_u);
PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0];
if (frame_parms[CC_id]->frame_type==FDD) {
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
} else {
if (frame_parms[CC_id]->N_RB_DL == 100)
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624;
else if (frame_parms[CC_id]->N_RB_DL == 50)
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2;
else if (frame_parms[CC_id]->N_RB_DL == 25)
PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4;
}
// for NB-IoT testing
PHY_vars_eNB_NB_IoT_g[0]->rx_total_gain_dB = (int)rx_gain[CC_id][0];
if (frame_parms_NB_IoT[CC_id]->frame_type==FDD) {
PHY_vars_eNB_NB_IoT_g[0]->N_TA_offset = 0;
} else {
if (frame_parms_NB_IoT[CC_id]->N_RB_DL == 100)
PHY_vars_eNB_NB_IoT_g[0]->N_TA_offset = 624;
else if (frame_parms_NB_IoT[CC_id]->N_RB_DL == 50)
PHY_vars_eNB_NB_IoT_g[0]->N_TA_offset = 624/2;
else if (frame_parms_NB_IoT[CC_id]->N_RB_DL == 25)
PHY_vars_eNB_NB_IoT_g[0]->N_TA_offset = 624/4;
}
}
if (RC.nb_inst > 0 && NODE_IS_CU(node_type)) { if (RC.nb_inst > 0 && NODE_IS_CU(node_type)) {
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
ctxt.module_id = 0 ; ctxt.module_id = 0 ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment