Commit a827e6a0 authored by oai's avatar oai

dlsch functions for TX

parent 771043a4
......@@ -1157,6 +1157,11 @@ set(PHY_TURBOIF
add_library(coding MODULE ${PHY_TURBOSRC} )
set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/SIB_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dci_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dlsch_coding_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dlsch_modulation_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/LTE_TRANSPORT/dci_tools_common.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slss.c
......
/*
* 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/dci_NB_IoT.c
* \brief Implements PDCCH physical channel TX/RX procedures (36.211) and DCI encoding/decoding (36.212/36.213). Current LTE compliance V8.6 2009-03.
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include "PHY/defs_common.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
//#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
//#include "PHY/CODING/defs_NB_IoT.h"
#include "PHY/defs_L1_NB_IoT.h" // /LTE_TRANSPORT/defs_NB_IoT.h
//#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
//#include "PHY/extern.h"
//////////#include "PHY/extern_NB_IoT.h"
//#include "SCHED/defs.h"
/////////////////////////////#include "SCHED/defs_nb_iot.h"
//#include "SIMULATION/TOOLS/defs.h" // for taus
//#include "PHY/sse_intrin.h"
//#include "assertions.h"
//#include "T.h"
/////////////////////////////////////////////////////////////////////
//static uint8_t d[2][3*(MAX_DCI_SIZE_BITS_NB_IoT + 16) + 96];
//static uint8_t w[2][3*3*(MAX_DCI_SIZE_BITS_NB_IoT+16)];
void dci_encoding_NB_IoT(uint8_t *a, // Array of two DCI pdus, even if one DCI is to transmit , the number of DCI is indicated in dci_number
NB_IoT_eNB_NPDCCH_t *dlcch, ////uint8_t *e[2], // *e should be e[2][G]
uint8_t A,
uint16_t G,
uint8_t ncce_index,
uint8_t agr_level) // Aggregation level
{
uint8_t D = (A + 16);
uint32_t RCC;
uint8_t occupation_size=1;
if(agr_level == 2 && ncce_index == 0)
{
occupation_size=1;
}else{
occupation_size=2;
}
memset((void *)dlcch->npdcch_d[ncce_index],LTE_NULL_NB_IoT,96);
ccode_encode_NB_IoT(A,2,a,dlcch->npdcch_d[ncce_index]+96,dlcch->rnti[ncce_index]); // CRC attachement & Tail-biting convolutional coding
RCC = sub_block_interleaving_cc_NB_IoT(D,dlcch->npdcch_d[ncce_index]+96,dlcch->npdcch_w[ncce_index]); // Interleaving
lte_rate_matching_cc_NB_IoT(RCC,(G/occupation_size),dlcch->npdcch_w[ncce_index],dlcch->npdcch_e[ncce_index]); // Rate Matching
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///The scrambling sequence shall be initialised at the start of the search space and after every 4th NPDCCH subframes.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void npdcch_scrambling_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_NPDCCH_t *dlcch, // Input data
int G, // Total number of bits to transmit in one subframe(case of DCI = G)
uint8_t Ns, //XXX we pass the subframe // Slot number (0..19)
uint8_t ncce_index,
uint8_t agr_level) // Aggregation level
{
int i;
uint32_t x1, x2, s=0;
uint8_t reset;
uint8_t occupation_size=1;
reset = 1;
if(agr_level == 2 && ncce_index == 0)
{
occupation_size=1;
}else{
occupation_size=2;
}
x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell; // This is c_init in 36.211 Sec 10.2.3.1
for (i=0; i<G/occupation_size; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic_NB_IoT(&x1, &x2, reset);
reset = 0;
}
dlcch->npdcch_e[ncce_index][i] = (dlcch->npdcch_e[ncce_index][i]&1) ^ ((s>>(i&0x1f))&1);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int dci_allocate_REs_in_RB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
uint8_t pilot_shift,
int16_t amp,
unsigned short id_offset,
uint8_t ncce_index,
uint8_t agr_level,
uint32_t *re_allocated)
{
MIMO_mode_t mimo_mode = (frame_parms->mode1_flag==1)? SISO:ALAMOUTI;
uint32_t tti_offset,aa;
uint8_t re;
int16_t gain_lin_QPSK;
uint8_t first_re,last_re;
int32_t tmp_sample1,tmp_sample2;
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
first_re = 0;
last_re = 12;
if(ncce_index == 0 && agr_level == 2)
{
for (re=first_re; re<last_re; re++) { // re varies between 0 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || (re%6 != ((id_offset + 3*pilot_shift) % 6) ) ) // if re is not a pilot
{
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
} else if(agr_level == 1) {
for (re=(first_re + ncce_index*6); re<(6 + ncce_index*6); re++) { // re varies between 0 and 6 or 6 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || (re%6 != ((id_offset + 3*pilot_shift) % 6) ) ) // if re is not a pilot
{
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
} else {
printf("Error in allocate RE of DCI NB_IoT");
}
return(0);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int dci_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
NB_IoT_eNB_NPDCCH_t *dlcch,
unsigned int npdsch_data_subframe, // subframe index of the data table of npdsch channel (G*Nsf) , values are between 0..Nsf
uint8_t agr_level,
uint8_t ncce_index,
unsigned int subframe,
unsigned short NB_IoT_RB_ID) /// NB_IoT_RB_ID should be initialized in the LTE_DL_FRAME_PARMS
{
uint32_t jj = 0;
uint32_t re_allocated,symbol_offset;
uint16_t l;
uint8_t id_offset,pilot_shift,pilots = 0;
unsigned short bandwidth_even_odd;
unsigned short NB_IoT_start, RB_IoT_ID;
re_allocated = 0;
id_offset = 0;
pilot_shift = 0;
// testing if the total number of RBs is even or odd
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
RB_IoT_ID = NB_IoT_RB_ID;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for (l=control_region_size; l<14; l++) { // loop on OFDM symbols
if((l>=4 && l<=7) || (l>=11 && l<=13))
{
pilots = 1;
if(l==4 || l==6 || l==11 || l==13)
{
pilot_shift = 1;
}
} else {
pilots = 0;
}
id_offset = frame_parms->Nid_cell % 6; // Cell_ID_NB_IoT % 6
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
}
symbol_offset = (14*subframe*frame_parms->ofdm_symbol_size) + frame_parms->ofdm_symbol_size*l + NB_IoT_start; // symbol_offset = 512 * L + NB_IOT_RB start
if(agr_level == 2)
{
dci_allocate_REs_in_RB_NB_IoT(frame_parms,
txdataF,
&jj,
symbol_offset,
&dlcch->npdcch_e[0],
pilots,
pilot_shift,
amp,
id_offset,
ncce_index,
agr_level,
&re_allocated);
} else {
dci_allocate_REs_in_RB_NB_IoT(frame_parms,
txdataF,
&jj,
symbol_offset,
&dlcch->npdcch_e[ncce_index],
pilots,
pilot_shift,
amp,
id_offset,
ncce_index,
agr_level,
&re_allocated);
}
}
return (re_allocated);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t *npdcch,
uint8_t Num_dci,
DCI_ALLOC_NB_IoT_t *dci_alloc,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *fp,
int32_t **txdataF,
uint32_t subframe,
uint8_t npdcch_start_symbol)
{
int i, G;
//temporary variable
uint16_t rnti[2];
uint8_t L = 0;
/* PARAMETERS may not needed
**e_ptr : store the encoding result, and as a input to modulation
*num_pdcch_symbols : to calculate the resource allocation for pdcch
*L = aggregation level (there is 2 (at most) in NB-IoT) (Note this is not the real value but the index)
*lprime,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset,re_offset : used in the REG allocation
*gain_lin_QPSK,yseq0[Msymb],yseq1[Msymb],*y[2] : used in the modulation
*mi = used in interleaving
*e = used to store the taus sequence (taus sequence is used to generate the first sequence for DCI) Turbo coding
*wbar used in the interleaving and also REG allocation
*/
// MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization???
// Value of aggregation level (FAPI/NFAPI specs v.9.0 pag 221 value 1,2)
/*
* in NB-IoT we can have at most 2 aggregation level since we have only 2 NCCE (Narrowband control channel element)
* if only 1 DCI transmitted:
* - Aggregation level could be 1 or 2
* if 2 DCI transmitted:
* - Aggregation level should be 1
*
*/
//First take all the DCI pdu and their corrispondent rnti
for(i = 0; i<Num_dci;i++)
{
npdcch->pdu[i][0]=dci_alloc[i].dci_pdu;
rnti[i]=dci_alloc[i].rnti;
L = dci_alloc[i].L;
}
if(Num_dci == 2 && L == 1)
LOG_E(PHY,"generate_dci_top_NB_IoT: Aggregation level not compatible with Num_dci\n" );
//Second, evaluate the G variable based of the npdcch_start_sysmbol
/*
* TS 36.213 ch 16.6.1
* npdcch_start_symbol indicate the starting OFDM symbol for NPDCCH in the first slot of a subframe k ad is determined as follow:
* - if eutracontrolregionsize is present (defined for in-band operating mode (mode 0,1 for FAPI specs))
* npdcch_start_symbol = eutracontrolregionsize (value 1,2,3) [units in number of OFDM symbol]
* -otherwise
* npdcch_start_symbol = 0
*
*XXX npdcch_start symbol should be the same for every DCI once is decided since depends on the parameters
*(the setting of this npdcch_start_symbol parameter should be done in the MAC)
*Depending on npdcch_start_symbol then we define different values for G
*
*/
switch(npdcch_start_symbol) //mail Bcom matthieu
{
case 0:
G = 304;
break;
case 1:
G = 240;
break;
case 2:
G = 224;
break;
case 3:
G =200;
break;
default:
LOG_E (PHY,"npdcch_start_symbol has unwanted value\n");
break;
}
//NB-IoT encoding
// dci_encoding_NB_IoT(
// a,
// 4, // total length (in byte) of a [assume max 2 pdus of ??]
// G,
// npdcch->e,
// rnti,
// Num_dci,
// L
// );
//NB-IoT scrambling
// npdcch_scrambling_NB_IoT(
// fp,
// npdcch->e,
// G,
// subframe,
// Num_dci,
// L
// );
//NB-IoT Modulation
// dci_modulation_NB_IoT(
// txdataF,
// amp,
// fp,
// npdcch_start_symbol,
// npdcch->e,
// G,
// Num_dci,
// L
// );
return 0;
}
......@@ -232,7 +232,7 @@ typedef struct { // LTE_eNB_DLSCH_t
/// First-round error threshold for fine-grain rate adaptation
uint8_t error_threshold;
/// Pointers to 8 HARQ processes for the DLSCH
NB_IoT_DL_eNB_HARQ_t harq_processes[8];
NB_IoT_DL_eNB_HARQ_t *harq_process;
/// circular list of free harq PIDs (the oldest come first)
/// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE)
int harq_pid_freelist[10];
......
/*
* 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/dlsch_coding_NB_IoT.c
* \brief Top-level routines for implementing Tail-biting convolutional coding for transport channels (NPDSCH) for NB_IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#include <string.h>
//#include "PHY/impl_defs_lte.h"
//#include "openair2/COMMON/openair_defs.h"
//#include "PHY/defs.h"
//#include "PHY/extern_NB_IoT.h"
#include "PHY/CODING/defs_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
//#include "SCHED/defs_NB_IoT.h"
//#include "defs_nb_iot.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
#include "PHY/TOOLS/time_meas_NB_IoT.h"
unsigned char ccodelte_table2_NB_IoT[128];
unsigned short glte2_NB_IoT[] = { 0133, 0171, 0165 };
void free_eNB_dlsch_NB_IoT(NB_IoT_eNB_NDLSCH_t *dlsch)
{
if (dlsch) {
/*
#ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch %p\n",dlsch);
#endif*/
if (dlsch->harq_process) {
if (dlsch->harq_process->b) {
free16(dlsch->harq_process->b,300);
dlsch->harq_process->b = NULL;
}
if (dlsch->harq_process->d) {
free16(dlsch->harq_process->d,96+(3*(24+MAX_TBS_DL_SIZE_BITS_NB_IoT)));
// dlsch->harq_process->d = NULL;
}
free16(dlsch->harq_process,sizeof(NB_IoT_DL_eNB_HARQ_t));
dlsch->harq_process = NULL;
}
free16(dlsch,sizeof(NB_IoT_eNB_NDLSCH_t));
dlsch = NULL;
}
}
void free_eNB_dlcch_NB_IoT(NB_IoT_eNB_NPDCCH_t *dlcch)
{
if (dlcch) {
free16(dlcch,sizeof(NB_IoT_eNB_NPDCCH_t));
dlcch = NULL;
}
}
void ccode_encode_npdsch_NB_IoT (int32_t numbits,
uint8_t *inPtr,
uint8_t *outPtr,
uint32_t crc)
{
uint32_t state;
uint8_t c, out, first_bit;
int8_t shiftbit = 0;
/* The input bit is shifted in position 8 of the state.
Shiftbit will take values between 1 and 8 */
state = 0;
first_bit = 2;
c = ((uint8_t*)&crc)[0];
// Perform Tail-biting
// get bits from last byte of input (or crc)
for (shiftbit = 0 ; shiftbit <(8-first_bit) ; shiftbit++) {
if ((c&(1<<(7-first_bit-shiftbit))) != 0)
state |= (1<<shiftbit);
}
state = state & 0x3f; // true initial state of Tail-biting CCode
state<<=1; // because of loop structure in CCode
while (numbits > 0) { // Tail-biting is applied to input bits , input 34 bits , output 102 bits
c = *inPtr++;
for (shiftbit = 7; (shiftbit>=0) && (numbits>0); shiftbit--,numbits--) {
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
}
out = ccodelte_table2_NB_IoT[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
*outPtr++ = (out>>2)&1;
}
}
}
///////////////////////////////////////////////////////////////////////////////
int32_t dlsch_encoding_NB_IoT(unsigned char *a,
NB_IoT_eNB_DLSCH_t *dlsch,
uint8_t Nsf, // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table)
unsigned int G, // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation)
time_stats_t *rm_stats,
time_stats_t *te_stats,
time_stats_t *i_stats){
uint32_t crc = 1;
//unsigned char harq_pid = dlsch->current_harq_pid; // to check during implementation if harq_pid is required in the NB_IoT_eNB_DLSCH_t structure in defs_NB_IoT.h
//uint8_t option1,option2,option3,option4;
unsigned int A=0;
A = dlsch->harq_process->TBS / 8;
uint8_t RCC;
uint8_t npbch_a[A];
uint8_t npbch_a_crc[A+3];
bzero(npbch_a,A);
bzero(npbch_a_crc,A+3);
dlsch->harq_process->length_e = G*Nsf; // G*Nsf (number_of_subframes) = total number of bits to transmit G=236
for (int i=0; i<A; i++)
{
npbch_a[i] = a[i];
}
int32_t numbits = (A*8)+24;
crc = crc24a_NB_IoT(npbch_a,A*8)>>8;
for (int j=0; j<A; j++)
{
npbch_a_crc[j] = npbch_a[j];
}
npbch_a_crc[A] = ((uint8_t*)&crc)[2];
npbch_a_crc[A+1] = ((uint8_t*)&crc)[1];
npbch_a_crc[A+2] = ((uint8_t*)&crc)[0];
dlsch->harq_process->B = numbits; // The length of table b in bits
//memcpy(dlsch->b,a,numbits/8); // comment if option 2
memset(dlsch->harq_process->d,LTE_NULL_NB_IoT,96);
ccode_encode_npdsch_NB_IoT(numbits,npbch_a_crc,dlsch->harq_process->d+96,crc);
RCC = sub_block_interleaving_cc_NB_IoT(numbits,dlsch->harq_process->d+96,dlsch->harq_process->w); // step 2 interleaving
lte_rate_matching_cc_NB_IoT(RCC,dlsch->harq_process->length_e,dlsch->harq_process->w,dlsch->harq_process->e); // step 3 Rate Matching
return(0);
}
///////////////////////////////////////////////////////////////////////////
NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(uint32_t Nsoft, uint8_t type, NB_IoT_DL_FRAME_PARMS* frame_parms)
{
NB_IoT_eNB_NDLSCH_t *dlsch;
unsigned char exit_flag = 0,r;
dlsch = (NB_IoT_eNB_NDLSCH_t *)malloc16(sizeof(NB_IoT_eNB_NDLSCH_t));
if (dlsch) {
bzero(dlsch,sizeof(NB_IoT_eNB_NDLSCH_t));
dlsch->harq_process = (NB_IoT_DL_eNB_HARQ_t *)malloc16(sizeof(NB_IoT_DL_eNB_HARQ_t));
if (dlsch->harq_process) {
bzero(dlsch->harq_process,sizeof(NB_IoT_DL_eNB_HARQ_t));
// dlsch->harq_process[i]->first_tx=1;
dlsch->harq_process->b = (unsigned char*)malloc(300); // to set a new one that replace 300 , MAX_DLSCH_PAYLOAD_BYTES/bw_scaling
if (dlsch->harq_process->b) {
bzero(dlsch->harq_process->b,300);
} else {
printf("Can't get b\n");
exit_flag=1;
}
if (dlsch->harq_process->d) {
bzero((void *)dlsch->harq_process->d,96+(3*(24+MAX_TBS_DL_SIZE_BITS_NB_IoT)));
} else {
printf("Can't get d\n");
exit_flag=2;
}
// }
} else {
exit_flag=3;
}
if (exit_flag==0) {
dlsch->harq_process->round=0;
// for (r=0; r<(96+(3*(24+MAX_TBS_DL_SIZE_BITS_NB_IoT))); r++) {
//
// if (dlsch->harq_process->d)
// dlsch->harq_process->d[0]= LTE_NULL_NB_IoT;
// }
return(dlsch);
}
}
/// LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of %ld\n",
// exit_flag, sizeof(NB_IoT_eNB_NDLSCH_t));
free_eNB_dlsch_NB_IoT(dlsch);
return(NULL);
}
///////////////////////////////////////////////////////////////////////////
NB_IoT_eNB_NPDCCH_t *new_eNB_dlcch_NB_IoT(LTE_DL_FRAME_PARMS* frame_parms)
{
NB_IoT_eNB_NPDCCH_t *dlcch;
dlcch = (NB_IoT_eNB_NPDCCH_t *)malloc16(sizeof(NB_IoT_eNB_NPDCCH_t));
if (dlcch) {
bzero(dlcch,sizeof(NB_IoT_eNB_NPDCCH_t));
return(dlcch);
}
/// LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of %ld\n",
// exit_flag, sizeof(NB_IoT_eNB_NDLSCH_t));
free_eNB_dlcch_NB_IoT(dlcch);
return(NULL);
}
/*************************************************************************
Functions to initialize the code tables
*************************************************************************/
/* Basic code table initialization for constraint length 7 */
/* Input in MSB, followed by state in 6 LSBs */
void ccodelte_init2_NB_IoT(void)
{
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
ccodelte_table2_NB_IoT[i] = 0;
/* Compute 3 output bits */
for (j = 0; j < 3; j++) {
sum = 0;
for (k = 0; k < 7; k++)
if ((i & glte2_NB_IoT[j]) & (1 << k))
sum++;
/* Write the sum modulo 2 in bit j */
ccodelte_table2_NB_IoT[i] |= (sum & 1) << j;
}
}
}
/*
* 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/dlsch_modulation_NB_IoT.c
* \brief Top-level routines for generating the NPDSCH physical channel for NB_IoT,
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#include <math.h>
//#include "PHY/defs.h"
//#include "PHY/defs_NB_IoT.h"
//#include "PHY/extern_NB_IoT.h"
//#include "PHY/impl_defs_lte.h"
//#include "PHY/CODING/defs_nb_iot.h"
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/impl_defs_top_NB_IoT.h"
//#include "defs.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
int allocate_REs_in_RB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
int16_t amp,
unsigned short id_offset,
uint8_t pilot_shift,
uint32_t *re_allocated) // not used variable ??!!
{
MIMO_mode_t mimo_mode = (frame_parms->mode1_flag==1)? SISO:ALAMOUTI;
uint32_t tti_offset,aa;
uint8_t re;
int16_t gain_lin_QPSK;
uint8_t first_re,last_re;
int32_t tmp_sample1,tmp_sample2;
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
first_re = 0;
last_re = 12;
for (re=first_re; re<last_re; re++) { // re varies between 0 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || (re%6 != ((id_offset + 3*pilot_shift) % 6) ) ) // if re is not a pilot
{
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
return(0);
}
int dlsch_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
LTE_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
NB_IoT_eNB_NDLSCH_t *dlsch0, //NB_IoT_eNB_NDLSCH_t
int G, // number of bits per subframe
unsigned int npdsch_data_subframe, // subframe index of the data table of npdsch channel (G*Nsf) , values are between 0..Nsf
unsigned int subframe,
unsigned short NB_IoT_RB_ID)
{
//uint8_t harq_pid = dlsch0->current_harq_pid;
//NB_IoT_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
uint32_t jj = 0;
uint32_t re_allocated,symbol_offset;
uint16_t l;
uint8_t id_offset,pilot_shift,pilots = 0;
unsigned short bandwidth_even_odd;
unsigned short NB_IoT_start, RB_IoT_ID;
re_allocated = 0;
id_offset = 0;
pilot_shift = 0;
// testing if the total number of RBs is even or odd
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
RB_IoT_ID = NB_IoT_RB_ID;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for (l=control_region_size; l<14; l++) { // loop on OFDM symbols
if((l>=4 && l<=7) || (l>=11 && l<=13))
{
pilots = 1;
if(l==4 || l==6 || l==11 || l==13)
{
pilot_shift = 1;
}
} else {
pilots = 0;
}
id_offset = frame_parms->Nid_cell % 6; // Cell_ID_NB_IoT % 6
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
}
symbol_offset = (14*subframe*frame_parms->ofdm_symbol_size) + frame_parms->ofdm_symbol_size*l + NB_IoT_start; // symbol_offset = 512 * L + NB_IOT_RB start
allocate_REs_in_RB_NB_IoT(frame_parms,
txdataF,
&jj,
symbol_offset,
&dlsch0->harq_process->s_e[G*npdsch_data_subframe],
pilots,
amp,
id_offset,
pilot_shift,
&re_allocated);
}
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
return (re_allocated);
}
/*
* 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/dlsch_scrambling_NB_IoT.c
* \brief Routines for the scrambling procedure of the NPDSCH physical channel for NB_IoT, TS 36-211, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
//#define DEBUG_SCRAMBLING 1
//#include "PHY/defs.h"
//#include "PHY/defs_NB_IoT.h"
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
//#include "defs.h"
//#include "extern_NB_IoT.h"
//#include "PHY/extern_NB_IoT.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/impl_defs_lte.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "openair1/PHY/NBIoT_TRANSPORT/extern_NB_IoT.h"
void dlsch_scrambling_Gen_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_NDLSCH_t *dlsch,
int tot_bits, // total number of bits to transmit
uint16_t Nf, // Nf is the frame number (0..9)
uint8_t Ns,
uint32_t rnti,
uint8_t release_v13_5_0,
uint8_t SIB)
{
int i,j,k=0;
uint32_t x1,x2, s=0;
uint8_t *e = dlsch->harq_process->e; //uint8_t *e=dlsch->harq_processes[dlsch->current_harq_pid]->e;
if(release_v13_5_0 == 1 && SIB == 1) /// for SIBs from release 13.5.0 and above
{
x2 = (rnti<<15) + (frame_parms->Nid_cell + 1) * ( (Nf % 61) + 1 ) ;
} else {
x2 = (rnti<<14) + ((Nf%2)<<13) + ((Ns>>1)<<9) + frame_parms->Nid_cell;
}
s = lte_gold_generic_NB_IoT(&x1, &x2, 1);
for (i=0; i<(1+(tot_bits>>5)); i++) {
for (j=0; j<32; j++,k++) {
dlsch->harq_process->s_e[k] = (e[k]&1) ^ ((s>>j)&1);
}
s = lte_gold_generic_NB_IoT(&x1, &x2, 0);
}
}
void init_unscrambling_lut_NB_IoT() {
uint32_t s;
int i=0,j;
for (s=0;s<=65535;s++) {
for (j=0;j<16;j++) {
unscrambling_lut_NB_IoT[i++] = (int16_t)((((s>>j)&1)<<1)-1);
}
}
}
......@@ -40,6 +40,7 @@ extern short *ul_ref_sigs_rx_NB_IoT[30][4]; // NB-IoT: format 1 pilots
extern short *ul_ref_sigs_f2_rx_NB_IoT[16]; // NB-IoT: format 2 pilots
//extern unsigned short dftsizes[33];
extern int16_t unscrambling_lut_NB_IoT[65536*16];
extern int16_t e_phi_re_m6[120];
extern int16_t e_phi_im_m6[120];
......
/*
* 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/lte_mcs_NB_IoT.c
* \brief Some support routines for MCS computations
* \author M. KANJ
* \date 2017
* \version 0.1
* \company b<>com
* \email:
* \note
* \warning
*/
//#include "PHY/defs.h"
//#include "PHY/extern.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/extern_NB_IoT.h"
uint8_t get_Qm_UL_NB_IoT(unsigned char I_mcs, uint8_t N_sc_RU, uint8_t I_sc, uint8_t Msg3_flag)
{
if (Msg3_flag == 1) /////////////////////////// case of Msg3
{
if(I_mcs > 0)
{
return 2;
} else if (I_mcs == 0 && I_sc <12) {
return 1;
} else { ////// I_mcs == 0 && I_sc >11
return 2;
}
} else { /////////////////////// case of other NPUSCH config
if(N_sc_RU == 1)
{
if(I_mcs <2)
{
return 1;
} else {
return 2;
}
} else { /////////////// N_sc_RU > 1
return 2;
}
}
}
int get_G_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms)
{
uint16_t num_ctrl_symbols = frame_parms->control_region_size; // eutra_control_region_size values are 0,1,2
uint8_t nb_antennas_tx_LTE = frame_parms->nb_antennas_tx;
uint8_t nb_antennas_tx_NB_IoT = frame_parms->nb_antennas_tx_NB_IoT;
int G_value=0;
switch (nb_antennas_tx_NB_IoT + (2*nb_antennas_tx_LTE)) {
case 10:
G_value = G_tab[(1*3)-num_ctrl_symbols-1];
break;
case 6:
G_value = G_tab[(2*3)-num_ctrl_symbols-1];
break;
case 4 :
G_value = G_tab[(3*3)-num_ctrl_symbols-1];
break;
case 9 :
G_value = G_tab[(4*3)-num_ctrl_symbols-1];
break;
case 5:
G_value = G_tab[(5*3)-num_ctrl_symbols-1];
break;
case 3 :
G_value = G_tab[(6*3)-num_ctrl_symbols-1];
break;
default:
printf("Error getting G");
}
return(G_value);
}
int get_G_SIB1_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, uint8_t operation_mode_info)
{
uint16_t num_ctrl_symbols = 0; // eutra_control_region_size values are 0,1,2
if(operation_mode_info<2) /// operation_mode_info, in-band (two value 0,1), stand-alone(3), guard band (2)
{
num_ctrl_symbols = 2;
}
uint8_t nb_antennas_tx_LTE = frame_parms->nb_antennas_tx;
uint8_t nb_antennas_tx_NB_IoT = frame_parms->nb_antennas_tx_NB_IoT;
int G_value=0;
switch (nb_antennas_tx_NB_IoT + (2*nb_antennas_tx_LTE)) {
case 10:
G_value = G_tab[(1*3)-num_ctrl_symbols-1];
break;
case 6:
G_value = G_tab[(2*3)-num_ctrl_symbols-1];
break;
case 4 :
G_value = G_tab[(3*3)-num_ctrl_symbols-1];
break;
case 9 :
G_value = G_tab[(4*3)-num_ctrl_symbols-1];
break;
case 5:
G_value = G_tab[(5*3)-num_ctrl_symbols-1];
break;
case 3 :
G_value = G_tab[(6*3)-num_ctrl_symbols-1];
break;
default:
printf("Error getting G");
}
return(G_value);
}
int get_rep_num_SIB1_NB_IoT(uint8_t scheduling_info_sib1)
{
int value=0;
if(scheduling_info_sib1 >11)
{
printf("value not allowed for schedulinginfo for sib1");
} else {
switch(scheduling_info_sib1 % 3)
{
case 0:
value =4;
break;
case 1:
value =8;
break;
case 2:
value =16;
break;
}
}
return(value);
}
int get_start_frame_SIB1_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint8_t repetition)
{
int value=0;
uint16_t cell_id = frame_parms->Nid_cell ;
if(repetition == 4)
{
switch(cell_id %4)
{
case 0:
value =0;
break;
case 1:
value =16;
break;
case 2:
value =32;
break;
case 3:
value =48;
break;
}
} else if(repetition == 8) {
switch(cell_id %2)
{
case 0:
value =0;
break;
case 1:
value =16;
break;
}
} else if(repetition == 16) {
switch(cell_id %2)
{
case 0:
value =0;
break;
case 1:
value =1;
break;
}
} else {
printf("Error in getting the starting frame of SIB1 ");
}
return(value);
}
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