Commit f83cca43 authored by Ting-An Lin's avatar Ting-An Lin

Merge branch 'develop-nb-iot-ntust' of...

Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust
parents b1adf9da 9fc01190
......@@ -326,7 +326,7 @@ add_custom_target (
set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code
add_library(RRC_LIB ${rrc_source}
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c)
#${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c
#${OPENAIR2_DIR}/RRC/NBIOT/MESSAGES/asn1_msg_NB_IoT.c
add_dependencies(RRC_LIB rrc_flag)
include_directories ("${RRC_FULL_DIR}")
......@@ -1065,6 +1065,7 @@ add_dependencies(SCHED_LIB rrc_flag)
set(SCHED_SRC_NB_IoT
#${OPENAIR1_DIR}/SCHED_NBIOT/fapi_l1.c
${OPENAIR1_DIR}/SCHED_NBIOT/phy_procedures_lte_eNb_NB_IoT.c
${OPENAIR1_DIR}/SCHED_NBIOT/IF_Module_L1_primitives_NB_IoT.c
#${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
)
add_library(SCHED_NB_IoT_LIB ${SCHED_SRC_NB_IoT})
......@@ -1163,6 +1164,10 @@ set(PHY_SRC_COMMON
${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/ulsch_demodulation_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_ESTIMATION/lte_ul_channel_estimation_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation_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: lte_segmentation.c
purpose: Procedures for transport block segmentation for LTE (turbo-coded transport channels)
author: raymond.knopp@eurecom.fr
date: 21.10.2009
*/
#include "PHY/defs_L1_NB_IoT.h"
#include "SCHED_NBIOT/defs_NB_IoT.h"
//#define DEBUG_SEGMENTATION
int lte_segmentation_NB_IoT(unsigned char *input_buffer,
unsigned char **output_buffers,
unsigned int B,
unsigned int *C,
unsigned int *Cplus,
unsigned int *Cminus,
unsigned int *Kplus,
unsigned int *Kminus,
unsigned int *F)
{
unsigned int L,Bprime,Bprime_by_C,r,Kr,k,s,crc;
if (B<=6144) {
L=0;
*C=1;
Bprime=B;
} else {
L=24;
*C = B/(6144-L);
if ((6144-L)*(*C) < B)
*C=*C+1;
Bprime = B+((*C)*L);
}
if ((*C)>MAX_NUM_DLSCH_SEGMENTS_NB_IoT) {
LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
return(-1);
}
// Find K+
Bprime_by_C = Bprime/(*C);
if (Bprime_by_C <= 40) {
*Kplus = 40;
*Kminus = 0;
} else if (Bprime_by_C<=512) { // increase by 1 byte til here
*Kplus = (Bprime_by_C>>3)<<3;
*Kminus = Bprime_by_C-8;
} else if (Bprime_by_C <=1024) { // increase by 2 bytes til here
*Kplus = (Bprime_by_C>>4)<<4;
if (*Kplus < Bprime_by_C)
*Kplus = *Kplus + 16;
*Kminus = (*Kplus - 16);
} else if (Bprime_by_C <= 2048) { // increase by 4 bytes til here
*Kplus = (Bprime_by_C>>5)<<5;
if (*Kplus < Bprime_by_C)
*Kplus = *Kplus + 32;
*Kminus = (*Kplus - 32);
} else if (Bprime_by_C <=6144 ) { // increase by 8 bytes til here
*Kplus = (Bprime_by_C>>6)<<6;
if (*Kplus < Bprime_by_C)
*Kplus = *Kplus + 64;
*Kminus = (*Kplus - 64);
} else {
msg("lte_segmentation.c: Illegal codeword size !!!\n");
return(-1);
}
if (*C == 1) {
*Cplus = *C;
*Kminus = 0;
*Cminus = 0;
} else {
// printf("More than one segment (%d), exiting \n",*C);
// exit(-1);
*Cminus = ((*C)*(*Kplus) - (Bprime))/((*Kplus) - (*Kminus));
*Cplus = (*C) - (*Cminus);
}
*F = ((*Cplus)*(*Kplus) + (*Cminus)*(*Kminus) - (Bprime));
if ((input_buffer) && (output_buffers)) {
for (k=0; k<*F>>3; k++) {
output_buffers[0][k] = 0;
}
s=0;
for (r=0; r<*C; r++) {
if (r<*Cminus)
Kr = *Kminus;
else
Kr = *Kplus;
while (k<((Kr - L)>>3)) {
output_buffers[r][k] = input_buffer[s];
// printf("encoding segment %d : byte %d (%d) => %d\n",r,k,Kr>>3,input_buffer[s]);
k++;
s++;
}
if (*C > 1) { // add CRC
crc = crc24b_NB_IoT(output_buffers[r],Kr-24)>>8;
output_buffers[r][(Kr-24)>>3] = ((uint8_t*)&crc)[2];
output_buffers[r][1+((Kr-24)>>3)] = ((uint8_t*)&crc)[1];
output_buffers[r][2+((Kr-24)>>3)] = ((uint8_t*)&crc)[0];
}
k=0;
}
}
return(0);
}
......@@ -68,7 +68,7 @@ int16_t lte_ul_freq_offset_estimation_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t *ul_ch_estimates,
uint16_t nb_rb);
void freq_equalization_NB_IoT(LTE_DL_FRAME_PARMS *frame_parms,
void freq_equalization_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp,
int **ul_ch_mag,
int **ul_ch_mag_b,
......
/*
* 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_ul_channel_estimation_NB_IoT.c
* \brief Channel estimation
* \author Vincent Savaux
* \date 2017
* \version 0.1
* \company b<>com
* \email: vincent.savaux@b<>com.com
* \note
* \warning
*/
#include "PHY/defs_L1_NB_IoT.h"
#include "PHY/extern_NB_IoT.h"
//#include "PHY/sse_intrin.h"
#include <math.h>
#include "PHY/NBIoT_ESTIMATION/defs_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/extern_NB_IoT.h"
//#define DEBUG_CH
#include "PHY/NBIoT_TRANSPORT/sc_rotation_NB_IoT.h"
#include "T.h"
// For Channel Estimation in Distributed Alamouti Scheme
//static int16_t temp_out_ifft[2048*4] __attribute__((aligned(16)));
/*
static int16_t temp_out_fft_0[2048*4] __attribute__((aligned(16)));
static int16_t temp_out_fft_1[2048*4] __attribute__((aligned(16)));
static int16_t temp_out_ifft_0[2048*4] __attribute__((aligned(16)));
static int16_t temp_out_ifft_1[2048*4] __attribute__((aligned(16)));
*/
// static int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32)));
//static int32_t temp_in_ifft_1[2048*2] __attribute__((aligned(32)));
//static int32_t temp_in_fft_0[2048*2] __attribute__((aligned(16)));
// static int32_t temp_in_fft_1[2048*2] __attribute__((aligned(16)));
// round(exp(sqrt(-1)*(pi/2)*[0:1:N-1]/N)*pow2(15))
// static int16_t ru_90[2*128] = {32767, 0,32766, 402,32758, 804,32746, 1206,32729, 1608,32706, 2009,32679, 2411,32647, 2811,32610, 3212,32568, 3612,32522, 4011,32470, 4410,32413, 4808,32352, 5205,32286, 5602,32214, 5998,32138, 6393,32058, 6787,31972, 7180,31881, 7571,31786, 7962,31686, 8351,31581, 8740,31471, 9127,31357, 9512,31238, 9896,31114, 10279,30986, 10660,30853, 11039,30715, 11417,30572, 11793,30425, 12167,30274, 12540,30118, 12910,29957, 13279,29792, 13646,29622, 14010,29448, 14373,29269, 14733,29086, 15091,28899, 15447,28707, 15800,28511, 16151,28311, 16500,28106, 16846,27897, 17190,27684, 17531,27467, 17869,27246, 18205,27020, 18538,26791, 18868,26557, 19195,26320, 19520,26078, 19841,25833, 20160,25583, 20475,25330, 20788,25073, 21097,24812, 21403,24548, 21706,24279, 22006,24008, 22302,23732, 22595,23453, 22884,23170, 23170,22884, 23453,22595, 23732,22302, 24008,22006, 24279,21706, 24548,21403, 24812,21097, 25073,20788, 25330,20475, 25583,20160, 25833,19841, 26078,19520, 26320,19195, 26557,18868, 26791,18538, 27020,18205, 27246,17869, 27467,17531, 27684,17190, 27897,16846, 28106,16500, 28311,16151, 28511,15800, 28707,15447, 28899,15091, 29086,14733, 29269,14373, 29448,14010, 29622,13646, 29792,13279, 29957,12910, 30118,12540, 30274,12167, 30425,11793, 30572,11417, 30715,11039, 30853,10660, 30986,10279, 31114,9896, 31238,9512, 31357,9127, 31471,8740, 31581,8351, 31686,7962, 31786,7571, 31881,7180, 31972,6787, 32058,6393, 32138,5998, 32214,5602, 32286,5205, 32352,4808, 32413,4410, 32470,4011, 32522,3612, 32568,3212, 32610,2811, 32647,2411, 32679,2009, 32706,1608, 32729,1206, 32746,804, 32758,402, 32766};
// static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32729, -1608,32706, -2009,32679, -2411,32647, -2811,32610, -3212,32568, -3612,32522, -4011,32470, -4410,32413, -4808,32352, -5205,32286, -5602,32214, -5998,32138, -6393,32058, -6787,31972, -7180,31881, -7571,31786, -7962,31686, -8351,31581, -8740,31471, -9127,31357, -9512,31238, -9896,31114, -10279,30986, -10660,30853, -11039,30715, -11417,30572, -11793,30425, -12167,30274, -12540,30118, -12910,29957, -13279,29792, -13646,29622, -14010,29448, -14373,29269, -14733,29086, -15091,28899, -15447,28707, -15800,28511, -16151,28311, -16500,28106, -16846,27897, -17190,27684, -17531,27467, -17869,27246, -18205,27020, -18538,26791, -18868,26557, -19195,26320, -19520,26078, -19841,25833, -20160,25583, -20475,25330, -20788,25073, -21097,24812, -21403,24548, -21706,24279, -22006,24008, -22302,23732, -22595,23453, -22884,23170, -23170,22884, -23453,22595, -23732,22302, -24008,22006, -24279,21706, -24548,21403, -24812,21097, -25073,20788, -25330,20475, -25583,20160, -25833,19841, -26078,19520, -26320,19195, -26557,18868, -26791,18538, -27020,18205, -27246,17869, -27467,17531, -27684,17190, -27897,16846, -28106,16500, -28311,16151, -28511,15800, -28707,15447, -28899,15091, -29086,14733, -29269,14373, -29448,14010, -29622,13646, -29792,13279, -29957,12910, -30118,12540, -30274,12167, -30425,11793, -30572,11417, -30715,11039, -30853,10660, -30986,10279, -31114,9896, -31238,9512, -31357,9127, -31471,8740, -31581,8351, -31686,7962, -31786,7571, -31881,7180, -31972,6787, -32058,6393, -32138,5998, -32214,5602, -32286,5205, -32352,4808, -32413,4410, -32470,4011, -32522,3612, -32568,3212, -32610,2811, -32647,2411, -32679,2009, -32706,1608, -32729,1206, -32746,804, -32758,402, -32766};
#define SCALE 0x3FFF
void rotate_channel_single_carrier_NB_IoT(int16_t *estimated_channel,unsigned char l, uint8_t Qm)
{
int16_t pi_2_re[2] = {32767 , 0};
int16_t pi_2_im[2] = {0 , 32768};
int16_t pi_4_re[2] = {32767 , 25735};
int16_t pi_4_im[2] = {0 , 25736};
int k;
int16_t est_channel_re, est_channel_im;
for (k=0;k<12;k++){
est_channel_re = estimated_channel[k<<1];
est_channel_im = estimated_channel[(k<<1)+1];
if (Qm == 1){
estimated_channel[k<<1] = (int16_t)(((int32_t)pi_2_re[l%2] * (int32_t)est_channel_re +
(int32_t)pi_2_im[l%2] * (int32_t)est_channel_im)>>15);
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)pi_2_re[l%2] * (int32_t)est_channel_im -
(int32_t)pi_2_im[l%2] * (int32_t)est_channel_re)>>15);
}
if(Qm == 2){
estimated_channel[k<<1] = (int16_t)(((int32_t)pi_4_re[l%2] * (int32_t)est_channel_re +
(int32_t)pi_4_im[l%2] * (int32_t)est_channel_im)>>15);
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)pi_4_re[l%2] * (int32_t)est_channel_im -
(int32_t)pi_4_im[l%2] * (int32_t)est_channel_re)>>15);
}
}
}
/////////////////////////////////////////// temporary functions for channel estimation and rotation
/*
void rotate_channel_sc_tmp_NB_IoT(int16_t *estimated_channel,
uint8_t l,
uint8_t Qm,
uint8_t counter_msg3,
uint16_t N_SF_per_word,
uint8_t flag)
{
int16_t e_phi_re[120] = {32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621};
int16_t e_phi_im[120] = {0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009};
int16_t e_phi_re_m6[120] = {32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621};
int16_t e_phi_im_m6[120] = {0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010};
int16_t pi_2_re[2] = {32767 , 0};
int16_t pi_2_im[2] = {0 , 32767};
//int16_t pi_4_re[2] = {32767 , 25735};
//int16_t pi_4_im[2] = {0 , 25736};
int16_t pi_4_re[2] = {32767 , 23170};
int16_t pi_4_im[2] = {0 , 23170};
int k;
int16_t est_channel_re, est_channel_im, est_channel_re2, est_channel_im2;
for (k=0;k<12;k++)
{
est_channel_re = estimated_channel[k<<1];
est_channel_im = estimated_channel[(k<<1)+1];
if (Qm == 1) // rotation due to pi/2 BPSK
{
est_channel_re2 = (int16_t)(((int32_t)pi_2_re[l%2] * (int32_t)est_channel_re +
(int32_t)pi_2_im[l%2] * (int32_t)est_channel_im)>>15);
est_channel_im2 = (int16_t)(((int32_t)pi_2_re[l%2] * (int32_t)est_channel_im -
(int32_t)pi_2_im[l%2] * (int32_t)est_channel_re)>>15);
}
if(Qm == 2) // rotation due to pi/4 QPSK
{
est_channel_re2 = (int16_t)(((int32_t)pi_4_re[l%2] * (int32_t)est_channel_re +
(int32_t)pi_4_im[l%2] * (int32_t)est_channel_im)>>15);
est_channel_im2 = (int16_t)(((int32_t)pi_4_re[l%2] * (int32_t)est_channel_im -
(int32_t)pi_4_im[l%2] * (int32_t)est_channel_re)>>15);
}
if(flag==0) // rotation of msg3
{
estimated_channel[k<<1] = (int16_t)(((int32_t)e_phi_re[14*(N_SF_per_word-counter_msg3) + l] * (int32_t)est_channel_re2 +
(int32_t)e_phi_im[14*(N_SF_per_word-counter_msg3) + l] * (int32_t)est_channel_im2)>>15);
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)e_phi_re[14*(N_SF_per_word-counter_msg3) + l] * (int32_t)est_channel_im2 -
(int32_t)e_phi_im[14*(N_SF_per_word-counter_msg3) + l] * (int32_t)est_channel_re2)>>15);
}
if(flag==1) // rotation of msg5
{
estimated_channel[k<<1] = (int16_t)(((int32_t)e_phi_re_m6[14*(2-counter_msg3) + l] * (int32_t)est_channel_re2 +
(int32_t)e_phi_im_m6[14*(2-counter_msg3) + l] * (int32_t)est_channel_im2)>>15);
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)e_phi_re_m6[14*(2-counter_msg3) + l] * (int32_t)est_channel_im2 -
(int32_t)e_phi_im_m6[14*(2-counter_msg3) + l] * (int32_t)est_channel_re2)>>15);
}
}
}
*/
///////////////////////////////////////////////////////////
void rotate_channel_sc_tmp_NB_IoT(int16_t *estimated_channel,
uint8_t l,
uint8_t Qm,
uint8_t counter_msg3,
uint16_t N_SF_per_word,
uint16_t ul_sc_start,
uint8_t flag)
{
//uint32_t I_sc = 10;//eNB->ulsch_NB_IoT[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
//uint16_t ul_sc_start; // subcarrier start index into UL RB
int16_t pi_2_re[2] = {32767 , 0};
int16_t pi_2_im[2] = {0 , 32767};
int16_t pi_4_re[2] = {32767 , 23170};
int16_t pi_4_im[2] = {0 , 23170};
int k;
int16_t est_channel_re, est_channel_im, est_channel_re2, est_channel_im2;
int16_t *e_phi_re,*e_phi_im;
int32_t sign_pm[2] = {1,-1};
int8_t ind_sign_pm; // index for above table
switch(ul_sc_start) /// only for single tone and 15 KHz spacing ? // missing the other configs
{
case 0:
e_phi_re = e_phi_re_m6;
e_phi_im = e_phi_im_m6;
break;
case 1:
e_phi_re = e_phi_re_m5;
e_phi_im = e_phi_im_m5;
break;
case 2:
e_phi_re = e_phi_re_m4;
e_phi_im = e_phi_im_m4;
break;
case 3:
e_phi_re = e_phi_re_m3;
e_phi_im = e_phi_im_m3;
break;
case 4:
e_phi_re = e_phi_re_m2;
e_phi_im = e_phi_im_m2;
break;
case 5:
e_phi_re = e_phi_re_m1;
e_phi_im = e_phi_im_m1;
break;
case 6:
e_phi_re = e_phi_re_0;
e_phi_im = e_phi_im_0;
break;
case 7:
e_phi_re = e_phi_re_p1;
e_phi_im = e_phi_im_p1;
break;
case 8:
e_phi_re = e_phi_re_p2;
e_phi_im = e_phi_im_p2;
break;
case 9:
e_phi_re = e_phi_re_p3;
e_phi_im = e_phi_im_p3;
break;
case 10:
e_phi_re = e_phi_re_p4;
e_phi_im = e_phi_im_p4;
break;
case 11:
e_phi_re = e_phi_re_p5;
e_phi_im = e_phi_im_p5;
break;
}
//ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
ind_sign_pm = ((14*(N_SF_per_word-counter_msg3) + l)/14)%2;
for (k=0;k<12;k++)
{
est_channel_re = estimated_channel[k<<1];
est_channel_im = estimated_channel[(k<<1)+1];
if (Qm == 1) // rotation due to pi/2 BPSK
{
est_channel_re2 = (int16_t)(((int32_t)pi_2_re[l%2] * (int32_t)est_channel_re +
(int32_t)pi_2_im[l%2] * (int32_t)est_channel_im)>>15);
est_channel_im2 = (int16_t)(((int32_t)pi_2_re[l%2] * (int32_t)est_channel_im -
(int32_t)pi_2_im[l%2] * (int32_t)est_channel_re)>>15);
}
if(Qm == 2) // rotation due to pi/4 QPSK
{
est_channel_re2 = (int16_t)(((int32_t)pi_4_re[l%2] * (int32_t)est_channel_re +
(int32_t)pi_4_im[l%2] * (int32_t)est_channel_im)>>15);
est_channel_im2 = (int16_t)(((int32_t)pi_4_re[l%2] * (int32_t)est_channel_im -
(int32_t)pi_4_im[l%2] * (int32_t)est_channel_re)>>15);
}
if(flag==0) // rotation of msg3
{
estimated_channel[k<<1] = (int16_t)(((int32_t)e_phi_re[(14*(N_SF_per_word-counter_msg3) + l)%14] * sign_pm[ind_sign_pm] * (int32_t)est_channel_re2 +
(int32_t)e_phi_im[(14*(N_SF_per_word-counter_msg3) + l)%14] * sign_pm[ind_sign_pm] * (int32_t)est_channel_im2)>>15);
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)e_phi_re[(14*(N_SF_per_word-counter_msg3) + l)%14] * sign_pm[ind_sign_pm] * (int32_t)est_channel_im2 -
(int32_t)e_phi_im[(14*(N_SF_per_word-counter_msg3) + l)%14] * sign_pm[ind_sign_pm] * (int32_t)est_channel_re2)>>15);
}
if(flag==1) // rotation of msg5
{
estimated_channel[k<<1] = (int16_t)(((int32_t)e_phi_re[14*(2-counter_msg3) + l] * (int32_t)est_channel_re2 +
(int32_t)e_phi_im[14*(2-counter_msg3) + l] * (int32_t)est_channel_im2)>>15);
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)e_phi_re[14*(2-counter_msg3) + l] * (int32_t)est_channel_im2 -
(int32_t)e_phi_im[14*(2-counter_msg3) + l] * (int32_t)est_channel_re2)>>15);
}
}
}
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
///////////////// for ACK ////////////
int ul_chest_tmp_f2_NB_IoT(int32_t **rxdataF_ext,
int32_t **ul_ch_estimates,
uint8_t l, //symbol within slot
uint8_t Ns,
uint8_t counter_msg5,
uint8_t flag,
uint8_t subframerx,
uint8_t Qm,
uint16_t ul_sc_start,
NB_IoT_DL_FRAME_PARMS *frame_parms)
{
// NB-IoT: 36.211, Section 5.5.2.2.1, Table 5.5.2.2.1-2
int16_t bar_w_re[9] = {32767, 32767, 32767, 32767, -16384, -16384, 32767, -16384, -16384};
int16_t bar_w_im[9] = { 0, 0, 0, 0, 28377, -28377, 0, -28377, 28377};
int pilot_pos_format2_15k[6] = {2,3,4,9,10,11}; // holds for npusch format 2, and 15 kHz subcarrier bandwidth
//uint16_t ul_sc_start; // subcarrier start index into UL RB
//uint8_t Qm = 1; // needed to rotate the estimated channel
uint32_t u; //for group hopping
//uint32_t I_sc = 0;
int symbol_offset;
uint8_t symbol; //symbol within subframe
int *pilot_pos_format2; // holds for npusch format 2, and 15 kHz subcarrier bandwidth
uint16_t aa,k,n;
int16_t *received_data, *estimated_channel, *pilot_sig; // pointers to
int16_t *ul_ch1, *ul_ch2, *ul_ch3, *ul_ch4, *ul_ch5, *ul_ch6;
uint8_t reset=1, index_w, p;
uint32_t x1, x2, s=0;
uint8_t n_s; // slot within frame (0,..,19)
int16_t ul_ch_estimates_re,ul_ch_estimates_im;
int16_t average_channel[24]; // average channel over a RB and 2 slots
int32_t *p_average_channel = (int32_t *)&average_channel;
pilot_pos_format2 = pilot_pos_format2_15k; // In futur version, this could be adapted for 3.75 kHz
u = frame_parms->Nid_cell%16;
//ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
symbol = l + 7*(Ns&1);
if (l == pilot_pos_format2[0] || l == pilot_pos_format2[1] || l == pilot_pos_format2[2])
{
n_s = Ns+(subframerx<<1);
x2 = 0; //(uint32_t) Ncell_ID;
for (p=0;p<n_s+1;p++) // this should be outsourced to avoid computation in each subframe
{
if ((p%4) == 0)
{
s = lte_gold_generic_NB_IoT(&x1,&x2,reset);
reset = 0;
}
}
index_w = (((s>>(8*(n_s%4)))&255))%3; /// See sections 10.1.4.1 and 5.5.2.2.1 in TS 36.211
symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++)
{
received_data = (int16_t *)&rxdataF_ext[aa][symbol_offset];
estimated_channel = (int16_t *)&ul_ch_estimates[aa][symbol_offset];
pilot_sig = &ul_ref_sigs_f2_rx_NB_IoT[u][24 + 24*((2-counter_msg5)*6+3*Ns+l-2)-(ul_sc_start<<1)]; // pilot values is the same during 3 symbols l = 1, 2, 3
for (k=0;k<12;k++)
{
// Multiplication by the complex conjugate of the pilot
estimated_channel[k<<1] = (int16_t)(((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //imaginary part of estimated channel
}
/// Apply inverse rotation to the channel
rotate_channel_sc_tmp_NB_IoT(estimated_channel,symbol,Qm,counter_msg5,0,ul_sc_start,flag);
ul_ch_estimates_re = estimated_channel[ul_sc_start<<1];
ul_ch_estimates_im = estimated_channel[(ul_sc_start<<1)+1];
estimated_channel[ul_sc_start<<1] =
(int16_t) (((int32_t) (bar_w_re[3*index_w+(l-2)]) * (int32_t) (ul_ch_estimates_re) +
(int32_t) (bar_w_im[3*index_w+(l-2)]) * (int32_t) (ul_ch_estimates_im))>>15);
estimated_channel[(ul_sc_start<<1)+1] =
(int16_t) (((int32_t) (bar_w_re[3*index_w+(l-2)]) * (int32_t) (ul_ch_estimates_im) -
(int32_t) (bar_w_im[3*index_w+(l-2)]) * (int32_t) (ul_ch_estimates_re))>>15);
if (Ns&1 && l==pilot_pos_format2[2]) //we are in the second slot of the sub-frame, so do the averaging of channel estimation
{
ul_ch1 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[0]];
ul_ch2 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[1]];
ul_ch3 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[2]];
ul_ch4 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[3]];
ul_ch5 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[4]];
ul_ch6 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[5]];
for (k=0;k<12;k++)
{
average_channel[k<<1] = (int16_t)(((int32_t)ul_ch1[k<<1] + (int32_t)ul_ch2[k<<1] +
(int32_t)ul_ch3[k<<1] + (int32_t)ul_ch4[k<<1] +
(int32_t)ul_ch5[k<<1] + (int32_t)ul_ch6[k<<1])/6);
average_channel[1+(k<<1)] = (int16_t)(((int32_t)ul_ch1[1+(k<<1)] + (int32_t)ul_ch2[1+(k<<1)] +
(int32_t)ul_ch3[1+(k<<1)] + (int32_t)ul_ch4[1+(k<<1)] +
(int32_t)ul_ch5[1+(k<<1)] + (int32_t)ul_ch6[1+(k<<1)])/6);
}
for (n=0; n<frame_parms->symbols_per_tti; n++)
{
for (k=0;k<12;k++)
{
ul_ch_estimates[aa][frame_parms->N_RB_UL*12*n + k] = p_average_channel[k];
}
}
}
}
}
return(0);
}
/////////////////////////////////////
int ul_chest_tmp_NB_IoT(int32_t **rxdataF_ext,
int32_t **ul_ch_estimates,
uint8_t l, //symbol within slot
uint8_t Ns,
uint8_t counter_msg3, /// should be replaced by the number of the received part of UL data
uint8_t pilot_pos1,
uint8_t pilot_pos2,
uint16_t ul_sc_start,
uint8_t Qm,
uint16_t N_SF_per_word,
NB_IoT_DL_FRAME_PARMS *frame_parms)
{
//int pilot_pos1 = 3, pilot_pos2 = 10; // holds for npusch format 1, and 15 kHz subcarrier bandwidth
//uint16_t ul_sc_start; // subcarrier start index into UL RB
//uint8_t Qm = 2; // needed to rotate the estimated channel
uint32_t u; //for group hopping
int symbol_offset;
uint16_t aa,k,n;
//int32_t **ul_ch_estimates=pusch_vars->drs_ch_estimates[eNB_id];
int16_t *received_data, *estimated_channel, *pilot_sig; // pointers to
unsigned int index_Nsc_RU=0;
uint8_t symbol; //symbol within subframe
int16_t average_channel[24]; // average channel over a RB and 2 slots
int32_t *p_average_channel = (int32_t *)&average_channel;
int16_t *ul_ch1, *ul_ch2;
u= frame_parms->Nid_cell % 16; //Ncell_ID%16;
//ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB // I_sc = 11 for testing
symbol = l + 7*(Ns&1);
if (l == pilot_pos1)
{
symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++)
{
received_data = (int16_t *)&rxdataF_ext[aa][symbol_offset];
estimated_channel = (int16_t *)&ul_ch_estimates[aa][symbol_offset];
pilot_sig = &ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][24 + 24*((N_SF_per_word-counter_msg3)*2+Ns)-(ul_sc_start<<1)]; // pilot values depends on the slots
for (k=0;k<12;k++)
{
// Multiplication by the complex conjugate of the pilot
estimated_channel[k<<1] = (int16_t)(((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //imaginary part of estimated channel
}
rotate_channel_sc_tmp_NB_IoT(estimated_channel,symbol,Qm,counter_msg3,N_SF_per_word,ul_sc_start,0); // 0 is used to indicate msg3
//printf("\n");
/*for (k=11;k<12;k++)
{
printf(" re_chest = %d im_chest = %d pilot_sig_re =%d pilot_sig_im =%d received_data_re =%d received_data_im=%d ",estimated_channel[k<<1],estimated_channel[(k<<1)+1],pilot_sig[k<<1],pilot_sig[(k<<1)+1],received_data[k<<1],received_data[(k<<1)+1]);
}
printf("\n");
for (k=0;k<40;k++)
{
printf(" pilot_sig_re =%d pilot_sig_im =%d ",pilot_sig[k<<1],pilot_sig[(k<<1)+1]);
}
printf("\n");*/
if (Ns&1) //we are in the second slot of the sub-frame, so do the interpolation
{
ul_ch1 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1];
ul_ch2 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2];
// Here, the channel is supposed to be quasi-static during one subframe
// Then, an average over 2 pilot symbols is performed to increase the SNR
// This part may be improved
for (k=0;k<12;k++)
{
average_channel[k<<1] = (int16_t)(((int32_t)ul_ch1[k<<1] + (int32_t)ul_ch2[k<<1])/2);
average_channel[1+(k<<1)] = (int16_t)(((int32_t)ul_ch1[1+(k<<1)] + (int32_t)ul_ch2[1+(k<<1)])/2);
}
for (n=0; n<frame_parms->symbols_per_tti; n++)
{
for (k=0;k<12;k++)
{
ul_ch_estimates[aa][frame_parms->N_RB_UL*12*n + k] = p_average_channel[k];
}
}
/*for (k=11;k<12;k++)
{
printf(" re_chest_av = %d im_chest_av = %d ",ul_ch2[k<<1],ul_ch2[1+(k<<1)]);
}
printf("\n");*/
}
}
}
return(0);
}
int ul_chequal_tmp_NB_IoT(int32_t **rxdataF_ext,
int32_t **rxdataF_comp,
int32_t **ul_ch_estimates,
uint8_t l, //symbol within slot
uint8_t Ns,
NB_IoT_DL_FRAME_PARMS *frame_parms)
{
int symbol_offset;
uint16_t aa,k;
int16_t *received_data, *estimated_channel, *equal_data;
symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++)
{
received_data = (int16_t *)&rxdataF_ext[aa][symbol_offset];
estimated_channel = (int16_t *)&ul_ch_estimates[aa][symbol_offset];
equal_data = (int16_t *)&rxdataF_comp[aa][symbol_offset];
for (k=0;k<12;k++)
{
// Multiplication by the complex conjugate of the channel
//printf("\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk %d",k);
equal_data[k<<1] = (int16_t)(((int32_t)received_data[k<<1]*(int32_t)estimated_channel[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)estimated_channel[(k<<1)+1])>>15); //real part of estimated channel
equal_data[(k<<1)+1] = (int16_t)(((int32_t)received_data[(k<<1)+1]*(int32_t)estimated_channel[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)estimated_channel[(k<<1)+1])>>15); //imaginary part of estimated channel
}
}
return(0);
}
/////////////////////////////////////////////////////////////////////////////
/*
int32_t ul_channel_estimation_NB_IoT(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
uint8_t eNB_id,
uint8_t UE_id,
unsigned char l,
unsigned char Ns,
uint8_t N_sc_RU,
uint8_t pilot_pos1,
uint8_t pilot_pos2,
uint8_t cooperation_flag)
{
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
LTE_eNB_PUSCH *pusch_vars = eNB->pusch_vars[UE_id];
int32_t **ul_ch_estimates=pusch_vars->drs_ch_estimates[eNB_id];
//int32_t **ul_ch_estimates_time= pusch_vars->drs_ch_estimates_time[eNB_id];
//int32_t **ul_ch_estimates_0= pusch_vars->drs_ch_estimates_0[eNB_id];
//int32_t **ul_ch_estimates_1= pusch_vars->drs_ch_estimates_1[eNB_id];
int32_t **rxdataF_ext= pusch_vars->rxdataF_ext[eNB_id];
int subframe = proc->subframe_rx;
//uint8_t harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
//int16_t delta_phase = 0;
// int16_t *ru1 = ru_90;
// int16_t *ru2 = ru_90;
//int16_t current_phase1,current_phase2;
// uint16_t N_rb_alloc = eNB->ulsch[UE_id]->harq_process->nb_rb;
uint16_t aa; //,Msc_RS,Msc_RS_idx;
//uint16_t * Msc_idx_ptr;
// int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp;
int pilot_pos1_15k = 3, pilot_pos2_15k = 10; // holds for npusch format 1, and 15 kHz subcarrier bandwidth
int pilot_pos_format2_15k[6] = {2,3,4,9,10,11}; // holds for npusch format 2, and 15 kHz subcarrier bandwidth
int pilot_pos1_3_75k = 4, pilot_pos2_3_75k = 11; // holds for npusch format 1, and 3.75 kHz subcarrier bandwidth
int pilot_pos_format2_3_75k[6] = {0,1,2,7,8,9}; // holds for npusch format 2, and 3.75 kHz subcarrier bandwidth
//int pilot_pos1, pilot_pos2; // holds for npusch format 1, and 15 kHz subcarrier bandwidth
int *pilot_pos_format2; // holds for npusch format 2, and 15 kHz subcarrier bandwidth
int16_t *ul_ch1=NULL, *ul_ch2=NULL, *ul_ch3=NULL, *ul_ch4=NULL, *ul_ch5=NULL, *ul_ch6=NULL;
int16_t average_channel[24]; // average channel over a RB and 2 slots
int32_t *p_average_channel = (int32_t *)&average_channel;
//int32_t *ul_ch1_0=NULL,*ul_ch2_0=NULL,*ul_ch1_1=NULL,*ul_ch2_1=NULL;
int16_t ul_ch_estimates_re,ul_ch_estimates_im;
//uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t subcarrier_spacing = frame_parms->subcarrier_spacing; // 15 kHz or 3.75 kHz
uint8_t Qm; // needed to rotate the estimated channel
//uint32_t alpha_ind;
uint32_t u;//=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[Ns+(subframe<<1)];
//uint32_t v=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.seqhop[Ns+(subframe<<1)];
// int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16)));
int symbol_offset, k, i, n, p;
uint16_t Ncell_ID = frame_parms->Nid_cell;
uint32_t x1, x2, s=0;
int n_s; // slot in frame
uint8_t reset=1, index_w;
////// NB-IoT specific ///////////////////////////////////////////////////////////////////////////////////////
uint32_t I_sc = 11; /// eNB->ulsch_NB_IoT[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
uint16_t ul_sc_start; // subcarrier start index into UL RB
// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-3
int16_t alpha3_re[9] = {32767 , 32767, 32767,
32767, -16384, -16384,
32767, -16384, -16384};
int16_t alpha3_im[9] = {0 , 0, 0,
0, 28377, -28378,
0, -28378, 28377};
int16_t alpha6_re[24] = {32767 , 32767, 32767, 32767, 32767, 32767,
32767, 16383, -16384, -32768, -16384, 16383,
32767, -16384, -16384, 32767, -16384, -16384,
32767, -16384, -16384, 32767, -16384, -16384};
int16_t alpha6_im[24] = {0 , 0, 0, 0, 0, 0,
0, 28377, 28377, 0, -28378, -28378,
0, 28377, -28378, 0, 28377, -28378,
0, -28378, 28377, 0, -28378, 28377};
// 36.211, Table 5.5.2.2.1-2 --> used for pilots in NPUSCH format 2
int16_t w_format2_re[9] = {32767 , 32767, 32767,
32767, -16384, -16384,
32767, -16384, -16384};
int16_t w_format2_im[9] = {0 , 0, 0,
0, 28377, -28378,
0, -28378, 28377};
int16_t *p_alpha_re, *p_alpha_im; // pointers to tables alpha above;
uint8_t threetnecyclicshift=0, sixtonecyclichift=0; // NB-IoT: to be defined from higher layer, see 36.211 Section 10.1.4.1.2
uint8_t actual_cyclicshift;
//uint8_t Nsc_RU = eNB->ulsch_NB_IoT[UE_id]->harq_process->N_sc_RU; // Vincent: number of sc 1,3,6,12
unsigned int index_Nsc_RU=4; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12
int16_t *received_data, *estimated_channel, *pilot_sig; // pointers to
uint8_t npusch_format = 1; // NB-IoT: format 1 (data), or 2: ack. Should be defined in higher layer
///////////////////////////////////////////////////////////////////////////////////////
//////// get pseudo-random sequence for NPUSCH format 2 //////////////
n_s = (int)Ns+(subframe<<1);
x2 = (uint32_t) Ncell_ID;
for (p=0;p<n_s+1;p++){ // this should be outsourced to avoid computation in each subframe
if ((p&3) == 0) {
s = lte_gold_generic_NB_IoT(&x1,&x2,reset);
reset = 0;
}
}
///////////////////////////////////////////////////////////////////////////////////////
switch (N_sc_RU){
case 1:
index_Nsc_RU = 0;
break;
case 3:
index_Nsc_RU = 1;
break;
case 6:
index_Nsc_RU = 2;
break;
case 12:
index_Nsc_RU = 3;
break;
default:
printf("Error in number of subcarrier in channel estimation\n");
break;
}
if (subcarrier_spacing){
pilot_pos_format2 = pilot_pos_format2_15k;
pilot_pos1 = pilot_pos1_15k;
pilot_pos2 = pilot_pos2_15k;
}else{
pilot_pos_format2 = pilot_pos_format2_3_75k;
pilot_pos1 = pilot_pos1_3_75k;
pilot_pos2 = pilot_pos2_3_75k;
}
ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
//u=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[n_s][index_Nsc_RU]; // Vincent: may be adapted for Nsc_RU, see 36.211, Section 10.1.4.1.3
u=Ncell_ID%16;
switch (npusch_format){
case 1:
if (l == pilot_pos1) { // NB-IoT: no extended CP
symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
for (aa=0; aa<nb_antennas_rx; aa++) {
received_data = (int16_t *)&rxdataF_ext[aa][symbol_offset];
estimated_channel = (int16_t *)&ul_ch_estimates[aa][symbol_offset];
if (index_Nsc_RU){ // NB-IoT: a shift ul_sc_start is added in order to get the same position of the first pilot in rxdataF_ext and ul_ref_sigs_rx_NB_IoT
pilot_sig = &ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][24-(ul_sc_start<<1)]; // pilot values are the same every slots
}else{
pilot_sig = &ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][24 + 2*12*(n_s)-(ul_sc_start<<1)]; // pilot values depends on the slots
}
for (k=0;k<12;k++){
// Multiplication by the complex conjugate of the pilot
estimated_channel[k<<1] = (int16_t)(((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //imaginary part of estimated channel
}
if (N_sc_RU == 1){ // rotate the estimated channel by pi/2 or pi/4, due to mapping b2c
Qm = get_Qm_ul_NB_IoT(2,N_sc_RU); ////eNB->ulsch_NB_IoT[UE_id]->harq_process->mcs,N_sc_RU);
rotate_channel_single_carrier_NB_IoT(estimated_channel,l,Qm);
}
if(N_sc_RU != 1 && N_sc_RU != 12) {
// Compensating for the phase shift introduced at the transmitter
// In NB-IoT NPUSCH format 1, phase alpha is zero when 1 and 12 subcarriers are allocated
// else (still format 1), alpha is defined in 36.211, Table 10.1.4.1.2-3
if (N_sc_RU == 3){
p_alpha_re = alpha3_re;
p_alpha_im = alpha3_im;
actual_cyclicshift = threetnecyclicshift; //// should be defined in higher layer
}else if (N_sc_RU == 6){
p_alpha_re = alpha6_re;
p_alpha_im = alpha6_im;
actual_cyclicshift = sixtonecyclichift; //// should be defined in higher layer
}else{
msg("lte_ul_channel_estimation_NB-IoT: wrong N_sc_RU value, N_sc_RU=%d\n",N_sc_RU);
return(-1);
}
for(i=symbol_offset+ul_sc_start; i<symbol_offset+ul_sc_start+N_sc_RU; i++) {
ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[i<<1];
ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1];
// ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
((int16_t*) ul_ch_estimates[aa])[i<<1] =
(int16_t) (((int32_t) (p_alpha_re[actual_cyclicshift*N_sc_RU+i]) * (int32_t) (ul_ch_estimates_re) +
(int32_t) (p_alpha_im[actual_cyclicshift*N_sc_RU+i]) * (int32_t) (ul_ch_estimates_im))>>15);
//((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im;
((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] =
(int16_t) (((int32_t) (p_alpha_re[actual_cyclicshift*N_sc_RU+i]) * (int32_t) (ul_ch_estimates_im) -
(int32_t) (p_alpha_im[actual_cyclicshift*N_sc_RU+i]) * (int32_t) (ul_ch_estimates_re))>>15);
}
}
if (Ns&1) {//we are in the second slot of the sub-frame, so do the interpolation
ul_ch1 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1];
ul_ch2 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2];
// Here, the channel is supposed to be quasi-static during one subframe
// Then, an average over 2 pilot symbols is performed to increase the SNR
// This part may be improved
for (k=0;k<12;k++){
average_channel[k<<1] = (int16_t)(((int32_t)ul_ch1[k<<1] + (int32_t)ul_ch2[k<<1])/2);
average_channel[1+(k<<1)] = (int16_t)(((int32_t)ul_ch1[1+(k<<1)] + (int32_t)ul_ch2[1+(k<<1)])/2);
}
for (n=0; n<frame_parms->symbols_per_tti; n++) {
if ((n != pilot_pos1) && (n != pilot_pos2)) {
for (k=0;k<12;k++){
ul_ch_estimates[aa][frame_parms->N_RB_UL*12*n + k] = p_average_channel[k];
}
}
}
}
}
}
break;
case 2:
if (l == pilot_pos_format2[0] || l == pilot_pos_format2[1] || l == pilot_pos_format2[2]){
symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
index_w = (uint8_t)l-2 + 3*(((uint8_t*)&s)[n_s&3]%3); // base index in w_format2_re and w_format2_im, see 36.211, Section 10.1.4.1.1
for (aa=0; aa<nb_antennas_rx; aa++) {
received_data = (int16_t *)&rxdataF_ext[aa][symbol_offset];
estimated_channel = (int16_t *)&ul_ch_estimates[aa][symbol_offset];
pilot_sig = &ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][24 + 2*12*(n_s)-(ul_sc_start<<1)]; // pilot values is the same during 3 symbols l = 1, 2, 3
for (k=0;k<12;k++){
// Multiplication by the complex conjugate of the pilot
estimated_channel[k<<1] = (int16_t)(((int32_t)received_data[k<<1]*(int32_t)pilot_sig[k<<1] +
(int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //real part of estimated channel
estimated_channel[(k<<1)+1] = (int16_t)(((int32_t)received_data[(k<<1)+1]*(int32_t)pilot_sig[k<<1] -
(int32_t)received_data[k<<1]*(int32_t)pilot_sig[(k<<1)+1])>>15); //imaginary part of estimated channel
}
// rotate the estimated channel by pi/2 or pi/4, due to mapping b2c
rotate_channel_single_carrier_NB_IoT(estimated_channel,l,1); // last input: Qm = 1 in format 2
// Compensating for the phase shift introduced at the transmitter
// In NB-IoT NPUSCH format 1, phase alpha is zero when 1 and 12 subcarriers are allocated
// else (still format 1), alpha is defined in 36.211, Table 10.1.4.1.2-3
ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[(symbol_offset+ul_sc_start)<<1];
ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[((symbol_offset+ul_sc_start)<<1)+1];
// ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
((int16_t*) ul_ch_estimates[aa])[i<<1] =
(int16_t) (((int32_t) (w_format2_re[index_w]) * (int32_t) (ul_ch_estimates_re) +
(int32_t) (w_format2_im[index_w]) * (int32_t) (ul_ch_estimates_im))>>15);
//((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im;
((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] =
(int16_t) (((int32_t) (w_format2_re[index_w]) * (int32_t) (ul_ch_estimates_im) -
(int32_t) (w_format2_im[index_w]) * (int32_t) (ul_ch_estimates_re))>>15);
if (Ns&1 && l==pilot_pos_format2[2]) {//we are in the second slot of the sub-frame, so do the interpolation
ul_ch1 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[0]];
ul_ch2 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[1]];
ul_ch3 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[2]];
ul_ch4 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[3]];
ul_ch5 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[4]];
ul_ch6 = (int16_t *)&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos_format2[5]];
// Here, the channel is supposed to be quasi-static during one subframe
// Then, an average over 6 pilot symbols is performed to increase the SNR
// This part may be improved
for (k=0;k<12;k++){
average_channel[k<<1] = (int16_t)(((int32_t)ul_ch1[k<<1] + (int32_t)ul_ch2[k<<1] +
(int32_t)ul_ch3[k<<1] + (int32_t)ul_ch4[k<<1] +
(int32_t)ul_ch5[k<<1] + (int32_t)ul_ch6[k<<1])/6);
average_channel[1+(k<<1)] = (int16_t)(((int32_t)ul_ch1[1+(k<<1)] + (int32_t)ul_ch2[1+(k<<1)] +
(int32_t)ul_ch3[1+(k<<1)] + (int32_t)ul_ch4[1+(k<<1)] +
(int32_t)ul_ch5[1+(k<<1)] + (int32_t)ul_ch6[1+(k<<1)])/2);
}
for (n=0; n<frame_parms->symbols_per_tti; n++) {
if ((n != pilot_pos_format2[0]) && (n != pilot_pos_format2[1])
&& (n != pilot_pos_format2[2]) && (n != pilot_pos_format2[3])
&& (n != pilot_pos_format2[4]) && (n != pilot_pos_format2[5])) {
for (k=0;k<12;k++){
ul_ch_estimates[aa][frame_parms->N_RB_UL*12*n + k] = p_average_channel[k];
}
}
}
}
}
}
break;
default:
printf("Error in NPUSCH format, npusch_format=%i \n", npusch_format);
break;
}
return(0);
}
*/
// int32_t lte_ul_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
// eNB_rxtx_proc_NB_IoT_t *proc,
// uint8_t eNB_id,
// uint8_t UE_id,
// unsigned char l,
// unsigned char Ns,
// uint8_t cooperation_flag)
// {
// NB_IoT_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
// NB_IoT_eNB_PUSCH *pusch_vars = eNB->pusch_vars[UE_id];
// int32_t **ul_ch_estimates=pusch_vars->drs_ch_estimates[eNB_id];
// int32_t **ul_ch_estimates_time= pusch_vars->drs_ch_estimates_time[eNB_id];
// //int32_t **ul_ch_estimates_0= pusch_vars->drs_ch_estimates_0[eNB_id];
// //int32_t **ul_ch_estimates_1= pusch_vars->drs_ch_estimates_1[eNB_id];
// int32_t **rxdataF_ext= pusch_vars->rxdataF_ext[eNB_id];
// int subframe = proc->subframe_rx;
// //uint8_t harq_pid = subframe2harq_pid_NB_IoT(frame_parms,proc->frame_rx,subframe);
// int16_t delta_phase = 0;
// int16_t *ru1 = ru_90;
// int16_t *ru2 = ru_90;
// int16_t current_phase1,current_phase2;
// uint16_t N_rb_alloc = eNB->ulsch[UE_id]->harq_process->nb_rb;
// uint16_t aa,Msc_RS,Msc_RS_idx;
// uint16_t * Msc_idx_ptr;
// int32_t rx_power_correction;
// // int k,pilot_pos1 = 3 - frame_parms->Ncp, pilot_pos2 = 10 - 2*frame_parms->Ncp;
// int k,pilot_pos1 = 3, pilot_pos2 = 10;
// int16_t alpha, beta;
// int32_t *ul_ch1=NULL, *ul_ch2=NULL;
// //int32_t *ul_ch1_0=NULL,*ul_ch2_0=NULL,*ul_ch1_1=NULL,*ul_ch2_1=NULL;
// int16_t ul_ch_estimates_re,ul_ch_estimates_im;
// //uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB;
// uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
// uint8_t cyclic_shift;
// uint32_t alpha_ind;
// uint32_t u;//=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[Ns+(subframe<<1)];
// //uint32_t v=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.seqhop[Ns+(subframe<<1)];
// int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16)));
// int symbol_offset,i;
// //int j;
// //debug_msg("lte_ul_channel_estimation: cyclic shift %d\n",cyclicShift);
// // int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377};
// // int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0,-16384,-28378,-32768,-28378,-16384};
// ////// NB-IoT specific ///////////////////////////////////////////////////////////////////////////////////////
// uint32_t I_sc = eNB->ulsch[UE_id]->harq_process->I_sc; // NB_IoT: subcarrier indication field: must be defined in higher layer
// uint16_t ul_sc_start; // subcarrier start index into UL RB
// // 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-3
// int16_t alpha3_re[9] = {32767 , 32767, 32767,
// 32767, -16384, -16384,
// 32767, -16384, -16384};
// int16_t alpha3_im[9] = {0 , 0, 0,
// 0, 28377, -28378,
// 0, -28378, 28377};
// int16_t alpha6_re[24] = {32767 , 32767, 32767, 32767, 32767, 32767,
// 32767, 16383, -16384, -32768, -16384, 16383,
// 32767, -16384, -16384, 32767, -16384, -16384,
// 32767, -16384, -16384, 32767, -16384, -16384};
// int16_t alpha6_im[24] = {0 , 0, 0, 0, 0, 0,
// 0, 28377, 28377, 0, -28378, -28378,
// 0, 28377, -28378, 0, 28377, -28378,
// 0, -28378, 28377, 0, -28378, 28377};
// int16_t *p_alpha_re, *p_alpha_im; // pointers to tables above;
// uint8_t threetnecyclicshift=0, sixtonecyclichift=0; // NB-IoT: to be defined from higher layer, see 36.211 Section 10.1.4.1.2
// uint8_t actual_cyclicshift;
// uint16_t Nsc_RU; // Vincent: number of sc 1,3,6,12
// unsigned int index_Nsc_RU; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12
// ///////////////////////////////////////////////////////////////////////////////////////
// /*
// int32_t *in_fft_ptr_0 = (int32_t*)0,*in_fft_ptr_1 = (int32_t*)0,
// *temp_out_fft_0_ptr = (int32_t*)0,*out_fft_ptr_0 = (int32_t*)0,
// *temp_out_fft_1_ptr = (int32_t*)0,*out_fft_ptr_1 = (int32_t*)0,
// *temp_in_ifft_ptr = (int32_t*)0;
// */
// #if defined(__x86_64__) || defined(__i386__)
// __m128i *rxdataF128,*ul_ref128,*ul_ch128;
// __m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
// #elif defined(__arm__)
// int16x8_t *rxdataF128,*ul_ref128,*ul_ch128;
// int32x4_t mmtmp0,mmtmp1,mmtmp_re,mmtmp_im;
// #endif
// Msc_RS = N_rb_alloc*12;
// cyclic_shift = (frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.cyclicShift +
// eNB->ulsch[UE_id]->harq_process->n_DMRS2 +
// frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.nPRS[(subframe<<1)+Ns]) % 12;
// #if defined(USER_MODE)
// Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints);
// if (Msc_idx_ptr)
// Msc_RS_idx = Msc_idx_ptr - dftsizes;
// else {
// msg("lte_ul_channel_estimation: index for Msc_RS=%d not found\n",Msc_RS);
// return(-1);
// }
// #else
// uint8_t b;
// for (b=0; b<33; b++)
// if (Msc_RS==dftsizes[b])
// Msc_RS_idx = b;
// #endif
// // LOG_I(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift);
// #ifdef DEBUG_CH
// #ifdef USER_MODE
// if (Ns==0)
// write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][Msc_RS_idx],2*Msc_RS,2,1);
// else
// write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][Msc_RS_idx],2*Msc_RS,2,1);
// #endif
// #endif
// rx_power_correction = 1;
// ul_sc_start = get_UL_sc_start_NB_IoT(I_sc); // NB-IoT: get the used subcarrier in RB
// u=frame_parms->npusch_config_common.ul_ReferenceSignalsNPUSCH.grouphop[Ns+(subframe<<1)][index_Nsc_RU]; // Vincent: may be adapted for Nsc_RU, see 36.211, Section 10.1.4.1.3
// // if (l == (3 - frame_parms->Ncp)) {
// if (l == 3) { // NB-IoT: no extended CP
// // symbol_offset = frame_parms->N_RB_UL*12*(l+((7-frame_parms->Ncp)*(Ns&1)));
// symbol_offset = frame_parms->N_RB_UL*12*(l+(7*(Ns&1)));
// for (aa=0; aa<nb_antennas_rx; aa++) {
// // msg("Componentwise prod aa %d, symbol_offset %d,ul_ch_estimates %p,ul_ch_estimates[aa] %p,ul_ref_sigs_rx[0][0][Msc_RS_idx] %p\n",aa,symbol_offset,ul_ch_estimates,ul_ch_estimates[aa],ul_ref_sigs_rx[0][0][Msc_RS_idx]);
// #if defined(__x86_64__) || defined(__i386__)
// rxdataF128 = (__m128i *)&rxdataF_ext[aa][symbol_offset];
// ul_ch128 = (__m128i *)&ul_ch_estimates[aa][symbol_offset];
// if (index_Nsc_RU){ // NB-IoT: a shift ul_sc_start is added in order to get the same position of the first pilot in rxdataF_ext and ul_ref_sigs_rx
// ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][index_Nsc_RU][24-(ul_sc_start<<1)]; // pilot values are the same every slots
// }else{
// ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][index_Nsc_RU][24 + 12*(subframe<<1)-(ul_sc_start<<1)]; // pilot values depends on the slots
// }
// #elif defined(__arm__)
// rxdataF128 = (int16x8_t *)&rxdataF_ext[aa][symbol_offset];
// ul_ch128 = (int16x8_t *)&ul_ch_estimates[aa][symbol_offset];
// if (index_Nsc_RU){
// ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][index_Nsc_RU][24-(ul_sc_start<<1)];
// }else{
// ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][index_Nsc_RU][24 + 12*(subframe<<1)-(ul_sc_start<<1)];
// }
// #endif
// // for (i=0; i<Msc_RS/12; i++) {
// #if defined(__x86_64__) || defined(__i386__)
// // multiply by conjugated channel
// mmtmpU0 = _mm_madd_epi16(ul_ref128[0],rxdataF128[0]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[0],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,15);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// ul_ch128[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// // printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]);
// // multiply by conjugated channel
// mmtmpU0 = _mm_madd_epi16(ul_ref128[1],rxdataF128[1]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[1],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[1]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,15);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// ul_ch128[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// mmtmpU0 = _mm_madd_epi16(ul_ref128[2],rxdataF128[2]);
// // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
// mmtmpU1 = _mm_shufflelo_epi16(ul_ref128[2],_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
// mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
// mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[2]);
// // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
// mmtmpU0 = _mm_srai_epi32(mmtmpU0,15);
// mmtmpU1 = _mm_srai_epi32(mmtmpU1,15);
// mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
// mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
// ul_ch128[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// #elif defined(__arm__)
// mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
// mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
// mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
// ul_ch128++;
// ul_ref128++;
// rxdataF128++;
// mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
// mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
// mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
// ul_ch128++;
// ul_ref128++;
// rxdataF128++;
// mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
// mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
// mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
// mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
// vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
// ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
// ul_ch128++;
// ul_ref128++;
// rxdataF128++;
// #endif
// // ul_ch128+=3;
// // ul_ref128+=3;
// // rxdataF128+=3;
// // }
// // alpha_ind = 0;
// // if((cyclic_shift != 0) && Msc_RS != 12) {
// // // if(Nsc_RU != 1 && Nsc_RU != 12) {
// // // Compensating for the phase shift introduced at the transmitter
// // // In NB-IoT, phase alpha is zero when 12 subcarriers are allocated
// // #ifdef DEBUG_CH
// // write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1);
// // #endif
// // for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
// // ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[i<<1];
// // ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1];
// // // ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
// // ((int16_t*) ul_ch_estimates[aa])[i<<1] =
// // (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_re) +
// // (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_im))>>15);
// // //((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im;
// // ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] =
// // (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_im) -
// // (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_re))>>15);
// // alpha_ind+=cyclic_shift;
// // if (alpha_ind>11)
// // alpha_ind-=12;
// // }
// // #ifdef DEBUG_CH
// // write_output("drs_est_post.m","drsest_post",ul_ch_estimates[0],300*12,1,1);
// // #endif
// // }
// alpha_ind = 0;
// if(Nsc_RU != 1 && Nsc_RU != 12) {
// // Compensating for the phase shift introduced at the transmitter
// // In NB-IoT, phase alpha is zero when 1 and 12 subcarriers are allocated
// #ifdef DEBUG_CH
// write_output("drs_est_pre.m","drsest_pre",ul_ch_estimates[0],300*12,1,1);
// #endif
// if (Nsc_RU == 3){
// p_alpha_re = alpha3_re;
// p_alpha_im = alpha3_im;
// actual_cyclicshift = threetnecyclicshift;
// }else if (Nsc_RU == 6){
// p_alpha_re = alpha6_re;
// p_alpha_im = alpha6_im;
// actual_cyclicshift= sixtonecyclichift;
// }else{
// msg("lte_ul_channel_estimation_NB-IoT: wrong Nsc_RU value, Nsc_RU=%d\n",Nsc_RU);
// return(-1);
// }
// for(i=symbol_offset+ul_sc_start; i<symbol_offset+ul_sc_start+Nsc_RU; i++) {
// ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[i<<1];
// ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1];
// // ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
// ((int16_t*) ul_ch_estimates[aa])[i<<1] =
// (int16_t) (((int32_t) (p_alpha_re[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_re) +
// (int32_t) (p_alpha_im[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_im))>>15);
// //((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im;
// ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] =
// (int16_t) (((int32_t) (p_alpha_re[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_im) -
// (int32_t) (p_alpha_im[actual_cyclicshift*Nsc_RU+i]) * (int32_t) (ul_ch_estimates_re))>>15);
// }
// #ifdef DEBUG_CH
// write_output("drs_est_post.m","drsest_post",ul_ch_estimates[0],300*12,1,1);
// #endif
// }
// //copy MIMO channel estimates to temporary buffer for EMOS
// //memcpy(&ul_ch_estimates_0[aa][symbol_offset],&ul_ch_estimates[aa][symbol_offset],frame_parms->ofdm_symbol_size*sizeof(int32_t)*2);
// memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
// // Convert to time domain for visualization
// for(i=0; i<Msc_RS; i++)
// ((int32_t*)temp_in_ifft_0)[i] = ul_ch_estimates[aa][symbol_offset+i];
// switch(frame_parms->N_RB_DL) {
// case 6:
// idft128((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// case 25:
// idft512((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// case 50:
// idft1024((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// case 100:
// idft2048((int16_t*) temp_in_ifft_0,
// (int16_t*) ul_ch_estimates_time[aa],
// 1);
// break;
// }
// #if T_TRACER
// if (aa == 0)
// T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(UE_id),
// T_INT(proc->frame_rx), T_INT(subframe),
// T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512 * 4));
// #endif
// #ifdef DEBUG_CH
// if (aa==0) {
// if (Ns == 0) {
// write_output("rxdataF_ext.m","rxF_ext",&rxdataF_ext[aa][symbol_offset],512*2,2,1);
// write_output("tmpin_ifft.m","drs_in",temp_in_ifft_0,512,1,1);
// write_output("drs_est0.m","drs0",ul_ch_estimates_time[aa],512,1,1);
// } else
// write_output("drs_est1.m","drs1",ul_ch_estimates_time[aa],512,1,1);
// }
// #endif
// // if(cooperation_flag == 2) {
// // memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
// // memset(temp_in_ifft_1,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
// // memset(temp_in_fft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
// // memset(temp_in_fft_1,0,frame_parms->ofdm_symbol_size*sizeof(int32_t*)*2);
// // temp_in_ifft_ptr = &temp_in_ifft_0[0];
// // i = symbol_offset;
// // for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
// // temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
// // i++;
// // }
// // alpha_ind = 0;
// // // Compensating for the phase shift introduced at the transmitter
// // for(i=symbol_offset; i<symbol_offset+Msc_RS; i++) {
// // ul_ch_estimates_re = ((int16_t*) ul_ch_estimates[aa])[i<<1];
// // ul_ch_estimates_im = ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1];
// // // ((int16_t*) ul_ch_estimates[aa])[i<<1] = (i%2 == 1? 1:-1) * ul_ch_estimates_re;
// // ((int16_t*) ul_ch_estimates[aa])[i<<1] =
// // (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_re) +
// // (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_im))>>15);
// // //((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] = (i%2 == 1? 1:-1) * ul_ch_estimates_im;
// // ((int16_t*) ul_ch_estimates[aa])[(i<<1)+1] =
// // (int16_t) (((int32_t) (alpha_re[alpha_ind]) * (int32_t) (ul_ch_estimates_im) -
// // (int32_t) (alpha_im[alpha_ind]) * (int32_t) (ul_ch_estimates_re))>>15);
// // alpha_ind+=10;
// // if (alpha_ind>11)
// // alpha_ind-=12;
// // }
// // //Extracting Channel Estimates for Distributed Alamouti Receiver Combining
// // temp_in_ifft_ptr = &temp_in_ifft_1[0];
// // i = symbol_offset;
// // for(j=0; j<(frame_parms->N_RB_UL*12); j++) {
// // temp_in_ifft_ptr[j] = ul_ch_estimates[aa][i];
// // i++;
// // }
// // switch (frame_parms->N_RB_DL) {
// // case 6:
// // idft128((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft128((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // break;
// // case 25:
// // idft512((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft512((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // break;
// // case 50:
// // idft1024((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft1024((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // break;
// // case 100:
// // idft2048((int16_t*) &temp_in_ifft_0[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_0,
// // 1);
// // idft2048((int16_t*) &temp_in_ifft_1[0], // Performing IFFT on Combined Channel Estimates
// // temp_out_ifft_1,
// // 1);
// // break;
// // }
// // // because the ifft is not power preserving, we should apply the factor sqrt(power_correction) here, but we rather apply power_correction here and nothing after the next fft
// // in_fft_ptr_0 = &temp_in_fft_0[0];
// // in_fft_ptr_1 = &temp_in_fft_1[0];
// // for(j=0; j<(frame_parms->ofdm_symbol_size)/12; j++) {
// // if (j>19) {
// // ((int16_t*)in_fft_ptr_0)[-40+(2*j)] = ((int16_t*)temp_out_ifft_0)[-80+(2*j)]*rx_power_correction;
// // ((int16_t*)in_fft_ptr_0)[-40+(2*j)+1] = ((int16_t*)temp_out_ifft_0)[-80+(2*j+1)]*rx_power_correction;
// // ((int16_t*)in_fft_ptr_1)[-40+(2*j)] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)]*rx_power_correction;
// // ((int16_t*)in_fft_ptr_1)[-40+(2*j)+1] = ((int16_t*)temp_out_ifft_1)[-80+(2*j)+1]*rx_power_correction;
// // } else {
// // ((int16_t*)in_fft_ptr_0)[2*(frame_parms->ofdm_symbol_size-20+j)] = ((int16_t*)temp_out_ifft_0)[2*(frame_parms->ofdm_symbol_size-20+j)]*rx_power_correction;
// // ((int16_t*)in_fft_ptr_0)[2*(frame_parms->ofdm_symbol_size-20+j)+1] = ((int16_t*)temp_out_ifft_0)[2*(frame_parms->ofdm_symbol_size-20+j)+1]*rx_power_correction;
// // ((int16_t*)in_fft_ptr_1)[2*(frame_parms->ofdm_symbol_size-20+j)] = ((int16_t*)temp_out_ifft_1)[2*(frame_parms->ofdm_symbol_size-20+j)]*rx_power_correction;
// // ((int16_t*)in_fft_ptr_1)[2*(frame_parms->ofdm_symbol_size-20+j)+1] = ((int16_t*)temp_out_ifft_1)[2*(frame_parms->ofdm_symbol_size-20+j)+1]*rx_power_correction;
// // }
// // }
// // switch (frame_parms->N_RB_DL) {
// // case 6:
// // dft128((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // case 25:
// // dft512((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // case 50:
// // dft1024((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // case 100:
// // dft2048((int16_t*) &temp_in_fft_0[0],
// // // Performing FFT to obtain the Channel Estimates for UE0 to eNB1
// // temp_out_fft_0,
// // 1);
// // break;
// // }
// // out_fft_ptr_0 = &ul_ch_estimates_0[aa][symbol_offset]; // CHANNEL ESTIMATES FOR UE0 TO eNB1
// // temp_out_fft_0_ptr = (int32_t*) temp_out_fft_0;
// // i=0;
// // for(j=0; j<frame_parms->N_RB_UL*12; j++) {
// // out_fft_ptr_0[i] = temp_out_fft_0_ptr[j];
// // i++;
// // }
// // switch (frame_parms->N_RB_DL) {
// // case 6:
// // dft128((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // case 25:
// // dft512((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // case 50:
// // dft1024((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // case 100:
// // dft2048((int16_t*) &temp_in_fft_1[0], // Performing FFT to obtain the Channel Estimates for UE1 to eNB1
// // temp_out_fft_1,
// // 1);
// // break;
// // }
// // out_fft_ptr_1 = &ul_ch_estimates_1[aa][symbol_offset]; // CHANNEL ESTIMATES FOR UE1 TO eNB1
// // temp_out_fft_1_ptr = (int32_t*) temp_out_fft_1;
// // i=0;
// // for(j=0; j<frame_parms->N_RB_UL*12; j++) {
// // out_fft_ptr_1[i] = temp_out_fft_1_ptr[j];
// // i++;
// // }
// // #ifdef DEBUG_CH
// // #ifdef USER_MODE
// // if((aa == 0)&& (cooperation_flag == 2)) {
// // write_output("test1.m","t1",temp_in_ifft_0,512,1,1);
// // write_output("test2.m","t2",temp_out_ifft_0,512*2,2,1);
// // write_output("test3.m","t3",temp_in_fft_0,512,1,1);
// // write_output("test4.m","t4",temp_out_fft_0,512,1,1);
// // write_output("test5.m","t5",temp_in_fft_1,512,1,1);
// // write_output("test6.m","t6",temp_out_fft_1,512,1,1);
// // }
// // #endif
// // #endif
// // }//cooperation_flag == 2
// if (Ns&1) {//we are in the second slot of the sub-frame, so do the interpolation
// ul_ch1 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos1];
// ul_ch2 = &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*pilot_pos2];
// // if(cooperation_flag == 2) { // For Distributed Alamouti
// // ul_ch1_0 = &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*pilot_pos1];
// // ul_ch2_0 = &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*pilot_pos2];
// // ul_ch1_1 = &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*pilot_pos1];
// // ul_ch2_1 = &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*pilot_pos2];
// // }
// // Estimation of phase difference between the 2 channel estimates
// // delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms,
// // ul_ch_estimates[aa],
// // N_rb_alloc);
// delta_phase = lte_ul_freq_offset_estimation_NB_IoT(frame_parms,
// ul_ch_estimates[aa],
// 1); // NB-IoT: only 1 RB
// // negative phase index indicates negative Im of ru
// // msg("delta_phase: %d\n",delta_phase);
// #ifdef DEBUG_CH
// msg("lte_ul_channel_estimation: ul_ch1 = %p, ul_ch2 = %p, pilot_pos1=%d, pilot_pos2=%d\n",ul_ch1, ul_ch2, pilot_pos1,pilot_pos2);
// #endif
// for (k=0; k<frame_parms->symbols_per_tti; k++) {
// // we scale alpha and beta by SCALE (instead of 0x7FFF) to avoid overflows
// alpha = (int16_t) (((int32_t) SCALE * (int32_t) (pilot_pos2-k))/(pilot_pos2-pilot_pos1));
// beta = (int16_t) (((int32_t) SCALE * (int32_t) (k-pilot_pos1))/(pilot_pos2-pilot_pos1));
// #ifdef DEBUG_CH
// msg("lte_ul_channel_estimation: k=%d, alpha = %d, beta = %d\n",k,alpha,beta);
// #endif
// //symbol_offset_subframe = frame_parms->N_RB_UL*12*k;
// // interpolate between estimates
// if ((k != pilot_pos1) && (k != pilot_pos2)) {
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1,alpha,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2,beta ,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1,SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2,SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// // msg("phase = %d\n",ru[2*cmax(((delta_phase/7)*(k-3)),0)]);
// // the phase is linearly interpolated
// current_phase1 = (delta_phase/7)*(k-pilot_pos1);
// current_phase2 = (delta_phase/7)*(k-pilot_pos2);
// // msg("sym: %d, current_phase1: %d, current_phase2: %d\n",k,current_phase1,current_phase2);
// // set the right quadrant
// (current_phase1 > 0) ? (ru1 = ru_90) : (ru1 = ru_90c);
// (current_phase2 > 0) ? (ru2 = ru_90) : (ru2 = ru_90c);
// // take absolute value and clip
// current_phase1 = cmin(abs(current_phase1),127);
// current_phase2 = cmin(abs(current_phase2),127);
// // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]);
// // rotate channel estimates by estimated phase
// rotate_cpx_vector((int16_t*) ul_ch1,
// &ru1[2*current_phase1],
// (int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],
// Msc_RS,
// 15);
// rotate_cpx_vector((int16_t*) ul_ch2,
// &ru2[2*current_phase2],
// (int16_t*) &tmp_estimates[0],
// Msc_RS,
// 15);
// // Combine the two rotated estimates
// multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// /*
// if ((k<pilot_pos1) || ((k>pilot_pos2))) {
// multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// } else {
// multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],SCALE>>1,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],alpha,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) &tmp_estimates[0],beta ,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// }
// */
// // memcpy(&ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],ul_ch1,Msc_RS*sizeof(int32_t));
// // if(cooperation_flag == 2) { // For Distributed Alamouti
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_0,beta ,(int16_t*) &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_0,alpha,(int16_t*) &ul_ch_estimates_0[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_1,beta ,(int16_t*) &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_1,alpha,(int16_t*) &ul_ch_estimates_1[aa][frame_parms->N_RB_UL*12*k],0,Msc_RS);
// // }
// }
// } //for(k=...
// // because of the scaling of alpha and beta we also need to scale the final channel estimate at the pilot positions
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1,SCALE,(int16_t*) ul_ch1,1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2,SCALE,(int16_t*) ul_ch2,1,Msc_RS);
// // if(cooperation_flag == 2) { // For Distributed Alamouti
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_0,SCALE,(int16_t*) ul_ch1_0,1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_0,SCALE,(int16_t*) ul_ch2_0,1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch1_1,SCALE,(int16_t*) ul_ch1_1,1,Msc_RS);
// // multadd_complex_vector_real_scalar((int16_t*) ul_ch2_1,SCALE,(int16_t*) ul_ch2_1,1,Msc_RS);
// // }
// } //if (Ns&1)
// } //for(aa=...
// } //if(l==...
// return(0);
// }
// int16_t lte_ul_freq_offset_estimation_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
// int32_t *ul_ch_estimates,
// uint16_t nb_rb)
// {
// #if defined(__x86_64__) || defined(__i386__)
// int k, rb;
// int a_idx = 64;
// uint8_t conj_flag = 0;
// uint8_t output_shift;
// // int pilot_pos1 = 3 - frame_parms->Ncp;
// // int pilot_pos2 = 10 - 2*frame_parms->Ncp;
// int pilot_pos1 = 3;
// int pilot_pos2 = 10;
// __m128i *ul_ch1 = (__m128i*)&ul_ch_estimates[pilot_pos1*frame_parms->N_RB_UL*12];
// __m128i *ul_ch2 = (__m128i*)&ul_ch_estimates[pilot_pos2*frame_parms->N_RB_UL*12];
// int32_t avg[2];
// int16_t Ravg[2];
// Ravg[0]=0;
// Ravg[1]=0;
// int16_t iv, rv, phase_idx;
// __m128i avg128U1, avg128U2, R[3], mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
// // round(tan((pi/4)*[1:1:N]/N)*pow2(15))
// int16_t alpha[128] = {201, 402, 603, 804, 1006, 1207, 1408, 1610, 1811, 2013, 2215, 2417, 2619, 2822, 3024, 3227, 3431, 3634, 3838, 4042, 4246, 4450, 4655, 4861, 5066, 5272, 5479, 5686, 5893, 6101, 6309, 6518, 6727, 6937, 7147, 7358, 7570, 7782, 7995, 8208, 8422, 8637, 8852, 9068, 9285, 9503, 9721, 9940, 10160, 10381, 10603, 10825, 11049, 11273, 11498, 11725, 11952, 12180, 12410, 12640, 12872, 13104, 13338, 13573, 13809, 14046, 14285, 14525, 14766, 15009, 15253, 15498, 15745, 15993, 16243, 16494, 16747, 17001, 17257, 17515, 17774, 18035, 18298, 18563, 18829, 19098, 19368, 19640, 19915, 20191, 20470, 20750, 21033, 21318, 21605, 21895, 22187, 22481, 22778, 23078, 23380, 23685, 23992, 24302, 24615, 24931, 25250, 25572, 25897, 26226, 26557, 26892, 27230, 27572, 27917, 28266, 28618, 28975, 29335, 29699, 30067, 30440, 30817, 31198, 31583, 31973, 32368, 32767};
// // compute log2_maxh (output_shift)
// avg128U1 = _mm_setzero_si128();
// avg128U2 = _mm_setzero_si128();
// for (rb=0; rb<nb_rb; rb++) {
// avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[0],ul_ch1[0]));
// avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[1],ul_ch1[1]));
// avg128U1 = _mm_add_epi32(avg128U1,_mm_madd_epi16(ul_ch1[2],ul_ch1[2]));
// avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[0],ul_ch2[0]));
// avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[1],ul_ch2[1]));
// avg128U2 = _mm_add_epi32(avg128U2,_mm_madd_epi16(ul_ch2[2],ul_ch2[2]));
// ul_ch1+=3;
// ul_ch2+=3;
// }
// avg[0] = (((int*)&avg128U1)[0] +
// ((int*)&avg128U1)[1] +
// ((int*)&avg128U1)[2] +
// ((int*)&avg128U1)[3])/(nb_rb*12);
// avg[1] = (((int*)&avg128U2)[0] +
// ((int*)&avg128U2)[1] +
// ((int*)&avg128U2)[2] +
// ((int*)&avg128U2)[3])/(nb_rb*12);
// // msg("avg0 = %d, avg1 = %d\n",avg[0],avg[1]);
// avg[0] = cmax(avg[0],avg[1]);
// avg[1] = log2_approx(avg[0]);
// output_shift = cmax(0,avg[1]-10);
// //output_shift = (log2_approx(avg[0])/2)+ log2_approx(frame_parms->nb_antennas_rx-1)+1;
// // msg("avg= %d, shift = %d\n",avg[0],output_shift);
// ul_ch1 = (__m128i*)&ul_ch_estimates[pilot_pos1*frame_parms->N_RB_UL*12];
// ul_ch2 = (__m128i*)&ul_ch_estimates[pilot_pos2*frame_parms->N_RB_UL*12];
// // correlate and average the 2 channel estimates ul_ch1*ul_ch2
// for (rb=0; rb<nb_rb; rb++) {
// mmtmpD0 = _mm_madd_epi16(ul_ch1[0],ul_ch2[0]);
// mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[0],_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
// mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[0]);
// mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
// mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// R[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// mmtmpD0 = _mm_madd_epi16(ul_ch1[1],ul_ch2[1]);
// mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[1],_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
// mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[1]);
// mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
// mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// R[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// mmtmpD0 = _mm_madd_epi16(ul_ch1[2],ul_ch2[2]);
// mmtmpD1 = _mm_shufflelo_epi16(ul_ch1[2],_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
// mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate);
// mmtmpD1 = _mm_madd_epi16(mmtmpD1,ul_ch2[2]);
// mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
// mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
// mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
// mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
// R[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
// R[0] = _mm_add_epi16(_mm_srai_epi16(R[0],1),_mm_srai_epi16(R[1],1));
// R[0] = _mm_add_epi16(_mm_srai_epi16(R[0],1),_mm_srai_epi16(R[2],1));
// Ravg[0] += (((short*)&R)[0] +
// ((short*)&R)[2] +
// ((short*)&R)[4] +
// ((short*)&R)[6])/(nb_rb*4);
// Ravg[1] += (((short*)&R)[1] +
// ((short*)&R)[3] +
// ((short*)&R)[5] +
// ((short*)&R)[7])/(nb_rb*4);
// ul_ch1+=3;
// ul_ch2+=3;
// }
// // phase estimation on Ravg
// // Ravg[0] = 56;
// // Ravg[1] = 0;
// rv = Ravg[0];
// iv = Ravg[1];
// if (iv<0)
// iv = -Ravg[1];
// if (rv<iv) {
// rv = iv;
// iv = Ravg[0];
// conj_flag = 1;
// }
// // msg("rv = %d, iv = %d\n",rv,iv);
// // msg("max_avg = %d, log2_approx = %d, shift = %d\n",avg[0], avg[1], output_shift);
// for (k=0; k<6; k++) {
// (iv<(((int32_t)(alpha[a_idx]*rv))>>15)) ? (a_idx -= 32>>k) : (a_idx += 32>>k);
// }
// (conj_flag==1) ? (phase_idx = 127-(a_idx>>1)) : (phase_idx = (a_idx>>1));
// if (Ravg[1]<0)
// phase_idx = -phase_idx;
// return(phase_idx);
// #elif defined(__arm__)
// return(0);
// #endif
// }
/*
* 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 subcarrier start into UL RB for ULSCH
* \author M. KANJ
* \date 2017
* \version 0.1
* \company b<>com
* \email:
* \note
* \warning
*/
//#include "PHY/defs.h"
//#include "PHY/extern.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
uint8_t tab_ack_15khz[16]= {0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3};
uint8_t tab_ack_3_75khz[16]= {38,39,40,41,42,43,44,45,38,39,40,41,42,43,44,45};
uint8_t tab_I_ru_N_ru_UL[8]= {1,2,3,4,5,6,8,10};
uint8_t tab_I_rep_N_rep_UL[8]={1,2,4,8,16,32,64,128};
///
uint8_t tab_ack_sc_format1[16]={0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3};
uint8_t tab_ack_sc_format2[16]={38,39,40,41,42,43,44,45,38,39,40,41,42,43,44,45};
/*
// Section 16.5.1.1 in 36.213
uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc)
{
if (0<=I_sc && I_sc<=11)
{
return I_sc;
} else if (12<=I_sc && I_sc<=15) {
return 3*(I_sc-12);
} else if (16<=I_sc && I_sc<=17) {
return 6*(I_sc-16);
} else if (I_sc==18){
return 0;
} else if (I_sc>18 || I_sc<0){
return -1; /// error msg is needed for this case
} else {
return -1; /// error msg is needed for this case
}
}
*/
uint16_t get_UL_N_rep_NB_IoT(uint8_t I_rep)
{
return tab_I_rep_N_rep_UL[I_rep];
}
uint16_t get_UL_N_ru_NB_IoT(uint8_t I_mcs, uint8_t I_ru, uint8_t flag_msg3)
{
if(flag_msg3 ==1) // msg3
{
if(I_mcs == 0)
{
return 4;
} else if(I_mcs == 1) {
return 3;
} else if(I_mcs == 2) {
return 1;
} else {
//printf("error in I_mcs value from nfapi");
return 0;
}
} else { // other NPUSCH
return tab_I_ru_N_ru_UL[I_ru];
}
}
uint16_t get_UL_sc_ACK_NB_IoT(uint8_t subcarrier_spacing,uint16_t harq_ack_resource)
{
if(subcarrier_spacing == 1) /// 15KHz
{
return tab_ack_sc_format1[harq_ack_resource];
} else { // 3.75 KHz
return tab_ack_sc_format2[harq_ack_resource];
}
}
uint16_t get_UL_sc_index_start_NB_IoT(uint8_t subcarrier_spacing, uint16_t I_sc, uint8_t npush_format)
{
if(npush_format == 0) // format 1
{
if(subcarrier_spacing == 1) ////////// 15 KHz
{
if (0<=I_sc && I_sc<12)
{
return I_sc;
} else if (12<=I_sc && I_sc<16) {
return 3*(I_sc-12);
} else if (16<=I_sc && I_sc<18) {
return 6*(I_sc-16);
} else if (I_sc==18){
return 0;
} else {
return -1;
printf("Error in passed nfapi parameters (I_sc)");
}
} else { //////////// 3.75 KHz
return I_sc; /// values 0-47
}
} else { /////////////////////////////////////// format 2
if(subcarrier_spacing == 1) ////////// 15 KHz
{
return(tab_ack_15khz[I_sc]);
} else { //////////// 3.75 KHz
return(tab_ack_3_75khz[I_sc]);
}
}
}
///////////////////////////////////////////////
uint8_t get_numb_UL_sc_NB_IoT(uint8_t subcarrier_spacing, uint8_t I_sc, uint8_t npush_format)
{
if(npush_format == 0) // format 1
{
if(subcarrier_spacing == 1) // 15 KHz
{
if(I_sc >= 0 && I_sc < 12)
{
return 1;
} else if (I_sc >= 12 && I_sc < 16) {
return 3;
} else if (I_sc >= 16 && I_sc < 18) {
return 6;
} else if (I_sc == 18) {
return 12;
} else {
return 0;
}
} else {
return 1;
}
} else {
return 1;
}
}
////////////////////////////////////////////////////
uint8_t get_UL_slots_per_RU_NB_IoT(uint8_t subcarrier_spacing, uint8_t subcarrier_indcation, uint8_t UL_format)
{
uint8_t subcarrier_number = get_numb_UL_sc_NB_IoT(subcarrier_spacing, subcarrier_indcation, UL_format);
if(UL_format == 0) // format 1
{
if(subcarrier_spacing == 1) // 15 KHz
{
if (subcarrier_number == 1 )
{
return 16;
} else if (subcarrier_number == 3) {
return 8;
} else if (subcarrier_number == 6) {
return 4;
} else {
return 2;
}
} else { // 3.75 KHz
return 16;
}
} else { // format 2
return 4;
}
}
/*
* 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/nprach_eNb_NB_IoT.c
* function for NPRACH signal detection and Timing Advance estimation
* \author V. Savaux
* \date 2018
* \version 0.1
* \company b<>com
* \email: vincent.savaux@b-com.com
* \note
* \warning
*/
//#include "PHY/sse_intrin.h"
#include "PHY/defs_L1_NB_IoT.h"
#include "PHY/TOOLS/tools_defs.h" // to take into account the dft functions
#include "tables_nprach_NB_IoT.h"
#include "first_sc_NB_IoT.h"
//#include "PHY/extern.h"
//#include "prach.h"
//#include "PHY/LTE_TRANSPORT/if4_tools.h"
//#include "SCHED/defs.h"
//#include "SCHED/extern.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
int filter_xx[40] = {-2161, 453, 489, 570, 688, 838, 1014, 1209, 1420, 1639,
1862, 2082, 2295, 2495, 2677, 2837, 2969, 3072, 3142, 3178,
3178, 3142, 3072, 2969, 2837, 2677, 2495, 2295, 2082, 1862,
1639, 1420, 1209, 1014, 838, 688, 570, 489, 453, -2161}; // this is a low-pass filter
int16_t buffer_nprach[153600];
int16_t filtered_buffer[153600];
int16_t signal_compensed_re[153600];
int16_t signal_compensed_im[153600];
int16_t output_buffer[4800];
uint8_t NPRACH_detection_NB_IoT(int16_t *input_buffer,uint32_t input_length){
uint8_t cp_type = 0; // 0: short ; 1: extended
uint32_t nb_signal_samples,nb_noise_samples,n1,n2;
uint64_t energy_signal=0,energy_noise=0;
uint32_t n;
if(cp_type){
}else{
nb_signal_samples = (uint32_t)(((uint64_t) 62670*input_length)/100000);
nb_noise_samples = input_length - nb_signal_samples;
}
n1 = nb_signal_samples;
n2 = nb_noise_samples;
// printf("n samples = %i %i\n",FRAME_LENGTH_COMPLEX_SAMPLESx,nb_signal_samples);
for(n=0;n<nb_signal_samples;n++){
energy_signal += (((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/n1);
//energy_signal += (uint64_t)(((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/10);
}
for(n=nb_signal_samples;n<input_length;n++){
energy_noise += (((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/n2);
//energy_noise += (uint64_t)(((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/10);
}
//printf("energies = %ld %ld\n",energy_signal,energy_noise);
if ((uint64_t)(((uint64_t) energy_signal))<(uint64_t)energy_noise>>6){
return 1;
}else{
return 0;
}
}
/*uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB *eNB,
int16_t *Rx_sub_sampled_buffer,
uint16_t sub_sampling_rate,
uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
uint32_t estimated_TA_coarse,
uint8_t coarse){
uint16_t length_seq_NPRACH,length_CP,length_symbol; // in number of samples, per NPRACH preamble: 4 sequences ; length of CP in number of samples
uint16_t length_CP_0 = 2048;//eNB->frame_parms.prach_config_common.nprach_CP_Length; //NB-IoT: 0: short, 1: long
uint32_t fs=30720000; //NB-IoT: sampling frequency of Rx_buffer, must be defined somewhere
uint32_t fs_sub_sampled;
uint16_t length_correl_window,base_length;
int64_t *vec_correlation;
int64_t max_correlation = 0;
//int16_t **matrix_received_signal_re, **matrix_received_signal_im;
uint16_t offset_estimation, offset_start; // offset due to first coarse estimation
// double *** mat_to_phase_estimation_re, *** mat_to_phase_estimation_im;
int64_t average_mat_to_phase_re, average_mat_to_phase_im;
float estimated_phase, estimated_CFO, CFO_correction, CFO_correction_k;
// int16_t *vec_CFO_compensation_re, *vec_CFO_compensation_im;
// int16_t *vec_received_signal_re, *vec_received_signal_im;
int16_t *signal_CFO_compensed_re, *signal_CFO_compensed_im;
int32_t **sub_sequence_reference_re, **sub_sequence_reference_im;
int32_t *sequence_reference_re, *sequence_reference_im;
uint32_t TA_sample_estimated = 0;
int32_t A;//,B;
int n,k,m,o;
int32_t pow_n1 = 1;
uint32_t index_av_ph1, index_av_ph2;
if (coarse){ // coarse = 1: first estimation at 240 kHz
length_seq_NPRACH = (length_CP_0+5*8192)/128;
length_CP = length_CP_0/128;
length_symbol = 64;
offset_start = 0;
length_correl_window = 80; //20512/sub_sampling_rate; // corresponds to the max TA, i.e. 667.66 micro s //FRAME_LENGTH_COMPLEX_SUB_SAMPLES - 4*length_seq_NPRACH+1;
fs_sub_sampled = (uint32_t)fs/128;
}else{
length_seq_NPRACH = (length_CP_0+5*8192)/16;
length_CP = length_CP_0/16;
length_symbol = 8192/16;
offset_estimation = 8 * estimated_TA_coarse;
base_length = 32;
// we arbitrarily define the length of correl window as base_length samples.
// Check if offset_estimation is close to zero or 1282 (max lentgh of delays)
if (offset_estimation-base_length/2 <0){
offset_start = 0;
length_correl_window = offset_estimation + base_length/2;
}
if (offset_estimation+base_length/2 >1281){
offset_start = offset_estimation-base_length/2;
length_correl_window = base_length;// 512 - (1282-offset_estimation);
}
if ((offset_estimation-base_length/2 >=0) && (offset_estimation+base_length/2 <=1281)){
offset_start = offset_estimation-base_length/2;
length_correl_window = base_length;
}
err
fs_sub_sampled = (uint32_t)fs/16;
}
//fs_sub_sampled = (uint32_t)fs/sub_sampling_rate;
// Method: MMSE (sub-optimal) CFO estimation -> CFO compensation -> ML (sub-optimal) TA estimation /============================================================/
//matrix_received_signal_re = (int16_t **)malloc(4*sizeof(int16_t *));
//matrix_received_signal_im = (int16_t **)malloc(4*sizeof(int16_t *));
// for (k=0;k<4;k++){ // # sequence
// matrix_received_signal_re[k] = (int16_t *)malloc((length_seq_NPRACH-length_CP)*sizeof(int16_t)); // avoid CP in this process
// matrix_received_signal_im[k] = (int16_t *)malloc((length_seq_NPRACH-length_CP)*sizeof(int16_t)); // avoid CP in this process
// }
signal_CFO_compensed_re = (int16_t *)malloc(4*length_seq_NPRACH*sizeof(int16_t)); /////to do : exact size of tables
signal_CFO_compensed_im = (int16_t *)malloc(4*length_seq_NPRACH*sizeof(int16_t));
sub_sequence_reference_re = (int32_t **)malloc(4*sizeof(int32_t *));
sub_sequence_reference_im = (int32_t **)malloc(4*sizeof(int32_t *));
for (k=0;k<4;k++){
sub_sequence_reference_re[k] = (int32_t *)calloc(length_symbol,sizeof(int32_t));
sub_sequence_reference_im[k] = (int32_t *)calloc(length_symbol,sizeof(int32_t));
}
sequence_reference_re = (int32_t *)malloc(4*length_seq_NPRACH*sizeof(int32_t));
sequence_reference_im = (int32_t *)malloc(4*length_seq_NPRACH*sizeof(int32_t));
vec_correlation = (int64_t *)calloc(length_correl_window,sizeof(int64_t));
for (n=0;n<length_correl_window;n++){ // loops over samples %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// MMSE (sub-optimal) CFO estimation /============================================================/
average_mat_to_phase_re = 0;
average_mat_to_phase_im = 0;
for (k=0;k<4;k++){ // # sequence
for (o=0;o<4;o++){ // # symbol in sequence
for (m=0;m<length_symbol;m++){ ///// creation of two variables for tab indexes "n+offset_start+k*length_seq_NPRACH+length_CP+o*length_symbol+m"
index_av_ph1 = (n+offset_start+k*length_seq_NPRACH+length_CP+o*length_symbol+m)<<1;
index_av_ph2 = index_av_ph1 + (length_symbol<<1);
average_mat_to_phase_re = average_mat_to_phase_re
- (int64_t)(Rx_sub_sampled_buffer[index_av_ph1]
* Rx_sub_sampled_buffer[index_av_ph2])
- (int64_t)(Rx_sub_sampled_buffer[index_av_ph1+1]
* Rx_sub_sampled_buffer[index_av_ph2+1]);
average_mat_to_phase_im = average_mat_to_phase_im
- (int64_t)(Rx_sub_sampled_buffer[index_av_ph1+1]
* Rx_sub_sampled_buffer[index_av_ph2])
+ (int64_t)(Rx_sub_sampled_buffer[index_av_ph1]
* Rx_sub_sampled_buffer[index_av_ph2+1]);
}
}
}
average_mat_to_phase_re = average_mat_to_phase_re/(16*length_symbol);
average_mat_to_phase_im = average_mat_to_phase_im/(16*length_symbol);
estimated_phase = atan2f(average_mat_to_phase_im,average_mat_to_phase_re);
estimated_CFO = ((float)fs*estimated_phase)/(8192*2*(float)M_PI);
CFO_correction = 2*(float)M_PI*estimated_CFO/fs_sub_sampled;
// CFO compensation /============================================================/
for (k=0;k<4*length_seq_NPRACH;k++){ ///// creation of two variables for tab indexes /// replace "2*(float)M_PI*estimated_CFO*k/fs_sub_sampled" and "2*(n+offset_start+k)"
CFO_correction_k = (float)k*CFO_correction;
signal_CFO_compensed_re[k] = (int16_t)((Rx_sub_sampled_buffer[(n+offset_start+k)<<1] * (int32_t)(cosf(CFO_correction_k)*32767)
- Rx_sub_sampled_buffer[((n+offset_start+k)<<1)+1] * (int32_t)(sinf(CFO_correction_k)*32767))>>15);
signal_CFO_compensed_im[k] = (int16_t)((Rx_sub_sampled_buffer[(n+offset_start+k)<<1] * (int32_t)(sinf(CFO_correction_k)*32767)
+ Rx_sub_sampled_buffer[((n+offset_start+k)<<1)+1] * (int32_t)(cosf(CFO_correction_k)*32767))>>15);
}
// sub-optimal ML TA estimation /============================================================/
for (k=0;k<4;k++){ // loop over the 4 sequences of a preamble
pow_n1 = 1;
for (o=0;o<5;o++){ // loop over the symbols of a sequence
for (m=0;m<length_symbol;m++){
// mon_variable=k*length_seq_NPRACH + o*length_symbol + length_CP + m ///////////////////////////////////////////////////////////////////////////////////////////////
sub_sequence_reference_re[k][m] = sub_sequence_reference_re[k][m] + pow_n1 * signal_CFO_compensed_re[k*length_seq_NPRACH + o*length_symbol + length_CP + m] / 5; // average over the 5 symbols of a group
sub_sequence_reference_im[k][m] = sub_sequence_reference_im[k][m] + pow_n1 * signal_CFO_compensed_im [k*length_seq_NPRACH + o*length_symbol + length_CP + m]/ 5; // average over the 5 symbols of a group
}
pow_n1 = -pow_n1;
}
}
pow_n1 = 1;
for (k=0;k<4;k++){ // loop over the 4 sequences of a preamble
pow_n1 = 1;
for (o=0;o<5;o++){ // loop over the symbols of a sequence // mon_variable=k*length_seq_NPRACH+o*length_symbol +length_CP +m///////////////////////////////////////////////
for (m=0;m<length_symbol;m++){
sequence_reference_re[k*length_seq_NPRACH+o*length_symbol +length_CP +m] = pow_n1 * sub_sequence_reference_re[k][m];
sequence_reference_im[k*length_seq_NPRACH+o*length_symbol +length_CP +m] = pow_n1 * sub_sequence_reference_im[k][m];
}
pow_n1 = -pow_n1;
}
}
for (k=0;k<4;k++){ // loop over the 4 sequences of a preamble
for (m=0;m<length_CP;m++){
sequence_reference_re[k*length_seq_NPRACH+m] = -sub_sequence_reference_re[k][length_symbol-length_CP+m];
sequence_reference_im[k*length_seq_NPRACH+m] = -sub_sequence_reference_im[k][length_symbol-length_CP+m];
}
}
// for (m=0;m<length_seq_NPRACH;m++){
// vec_correlation[n] = vec_correlation[n] + (double)signal_CFO_compensed_re[m] * sequence_reference_re[m] + (double)signal_CFO_compensed_im[m] * sequence_reference_im[m];
// printf("seq=%i\n",sequence_reference_re[m]);
// }
for (m=0;m<4*length_seq_NPRACH;m++){
A = (int64_t)((signal_CFO_compensed_re[m] * sequence_reference_re[m]
+ signal_CFO_compensed_im[m] * sequence_reference_im[m]));
//B = -(int32_t)(((int64_t)signal_CFO_compensed_re[m] * (int64_t)sequence_reference_im[m]
// - (int64_t)signal_CFO_compensed_im[m] * (int64_t)sequence_reference_re[m])>>32);
vec_correlation[n] = vec_correlation[n] + A;//(int32_t)(((int64_t)A*(int64_t)A + 2*(int64_t)B*(int64_t)B)>>32);
}
for (k=0;k<4;k++){ // re-initialize sub_sequence_reference matrices ////////////////////////////////////////////
for (m=0;m<length_symbol;m++){
sub_sequence_reference_re[k][m] = 0;
sub_sequence_reference_im[k][m] = 0;
}
}
}
for (n=0;n<length_correl_window;n++){
//printf("\ncorr=%li \n",vec_correlation[n]);
if(vec_correlation[n]>=max_correlation){
max_correlation = vec_correlation[n];
TA_sample_estimated = offset_start+ n;
}
}
free(vec_correlation);
for (k=0;k<4;k++){ // # sequence
//free(matrix_received_signal_re[k]);
err//free(matrix_received_signal_im[k]);
free(sub_sequence_reference_re[k]);
free(sub_sequence_reference_im[k]);
}
//free(matrix_received_signal_re);
//free(matrix_received_signal_im);
free(signal_CFO_compensed_re);
free(signal_CFO_compensed_im);
free(sub_sequence_reference_re);
free(sub_sequence_reference_im);
return TA_sample_estimated;
} */
uint16_t subcarrier_estimation(int16_t *input_buffer){
uint16_t estimated_sc=0;
int16_t *s_n_re, *s_n_im;
uint16_t k,m,n;
int64_t max_correl_sc_m = 0;
int64_t max_correl_sc_k = 0;
int64_t max_correl_sc_glob = 0;
int n_start_offset = 1920; // start at t=8 ms
for (k=0;k<12;k++){
s_n_re = &s_n_12_re[k*336];
s_n_im = &s_n_12_im[k*336];
for (m=0;m<20;m++){
for (n=0;n<336;n++){
max_correl_sc_m = max_correl_sc_m +
(int16_t)(((int32_t)input_buffer[(m<<1)+((n+n_start_offset)<<1)]*(int32_t)s_n_re[n] )>>15)
+ (int16_t)(((int32_t)input_buffer[(m<<1)+((n+n_start_offset)<<1)+1]*(int32_t)s_n_im[n])>>15);
}
if (max_correl_sc_m>max_correl_sc_k){
max_correl_sc_k = max_correl_sc_m;
}
max_correl_sc_m = 0;
}
//printf("correl = %li\n",max_correl_sc_k);
if (max_correl_sc_k>max_correl_sc_glob){
max_correl_sc_glob = max_correl_sc_k;
estimated_sc = k;
}
max_correl_sc_k = 0;
}
return estimated_sc;
}
int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate){ // void function ////// adding flag for switching between output_buffers
int k;
uint32_t L;
//int16_t *output_buffer;
int16_t *p_output_buffer;
L = (uint32_t)(length_input / sub_sampling_rate);
*length_ouput = L; ///// to remove
for (k=0;k<L;k++){
output_buffer[k<<1] = input_buffer[sub_sampling_rate*(k<<1)];
output_buffer[(k<<1)+1] = input_buffer[sub_sampling_rate*(k<<1)+1];
}
// for (k=0;k<2*L;k++){
// printf("%i\n",output_buffer[k]);
// }
p_output_buffer=output_buffer;
return p_output_buffer;
}
void filtering_signal(int16_t *input_buffer, int16_t *filtered_buffer, uint32_t FRAME_LENGTH_COMPLEX_SAMPLESx){
int n;
//int k;
//float f_s_RB22 = 1807.5;
//float f_s = 7680;
//int16_t *signal_compensed_re, *signal_compensed_im;
int16_t *cos_x, *sin_x;
cos_x = cos_x_rb22;
sin_x = sin_x_rb22;
for (n=0;n<FRAME_LENGTH_COMPLEX_SAMPLESx;n++){
signal_compensed_re[n] = (int16_t)((input_buffer[n<<1] * (int32_t)(cos_x[n])
+ input_buffer[(n<<1)+1] * (int32_t)(sin_x[n]))>>15);
signal_compensed_im[n] = (int16_t)((- input_buffer[n<<1] * (int32_t)(sin_x[n])
+ input_buffer[(n<<1)+1] * (int32_t)(cos_x[n]))>>15);
filtered_buffer[n<<1] = signal_compensed_re[n];
filtered_buffer[(n<<1)+1] = signal_compensed_im[n];
}
/*for (n=0;n<FRAME_LENGTH_COMPLEX_SAMPLESx-10;n++){
if (n<20){
for (k=-n;k<20;k++){
filtered_buffer[n<<1] = filtered_buffer[n<<1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_re[n+k])>>15);
filtered_buffer[(n<<1)+1] = filtered_buffer[(n<<1)+1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_im[n+k])>>15);
}
}else{
for (k=-20;k<20;k++){
filtered_buffer[n<<1] = filtered_buffer[n<<1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_re[n+k])>>15);
filtered_buffer[(n<<1)+1] = filtered_buffer[(n<<1)+1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_im[n+k])>>15);
}
}
}*/
}
uint32_t process_nprach_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int frame, uint8_t subframe, uint16_t *rnti, uint16_t *preamble_index, uint16_t *timing_advance){
//uint32_t estimated_TA_coarse=0;
//uint32_t estimated_TA;
int16_t *Rx_sub_sampled_buffer_128; // *Rx_sub_sampled_buffer_16;
uint16_t sub_sampling_rate; //NB-IoT: to be defined somewhere
uint32_t FRAME_LENGTH_COMPLEX_SAMPLESx; // NB-IoT: length of input buffer, to be defined somewhere
uint32_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES; // Length of buffer after sub-sampling
uint32_t *length_ouput; // Length of buffer after sub-sampling
// uint8_t coarse=1; // flag that indicate the level of TA estimation
int16_t *Rx_buffer;
//int16_t *filtered_buffer;
//int n;
//// 1. Coarse TA estimation using sub sampling rate = 128, i.e. fs = 240 kHz
FRAME_LENGTH_COMPLEX_SAMPLESx = 10*eNB->frame_parms.samples_per_tti;
Rx_buffer = (int16_t*)&eNB->common_vars.rxdata[0][0][0]; // get the whole frame
memcpy(&buffer_nprach[0],&Rx_buffer[0],307200);
//filtered_buffer = (int16_t *)calloc(2*FRAME_LENGTH_COMPLEX_SAMPLESx,sizeof(int16_t)); // calcule du taille exacte du tableau 76800
memset(filtered_buffer,0,307200);
filtering_signal(buffer_nprach,filtered_buffer,FRAME_LENGTH_COMPLEX_SAMPLESx);
// Sub-sampling stage /============================================================/
sub_sampling_rate = FRAME_LENGTH_COMPLEX_SAMPLESx/2400; // gives the sub-sampling rate leading to f=240 kHz
length_ouput = &FRAME_LENGTH_COMPLEX_SUB_SAMPLES;
Rx_sub_sampled_buffer_128 = sub_sampling_NB_IoT(filtered_buffer,FRAME_LENGTH_COMPLEX_SAMPLESx,length_ouput, sub_sampling_rate);
// Detection and TA estimation stage /============================================================/
if (NPRACH_detection_NB_IoT(Rx_sub_sampled_buffer_128,*length_ouput)){
/* estimated_TA_coarse = TA_estimation_NB_IoT(eNB,
Rx_sub_sampled_buffer_128,
sub_sampling_rate,
FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
estimated_TA_coarse,
coarse);
// 2. Fine TA estimation using sub sampling rate = 16, i.e. fs = 1.92 MHz
// Sub-sampling stage /============================================================/
//// sub_sampling_rate = FRAME_LENGTH_COMPLEX_SAMPLESx/(2400*8);
Rx_sub_sampled_buffer_16 = sub_sampling_NB_IoT(filtered_buffer,FRAME_LENGTH_COMPLEX_SAMPLESx,length_ouput, sub_sampling_rate);
// Fine TA estimation stage /============================================================/
// start1 = clock();
coarse = 0;
estimated_TA = TA_estimation_NB_IoT(eNB,
Rx_sub_sampled_buffer_16,
sub_sampling_rate,
FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
estimated_TA_coarse,
coarse); //
// Needs to be stored in a variable in PHY_VARS_eNB_NB_IoT structure
//for (n=0;n<FRAME_LENGTH_COMPLEX_SAMPLESx;n++){
//printf(" buf%i= %i",n,Rx_sub_sampled_buffer_128[2*n]);
// fprintf(f," %i %i ",Rx_buffer[2*n],Rx_buffer[2*n+1]);
//fprintf(f,"%i \n",Rx_buffer[2*n+1]);
//}*/
printf("\ndetection !!! at frame %i \n",frame);
//eNB->preamble_index_NB_IoT = subcarrier_estimation(Rx_sub_sampled_buffer_128); // c'est un uint16_t
*preamble_index = subcarrier_estimation(Rx_sub_sampled_buffer_128);
*timing_advance = 0;
*rnti = 1 + frame/4;
printf("estimated subaccier = %i\n",*preamble_index);
return 1;//estimated_TA;
}else{
return 0;
}
// }
return 0;
}
/*
* 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 IF_Module_L1_primitives_NB_IoT.c
* \brief handling nfapi
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
//#include "PHY/LTE_TRANSPORT/dlsch_tbs_full_NB_IoT.h"
#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
#include "IF_Module_L1_primitives_NB_IoT.h"
//#include "../SCHED/defs.h"
#include "defs_NB_IoT.h"
#include "assertions.h"
//#include "PHY/defs.h"
#include "PHY/defs_L1_NB_IoT.h"
//#include "PHY/extern.h"
#include "PHY/extern_NB_IoT.h"
#include "PHY/phy_extern.h"
//#include "PHY/vars.h"
#include "PHY/INIT/defs_NB_IoT.h"
int Irep_to_Nrep_x[16] = {1,2,4,8,16,32,64,128,192,256,384,512,768,1024,1536,2048};
void handle_nfapi_dlsch_pdu_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t *sdu)
{
NB_IoT_eNB_NDLSCH_t *ndlsch;
NB_IoT_eNB_NDLSCH_t *ndlsch23;
NB_IoT_DL_eNB_HARQ_t *ndlsch_harq;
NB_IoT_DL_eNB_HARQ_t *ndlsch_harq23;
nfapi_dl_config_ndlsch_pdu_rel13_t *rel13 = &dl_config_pdu->ndlsch_pdu.ndlsch_pdu_rel13;
int UE_id= -1;
int flag_malloc = 0;
ndlsch= eNB->ndlsch_SIB1;
ndlsch23= eNB->ndlsch_SIB23;
// if(flag_malloc) free (ndlsch->harq_process);
// ndlsch->harq_process = (NB_IoT_DL_eNB_HARQ_t*) malloc (sizeof(NB_IoT_DL_eNB_HARQ_t));
flag_malloc = 1 ;
//Check for SI PDU since in NB-IoT there is no DCI for that
//SIB1 (type 0), other DLSCH data (type 1) (include the SI messages) based on our ASSUMPTIONs
//is SIB1-NB
if(rel13->rnti_type == 0 && rel13->rnti == 65535)
{
/*
* the configuration of the NDLSCH PDU for the SIB1-NB shoudl be the following:
* -RNTI type = 0; (BCCH)
* -RNTI = OxFFFF (65535)
* -Repetition number = 0-15 and should be mapped to 4,8,16 as reported in Table 16.4.1.3-3 TS 36.213 (is the schedulingInoSIB1 of the MIB)
* -Number of subframe for resource assignment = may is not neded to know since the scheduling is fixed
* (Spec TS 36.331 "SIB1-NB transmission occur in subframe #4 of every other frame in 16 continuous frame"
* meaning that from the starting point we should transmit the SIB1-NB in 8 subframes among the 16 available (every other))
*
* From spec. TS 36.321 v14.2.o pag 31 --> there is an HARQ process for all the broadcast (so we consider it also for SIB1-NB)
*
*/
//LOG_I(PHY,"B NB-handle_nfapi_dlsch_pdu_NB_IoT SIB1\n");
ndlsch->active = 1;
ndlsch->rnti = 65535;
ndlsch_harq = ndlsch->harq_process;
ndlsch->ndlsch_type = SIB1;
ndlsch->npdsch_start_symbol = rel13->start_symbol; //start symbol for the ndlsch transmission
//ndlsch_harq->pdu = sdu;
//LOG_I(PHY,"B content_sib1:%d\n",sdu);
/////ndlsch->content_sib1.pdu = sdu;
ndlsch_harq->pdu = sdu;
//LOG_I(PHY,"A content_sib1:%d\n",ndlsch->content_sib1.pdu);
//should be from 1 to 8
ndlsch->resource_assignment_SIB1 = rel13->number_of_subframes_for_resource_assignment;//maybe we don't care about it since a fixed schedule
ndlsch->repetition_number_SIB1 = rel13->repetition_number; //is the schedulingInfoSIB1 (value 1-15) of MIB that is mapped into value 4-8-16 (see NDLSCH fapi specs Table 4-47)
ndlsch->modulation = rel13->modulation;
ndlsch->status = ACTIVE_NB_IoT;
//ndlsch->
//SI information in reality have no feedback (so there is no retransmission from the HARQ view point since no ack and nack)
// ndlsch_harq->frame = frame;
// ndlsch_harq->subframe = subframe;
ndlsch->nrs_antenna_ports = rel13->nrs_antenna_ports_assumed_by_the_ue;
ndlsch->scrambling_sequence_intialization = rel13->scrambling_sequence_initialization_cinit;
//LOG_I(PHY,"A NB-handle_nfapi_dlsch_pdu_NB_IoT SIB1\n");
ndlsch_harq->TBS = TBStable_NB_IoT_SIB1[rel13->repetition_number];
}
//is SI message (this is an NDLSCH that will be transmitted very frequently)
else if(rel13->rnti_type == 1 && rel13->rnti == 65535)
{
/*
*
* the configuration of the NDLSCH PDU for the SIB1-NB should be the following:
* RNTI type = 1;
* RNTI = OxFFFF (65535)
* Repetition number = 0 and should be mapped to 1 through Table 16.4.1.3-2 TS 36.213
* Number of subframe for resource assignment = will be evaluated by the MAC based on the value of the "si-TB" field inside the SIB1-NB (value 2 or 8)
*
* From spec. TS 36.321 v14.2.o pag 31 --> there is an HARQ process for all the broadcast
*
* XXX for the moment we are not able to prevent the problem of Error: first transmission but sdu = NULL.
* anyway, the PHY layer if have finished the transmission it will not transmit anything and will generate the error
*
*/
//LOG_I(PHY,"B NB-handle_nfapi_dlsch_pdu_NB_IoT SIB23\n");
ndlsch_harq23 = ndlsch23->harq_process;
//new SI starting transmission (should enter here only the first time for a new transmission)
if(sdu != NULL)
{
ndlsch23->active = 1;
ndlsch23->ndlsch_type = SI_Message;
ndlsch23->rnti = 65535;
ndlsch23->npdsch_start_symbol = rel13->start_symbol; //start OFDM symbol for the ndlsch transmission
//ndlsch_harq->pdu = sdu;
//LOG_I(PHY,"B content_sib23:%d\n",sdu);
ndlsch_harq23->pdu = sdu;
ndlsch_harq23->repetition_number = rel13->repetition_number;//should be always fix to 0 to be mapped in 1
ndlsch_harq23->modulation = rel13->modulation;
ndlsch_harq23->TBS = rel13->length;
//LOG_I(PHY,"A content_sib23:%d\n",sdu);
ndlsch23->resource_assignment = rel13->number_of_subframes_for_resource_assignment;//value 2 or 8
ndlsch23->counter_repetition_number = rel13->number_of_subframes_for_resource_assignment;
ndlsch23->counter_current_sf_repetition = 0;
ndlsch23->pointer_to_subframe = 0;
//SI information in reality have no feedback (so there is no retransmission from the HARQ view point since no sck and nack)
// ndlsch_harq->frame = frame;
// ndlsch_harq->subframe = subframe;
ndlsch23->nrs_antenna_ports = rel13->nrs_antenna_ports_assumed_by_the_ue;
ndlsch23->scrambling_sequence_intialization = rel13->scrambling_sequence_initialization_cinit;
}
else
{
//continue the remaining transmission of the previous SI at PHY if any (otherwise nothing)
//there is no need of repeating the configuration on the ndlsch
//ndlsch_harq->pdu = NULL;
//LOG_I(PHY,"sib23=NULL\n");
ndlsch_harq23->pdu = NULL;
}
//Independently if we have the PDU or not (first transmission or repetition) the process is activated for triggering the ndlsch_procedure
//LOG_I(PHY,"ACTIVE_NB_IoT\n");
ndlsch_harq23->status = ACTIVE_NB_IoT;
//LOG_D(PHY,"A NB-handle_nfapi_dlsch_pdu_NB_IoT SIB23\n");
}
//ue specific data or RAR (we already have received the DCI for this)
else if(rel13->rnti != 65535 && rel13->rnti_type == 1)
{
//printf("rel13->rnti: %d, eNB->ndlsch_RAR->rnti: %d\n",rel13->rnti,eNB->ndlsch_RAR->rnti);
//eNB->ndlsch_RAR->rnti = rel13->rnti;
//check if the PDU is for RAR
//if(eNB->ndlsch_RAR != NULL && eNB->ndlsch_RAR->ndlsch_type == RAR) //rnti for the RAR should have been set priviously by the DCI
if(eNB->ndlsch_RAR != NULL && rel13->rnti == eNB->ndlsch_RAR->rnti) //rnti for the RAR should have been set priviously by the DCI
{
eNB->ndlsch_RAR->active = 1;
eNB->ndlsch_RAR->active_msg2 = 1; /// activated only when NPDSCH is transmitting msg2
eNB->ndlsch_RAR->rnti = rel13->rnti;
eNB->ndlsch_RAR->npdsch_start_symbol = rel13->start_symbol;
eNB->ndlsch_RAR->rnti_type = rel13->rnti_type;
eNB->ndlsch_RAR->resource_assignment = rel13->resource_assignment; // for NDLSCH // this value point to --> number of subframes needed
eNB->ndlsch_RAR->repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
eNB->ndlsch_RAR->modulation = rel13->modulation;
eNB->ndlsch_RAR->number_of_subframes_for_resource_assignment = rel13->number_of_subframes_for_resource_assignment; // for NDLSCH //table 16.4.1.3-1 // TS 36.213
eNB->ndlsch_RAR->counter_repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
eNB->ndlsch_RAR->counter_current_sf_repetition = 0;
eNB->ndlsch_RAR->pointer_to_subframe = 0;
//printf("number of subframe : %d, Rep of subframe : %d\n",eNB->ndlsch_RAR->number_of_subframes_for_resource_assignment,eNB->ndlsch_RAR->counter_repetition_number);
eNB->ndlsch_RAR->harq_process->TBS = rel13->length;
eNB->ndlsch_RAR->harq_process->pdu = sdu;
}
else
{ //this for ue data
//TODO
LOG_I(PHY,"handling MSG4 or ue-spec data\n");
//program addition DLSCH parameters not from DCI (for the moment we only pass the pdu)
//int UE_id = find_dlsch(rel13->rnti,eNB,SEARCH_EXIST);
UE_id = 0;
//UE_id = find_ue_NB_IoT(rel13->rnti,eNB);
//AssertFatal(UE_id==-1,"no existing ue specific dlsch_context\n");
ndlsch = eNB->ndlsch[(uint8_t)UE_id];
ndlsch_harq = eNB->ndlsch[(uint8_t)UE_id]->harq_process;
AssertFatal(ndlsch_harq!=NULL,"dlsch_harq for ue specific is null\n");
ndlsch->active = 1;
ndlsch->rnti = rel13->rnti; // how this value is tested in line 177 ???? i am missing something ????
ndlsch->npdsch_start_symbol = rel13->start_symbol;
ndlsch->rnti_type = rel13->rnti_type;
ndlsch->resource_assignment = rel13->resource_assignment ; // for NDLSCH // this value point to --> number of subframes needed
ndlsch->repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
ndlsch->modulation = rel13->modulation;
ndlsch->number_of_subframes_for_resource_assignment = rel13->number_of_subframes_for_resource_assignment; // for NDLSCH //table 16.4.1.3-1 // TS 36.213
ndlsch->counter_repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
ndlsch->counter_current_sf_repetition = 0;
ndlsch->pointer_to_subframe = 0;
ndlsch_harq->TBS = rel13->length;
ndlsch_harq->pdu = sdu;
}
}
//I don't know which kind of data is
else
{
LOG_E(PHY, "handle_nfapi_dlsch_pdu_NB_IoT: Unknown type of data (rnti type %d, rnti %d)\n", rel13->rnti_type, rel13->rnti);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//Memo for initialization TODO: target/SIMU/USER/init_lte.c/init_lte_eNB --> new_eNB_dlsch(..) //
//this is where the allocation of PHy_vars_eNB_NB_IoT and all the ndlsch structures happen //
/////////////////////////////////////////////////////////////////////////////////////////////////
// do the schedule response and trigger the TX
void schedule_response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO)
{
//LOG_I(PHY,"schedule_response_NB_IoT\n");
//XXX check if correct to take eNB like this
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][Sched_INFO->CC_id];
eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];
NB_IoT_eNB_NPBCH_t *npbch;
///
int i;
//module_id_t Mod_id = Sched_INFO->module_id;
//uint8_t CC_id = Sched_INFO->CC_id;
nfapi_dl_config_request_t *DL_req = Sched_INFO->DL_req;
nfapi_ul_config_request_t *UL_req = Sched_INFO->UL_req;
nfapi_hi_dci0_request_t *HI_DCI0_req = Sched_INFO->HI_DCI0_req;
nfapi_tx_request_t *TX_req = Sched_INFO->TX_req;
//uint32_t hypersfn = Sched_INFO->hypersfn;
//frame_t frame = Sched_INFO->frame; // unused for instance
sub_frame_t subframe = Sched_INFO->subframe;
// implicite declaration of AssertFatal
//AsserFatal(proc->subframe_tx != subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe);
//AsserFatal(proc->frame_tx != frame, "Current sframe %d != NFAPI frame %d\n", proc->frame_tx,frame );
uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu;
uint8_t number_ul_pdu = UL_req->ul_config_request_body.number_of_pdus;
uint8_t number_ul_dci = HI_DCI0_req->hi_dci0_request_body.number_of_dci;
/*
if(number_dl_pdu>=5) number_dl_pdu=0;
if(number_ul_dci>=5) number_ul_dci=0;
*/
//uint8_t number_pdsch_rnti = DL_req->number_pdsch_rnti; // for the moment not used
// at most 2 pdus (DCI) in the case of NPDCCH
nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_ul_config_request_pdu_t *ul_config_pdu;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
//clear previous possible allocation (maybe something else should be added)
for(int i = 0; i < NUMBER_OF_UE_MAX_NB_IoT; i++)
{
if(eNB->ndlsch[i])
{
eNB->ndlsch[i]->harq_process->round=0; // may not needed
/*clear previous allocation information for all UEs*/
eNB->ndlsch[i]->subframe_tx[subframe] = 0;
}
/*clear the DCI allocation maps for new subframe*/
if(eNB->nulsch[i])
{
eNB->nulsch[i]->harq_process->dci_alloc = 0; //flag for indicating that a DCI has been allocated for UL
eNB->nulsch[i]->harq_process->rar_alloc = 0; //Flag indicating that this ULSCH has been allocated by a RAR (for Msg3)
//no phich for NB-IoT so no DMRS should be utilized
}
}
for (i=0;i<number_dl_pdu;i++) //in principle this should be at most 2 (in case of DCI)
{
dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i];
//LOG_I(PHY, "number_dl_pdu: %d ,dl_config_pdu type: %d\n",number_dl_pdu,dl_config_pdu->pdu_type);
switch (dl_config_pdu->pdu_type)
{
case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE:
//Remember: there is no DCI for SI information
//LOG_D(PHY,"Generate DL DCI PDU information from scheduler\n");
//TODO: separate the ndlsch structure configuration from the DCI (here we will encode only the DCI)
generate_eNB_dlsch_params_NB_IoT(eNB,proc,dl_config_pdu);
break;
case NFAPI_DL_CONFIG_NBCH_PDU_TYPE:
// for the moment we don't care about the n-bch pdu content since we need only the sdu if tx.request
npbch = &eNB->npbch; //in the main of the lte-softmodem they should allocate this memory of PHY_vars
npbch->h_sfn_lsb = dl_config_pdu->nbch_pdu.nbch_pdu_rel13.hyper_sfn_2_lsbs;
//LOG_I(PHY,"npbch->pdu\n");
dl_config_pdu->nbch_pdu.nbch_pdu_rel13.pdu_index = 1;
if(TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->nbch_pdu.nbch_pdu_rel13.pdu_index].segments[0].segment_data != NULL)
npbch->pdu = TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->nbch_pdu.nbch_pdu_rel13.pdu_index].segments[0].segment_data;
else
LOG_E(PHY, "Received a schedule_response with N-BCH but no SDU!!\n");
break;
case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE:
//we can have three types of NDLSCH based on our assumptions: SIB1, SI, Data, RAR
//remember that SI messages have no DCI in NB-IoT therefore this is the only way to configure the ndlsch_SI/ndlsch_SIB1 structures ndlsch->active = 1;
/*
* OBSERVATION:
* Although 2 DCI may be received over a schedule_response the transmission of the NDLSCH data foresees only 1 NDLSCH PDU at time.
* Therefore is the MAC scheduler that knowing the different timing delay will send the corresponding schedule_response containing the NDLSCH PDU and the MAC PDU
* at the proper DL subframe
* -for this reason the activation of the ndslch structure is done only when we receive the NDLSCH pdu (here) such the in the TX procedure only 1 ue-specific pdu
* result active from the loop before calling the ndlsch_procedure
*/
dl_config_pdu->ndlsch_pdu.ndlsch_pdu_rel13.pdu_index = 1;
handle_nfapi_dlsch_pdu_NB_IoT(eNB, proc,dl_config_pdu,TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->ndlsch_pdu.ndlsch_pdu_rel13.pdu_index].segments[0].segment_data);
break;
default:
LOG_D(PHY, "dl_config_pdu type not for NB_IoT\n");
break;
}
}
for (i=0;i<number_ul_dci;i++)
{
hi_dci0_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
LOG_D(PHY, "number_ul_dci:%d ,hi_dci0_pdu->pdu_type: %d\n",number_ul_dci,hi_dci0_pdu->pdu_type);
switch (hi_dci0_pdu->pdu_type)
{
case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE:
LOG_I(PHY, "hi_dci0_pdu type for NB_IoT\n");
generate_eNB_ulsch_params_NB_IoT(eNB,proc,hi_dci0_pdu);
break;
default:
LOG_E(PHY, "hi_dci0_pdu type not for NB_IoT\n");
break;
}
}
for(i = 0; i< number_ul_pdu; i++)
{
ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i];
NB_IoT_eNB_NULSCH_t *nulsch;
NB_IoT_UL_eNB_HARQ_t *nulsch_harq;
nfapi_ul_config_nulsch_pdu_rel13_t *nfapi_parameters_rel13 = &ul_config_pdu->nulsch_pdu.nulsch_pdu_rel13;
switch(ul_config_pdu->pdu_type)
{
case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE:
if(nfapi_parameters_rel13->nulsch_format==0)
{
// new condition should be added to identify if this is msg3 3 since the TBS_table is not the same.
// the type of subcarrier spacing should be specified before the call of rx_ulsch since the parameter does not exist in nfapi parameters.
//TODO should distinguish between data and between data (npusch format)
/*NB: for reception of Msg3 generally not exist a DCI (because scheduling information are implicitly given by the RAR)
* but in case of FAPI specs we should receive an UL_config (containing the NULSCH pdu) for configuring the PHY for Msg3 reception from the MAC
* (this UL_config most probably will be created by the MAC when fill the RAR)
* (most probably we don't have the DL_config (for the RAR transmission) and the UL_CONFIG (for the Msg3 reception) at the same time (same subrame)
* since we are working in HD-FDD mode so for sure the UE will transmit the Msg3 in another subframe so make sense to have a UL_CONFIG in subframe
* diferent from the DL_CONFIG one)
*
*/
///////////////////////////////////////////////////////////////////////////////////////////
//maybe this condition should be replaced by another test ?!
if(nfapi_parameters_rel13->size < 80) // msg3 data
{
nulsch = eNB->ulsch_NB_IoT[0];
nulsch_harq = nulsch->harq_process;
nulsch->Msg3_active = 1;
nulsch->Msg3_flag = 1;
nulsch->flag_vars = 1;
nulsch->rnti = nfapi_parameters_rel13->rnti;
nulsch->npusch_format = nfapi_parameters_rel13->nulsch_format;
nulsch->N_srs = nfapi_parameters_rel13->n_srs;
nulsch->C_init = nfapi_parameters_rel13->scrambling_sequence_initialization_cinit;
nulsch->SF_idx = nfapi_parameters_rel13->sf_idx;
nulsch->HARQ_ACK_resource = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource;
//nulsch_harq->subcarrier_spacing = nfapi_parameters_rel13->handle; // get from the UL_grant of MSG3
nulsch_harq->subcarrier_indication = nfapi_parameters_rel13->subcarrier_indication; // Isc =0->18 , or 0->47 // format 2, 0->3 or 0->7
nulsch_harq->resource_assignment = nfapi_parameters_rel13->resource_assignment; // valid for format 1 // this should be set by DCI N0 // not used for msg3 // I_RU --> helps to get N_RU
nulsch_harq->mcs = nfapi_parameters_rel13->mcs; // I_mcs = 0->10 (single tone) and 0->12 (multi-tone)
nulsch_harq->rvidx = nfapi_parameters_rel13->redudancy_version; // values = 0 or 1
nulsch_harq->repetition_number = nfapi_parameters_rel13->repetition_number; // // N_rep values = 0->7 // new funciton to be created to compute the nb_slots = f(N_rep)
nulsch_harq->new_data_indication = nfapi_parameters_rel13->new_data_indication; // valid only for DCI N0
nulsch_harq->TBS = nfapi_parameters_rel13->size; /// check if needed *8 or /8 or nothing to do
} else{ // other npusch data
nulsch = eNB->ulsch_NB_IoT[0];
nulsch_harq = nulsch->harq_process;
nulsch->Msg3_active = 1;
nulsch->Msg3_flag = 0;
nulsch->flag_vars = 1;
nulsch->rnti = nfapi_parameters_rel13->rnti;
nulsch->npusch_format = nfapi_parameters_rel13->nulsch_format;
nulsch->N_srs = nfapi_parameters_rel13->n_srs;
nulsch->C_init = nfapi_parameters_rel13->scrambling_sequence_initialization_cinit;
nulsch->SF_idx = nfapi_parameters_rel13->sf_idx;
nulsch->HARQ_ACK_resource = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource;
//nulsch_harq->subcarrier_spacing = nfapi_parameters_rel13->handle; // get from the UL_grant of MSG3
nulsch_harq->subcarrier_indication = nfapi_parameters_rel13->subcarrier_indication; // Isc =0->18 , or 0->47 // format 2, 0->3 or 0->7
nulsch_harq->resource_assignment = nfapi_parameters_rel13->resource_assignment; // valid for format 1 // this should be set by DCI N0 // not used for msg3 // I_RU --> helps to get N_RU
nulsch_harq->mcs = nfapi_parameters_rel13->mcs; // I_mcs = 0->10 (single tone) and 0->12 (multi-tone)
nulsch_harq->rvidx = nfapi_parameters_rel13->redudancy_version; // values = 0 or 1
nulsch_harq->repetition_number = nfapi_parameters_rel13->repetition_number; // // N_rep values = 0->7 // new funciton to be created to compute the nb_slots = f(N_rep)
nulsch_harq->new_data_indication = nfapi_parameters_rel13->new_data_indication; // valid only for DCI N0
nulsch_harq->TBS = nfapi_parameters_rel13->size; /// check if needed *8 or /8 or nothing to do
}
//nulsch_harq->rep_tmp = ;
////////////////////////////////////////////////////////////////////////////////////////
LOG_I(PHY,"subframe = %d (TX timing), IF module proceed UL config NULSCH data pdu, will trigger npusch in next subframe\n",subframe);
}else
{
nulsch = eNB->ulsch_NB_IoT[0];
nulsch_harq = nulsch->harq_process;
nulsch->Msg3_active = 1;
nulsch->Msg3_flag = 0;
nulsch->flag_vars = 1;
nulsch->rnti = nfapi_parameters_rel13->rnti;
nulsch->npusch_format = nfapi_parameters_rel13->nulsch_format;
nulsch->N_srs = nfapi_parameters_rel13->n_srs;
nulsch->C_init = nfapi_parameters_rel13->scrambling_sequence_initialization_cinit;
nulsch->SF_idx = nfapi_parameters_rel13->sf_idx;
nulsch->HARQ_ACK_resource = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource;
//nulsch_harq->subcarrier_spacing = nfapi_parameters_rel13->handle; // get from the UL_grant of MSG3
nulsch_harq->subcarrier_indication = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource; // Isc =0->18 , or 0->47 // format 2, 0->3 or 0->7
nulsch_harq->resource_assignment = nfapi_parameters_rel13->resource_assignment; // valid for format 1 // this should be set by DCI N0 // not used for msg3 // I_RU --> helps to get N_RU
nulsch_harq->mcs = nfapi_parameters_rel13->mcs; // I_mcs = 0->10 (single tone) and 0->12 (multi-tone)
nulsch_harq->rvidx = nfapi_parameters_rel13->redudancy_version; // values = 0 or 1
nulsch_harq->repetition_number = nfapi_parameters_rel13->ue_information.ue_information_rel13.total_number_of_repetitions; // // N_rep values = 0->7 // new funciton to be created to compute the nb_slots = f(N_rep)
nulsch_harq->new_data_indication = nfapi_parameters_rel13->new_data_indication; // valid only for DCI N0
nulsch_harq->TBS = nfapi_parameters_rel13->size; /// check if needed *8 or /8 or nothing to do
LOG_I(PHY,"subframe = %d (TX timing), IF module proceed UL config NULSCH ack pdu, will trigger npusch in next subframe\n",subframe);
}
break;
case NFAPI_UL_CONFIG_NRACH_PDU_TYPE:
//TODO just for update the nprach configuration (given at the beginning through phy_config_sib2)
break;
}
}
//XXX problem: although we may have nothing to transmit this function should be always triggered in order to allow the PHY layer to complete the repetitions
//of previous Transport Blocks
//phy_procedures_eNB_TX_NB_IoT(eNB,proc,NULL);
//phy_procedures_eNB_TX_NB_IoT(eNB,proc,0); // check if 0 or NULL ?!
LOG_D(PHY,"Schedule response has been done\n");
}
void PHY_config_req_NB_IoT(PHY_Config_NB_IoT_t* config_INFO){
LOG_D(PHY,"[NB-IoT] PHY CONFIG REQ NB-IoT In\n");
if(config_INFO->get_MIB != 0){
//MIB-NB configuration
phy_config_mib_eNB_NB_IoT(config_INFO->mod_id,
config_INFO->CC_id,
config_INFO->cfg->nfapi_config.rf_bands.rf_band[0],//eutraband
config_INFO->cfg->sch_config.physical_cell_id.value,
config_INFO->cfg->subframe_config.dl_cyclic_prefix_type.value,
config_INFO->cfg->subframe_config.ul_cyclic_prefix_type.value,
config_INFO->cfg->rf_config.tx_antenna_ports.value,
config_INFO->cfg->nfapi_config.earfcn.value,
config_INFO->cfg->nb_iot_config.prb_index.value,
config_INFO->cfg->nb_iot_config.operating_mode.value,
config_INFO->cfg->nb_iot_config.control_region_size.value,
config_INFO->cfg->nb_iot_config.assumed_crs_aps.value); //defined only in in-band different PCI
}
if(config_INFO->get_COMMON != 0)
{
//Common Configuration included in SIB2-NB
phy_config_sib2_eNB_NB_IoT(config_INFO->mod_id,
config_INFO->CC_id,
&config_INFO->cfg->nb_iot_config, // FIXME to be evaluated is should be passed a pointer
&config_INFO->cfg->rf_config,
&config_INFO->cfg->uplink_reference_signal_config,
&config_INFO->extra_phy_parms);
}
///FOR FAPI is not specified
if(config_INFO->get_DEDICATED!= 0)
{
//Dedicated Configuration
/*phy_config_dedicated_eNB_NB_IoT(config_INFO->mod_id,
config_INFO->CC_id,
config_INFO->rnti,
&config_INFO->extra_phy_parms);*/
}
LOG_D(PHY,"IF Module for PHY Configuration has been done\n");
}
......@@ -9,6 +9,7 @@
//#include "openair2/PHY_INTERFACE/IF_Module_nb_iot.h"
#include "nfapi_interface.h"
extern uint16_t hundred_times_log10_NPRB_NB_IoT[100];
enum openair_HARQ_TYPE_NB_IoT {
......
......@@ -1347,3 +1347,63 @@ void fill_rx_indication_NB_IoT(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t d
}
void prach_procedures_NB_IoT(PHY_VARS_eNB *eNB) {
// LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
// uint16_t preamble_energy_list[64],preamble_delay_list[64];
// uint16_t preamble_max,preamble_energy_max;
// uint16_t preamble_max=0;
// uint16_t i;
// int8_t UE_id;
uint16_t rnti[4],preamble_index[4],timing_advance_preamble[4];
// uint16_t i;
// int frame,subframe;
uint8_t subframe = eNB->proc.subframe_prach;
int frame = eNB->proc.frame_prach;
// uint8_t CC_id = eNB->CC_id;
uint32_t detection=0;
//uint16_t estimated_TA=2;
if (eNB->abstraction_flag == 0) {
/* rx_prach(eNB,
preamble_energy_list,
preamble_delay_list,
frame,
0);*/
detection = rx_nprach_NB_IoT(eNB,frame,subframe,rnti,preamble_index,timing_advance_preamble);
}
if(detection == 1) ////////////////////////// to be moved to handle_rach_NB_IoT
{
pthread_mutex_lock(&eNB->UL_INFO_mutex);
//////////////////////////////////////////////////////////
eNB->UL_INFO.nrach_ind.number_of_initial_scs_detected = 1; //!!!!!!!!!!!!! // should be set to zero in every call of UL_indication !!!!!!!!!!!!!!!!!!!!!!!
eNB->UL_INFO.nrach_ind.nrach_pdu_list[0].nrach_indication_rel13.rnti = rnti[0];
eNB->UL_INFO.nrach_ind.nrach_pdu_list[0].nrach_indication_rel13.initial_sc = preamble_index[0];
eNB->UL_INFO.nrach_ind.nrach_pdu_list[0].nrach_indication_rel13.timing_advance = timing_advance_preamble[0];
eNB->UL_INFO.nrach_ind.nrach_pdu_list[0].nrach_indication_rel13.nrach_ce_level = 2;
eNB->UL_INFO.frame = frame;
eNB->UL_INFO.subframe = subframe;
eNB->UL_INFO.hypersfn = eNB->proc.proc_rxtx[0].HFN;
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
/*initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf),
NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf),
UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble,
UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti);
mac_xface->initiate_ra_proc(eNB->Mod_id,
eNB->CC_id,
frame,
preamble_index[0],
(int16_t) timing_advance_preamble[0],
0,subframe,0);*/
}
}
\ No newline at end of file
/* 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 asn1_msg.c
* \brief primitives to build the asn1 messages
* \author Raymond Knopp, Navid Nikaein and Michele Paffetti
* \date 2011, 2017
* \version 1.0
* \company Eurecom
* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it
*/
#ifdef USER_MODE
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h> /* for atoi(3) */
#include <unistd.h> /* for getopt(3) */
#include <string.h> /* for strerror(3) */
#include <sysexits.h> /* for EX_* exit codes */
#include <errno.h> /* for errno */
#else
//#include <linux/module.h> /* Needed by all modules */
#endif
#ifdef USER_MODE
//#include "RRC/LITE/defs.h"
//#include "COMMON/mac_rrc_primitives.h"
#include "common/utils/LOG/log.h"
#endif
#include <asn_application.h>
#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */
#include <per_encoder.h>
#include "assertions.h"
#include "RRC/LTE/MESSAGES/asn1_msg.h"
//#include for NB-IoT-------------------
#include "LTE_RRCConnectionRequest-NB.h"
#include "LTE_BCCH-DL-SCH-Message-NB.h"
#include "LTE_UL-CCCH-Message-NB.h"
#include "LTE_UL-DCCH-Message-NB.h"
#include "LTE_DL-CCCH-Message-NB.h"
#include "LTE_DL-DCCH-Message-NB.h"
#include "LTE_EstablishmentCause-NB-r13.h"
#include "LTE_RRCConnectionSetup-NB.h"
#include "LTE_SRB-ToAddModList-NB-r13.h"
#include "LTE_DRB-ToAddModList-NB-r13.h"
#include "RRC/NBIOT/defs_NB_IoT.h"
#include "LTE_RRCConnectionSetupComplete-NB.h"
#include "LTE_RRCConnectionReconfigurationComplete-NB.h"
#include "LTE_RRCConnectionReconfiguration-NB.h"
#include "LTE_MasterInformationBlock-NB.h"
#include "LTE_SystemInformation-NB.h"
#include "LTE_SystemInformationBlockType1.h"
#include "LTE_SIB-Type-NB-r13.h"
#include "LTE_RRCConnectionResume-NB.h"
#include "LTE_RRCConnectionReestablishment-NB.h"
#include "PHY/defs_L1_NB_IoT.h"
//----------------------------------------
//#include "PHY/defs.h"
#include "enb_config.h"
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif
#ifndef USER_MODE
#define msg printk
#ifndef errno
int errno;
#endif
#else
# if !defined (msg)
# define msg printf
# endif
#endif
/*do_MIB_NB_NB_IoT*/
uint8_t do_MIB_NB_IoT(
rrc_eNB_carrier_data_NB_IoT_t *carrier,
uint16_t N_RB_DL,//may not needed--> for NB_IoT only 1 PRB is used
uint32_t frame,
uint32_t hyper_frame)
{
asn_enc_rval_t enc_rval;
LTE_BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT);
/*
* systemFrameNumber-MSB: (TS 36.331 pag 576)
* define the 4 MSB of the SFN (10 bits). The last significant 6 bits will be acquired implicitly by decoding the NPBCH
* NOTE: 6 LSB will be used for counting the 64 frames in the TTI period (640 ms) that is exactly the MIB period
*
* hyperSFN-LSB:
* indicates the 2 least significant bits of the HSFN. The remaining 8 bits are present in SIB1-NB
* NOTE: with the 2 bits we count the 4 HSFN (is 1 SIB1-Nb modification period) while the other 6 count the number of modification periods
*
*
* NOTE: in OAI never modify the SIB messages!!??
*/
//printf("Frame %d",frame);
//printf("HFN %d",hyper_frame);
//XXX check if correct the bit assignment
uint8_t sfn_MSB = (uint8_t)((frame>>2) & 0xf0);//(uint8_t)((frame>>6) & 0x0f); // all the 4 bits are set to 1
uint8_t hsfn_LSB = (uint8_t)((hyper_frame<<6) & 0xc0);///(uint8_t)(hyper_frame & 0x03); //2 bits set to 1 (0x3 = 0011)
uint16_t spare=0; //11 bits --> use uint16
//printf("Frame %d",sfn_MSB);
//printf("HFN %d",hsfn_LSB);
mib_NB_IoT->message.systemFrameNumber_MSB_r13.buf = &sfn_MSB;
mib_NB_IoT->message.systemFrameNumber_MSB_r13.size = 1; //if expressed in byte
mib_NB_IoT->message.systemFrameNumber_MSB_r13.bits_unused = 4; //is byte based (so how many bits you don't use of the 8 bits of a bite
mib_NB_IoT->message.hyperSFN_LSB_r13.buf= &hsfn_LSB;
mib_NB_IoT->message.hyperSFN_LSB_r13.size= 1;
mib_NB_IoT->message.hyperSFN_LSB_r13.bits_unused = 6;
//XXX to be set??
mib_NB_IoT->message.spare.buf = (uint8_t *)&spare;
mib_NB_IoT->message.spare.size = 2;
mib_NB_IoT->message.spare.bits_unused = 5;
//decide how to set it
mib_NB_IoT->message.schedulingInfoSIB1_r13 =10; //see TS 36.213-->tables 16.4.1.3-3 ecc... // to make 8 repetitions
mib_NB_IoT->message.systemInfoValueTag_r13= 0;
mib_NB_IoT->message.ab_Enabled_r13 = 0;
//to be decided
mib_NB_IoT->message.operationModeInfo_r13.present = LTE_MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13;
mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 8; /// TODO: take into account RB_index of NB-IoT
// printf("[MIB] Intialization of frame information ,sfn_MSB %x, hsfn_LSB %x\n",
// (uint32_t)sfn_MSB,
// (uint32_t)hsfn_LSB);
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message_NB,
NULL,
(void*)mib_NB_IoT,
carrier->MIB_NB_IoT,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
if (enc_rval.encoded==-1) {
return(-1);
}
return((enc_rval.encoded+7)/8);
}
/*do_SIB1_NB*/
uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id,
rrc_eNB_carrier_data_NB_IoT_t *carrier,
NbIoTRrcConfigurationReq *configuration,
uint32_t frame
)
{
LTE_BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT);
LTE_SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT);
asn_enc_rval_t enc_rval;
LTE_PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT;
LTE_MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3];
LTE_SchedulingInfo_NB_r13_t schedulingInfo_NB_IoT;
LTE_SIB_Type_NB_r13_t sib_type_NB_IoT;
long* attachWithoutPDN_Connectivity = NULL;
attachWithoutPDN_Connectivity = CALLOC(1,sizeof(long));
//long *nrs_CRS_PowerOffset=NULL;
//nrs_CRS_PowerOffset = CALLOC(1, sizeof(long));
long *eutraControlRegionSize=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI)
eutraControlRegionSize = CALLOC(1,sizeof(long));
//long systemInfoValueTagSI = 0;
long *offset=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI)
offset = CALLOC(1,sizeof(long));
memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_NB_t));
bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_NB_PR_c1;
bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13;
memset(&schedulingInfo_NB_IoT,0,sizeof(LTE_SchedulingInfo_NB_r13_t));
memset(&sib_type_NB_IoT,0,sizeof(LTE_SIB_Type_NB_r13_t));
//allocation
*sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13;
/*TS 36.331 v14.2.0 pag 589
* hyperSFN-MSB
* Indicates the 8 most significant bits of the hyper-SFN. Together with the hyper-LSB in MIB-NB the complete HSFN is build up
*/
//FIXME see if correct
uint8_t hyperSFN_MSB = (uint8_t) ((frame>>2)& 0xff);
//XXX to be checked
(*sib1_NB_IoT)->hyperSFN_MSB_r13.buf = &hyperSFN_MSB;
(*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1;
(*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0;
memset(&PLMN_identity_info_NB_IoT,0,sizeof(LTE_PLMN_IdentityInfo_NB_r13_t));
PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc));
memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc));
asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0;
//left as it is???
#if defined(ENABLE_ITTI)
dummy_mcc[0] = (configuration->mcc / 100) % 10;
dummy_mcc[1] = (configuration->mcc / 10) % 10;
dummy_mcc[2] = (configuration->mcc / 1) % 10;
#else
dummy_mcc[0] = 0;
dummy_mcc[1] = 0;
dummy_mcc[2] = 1;
#endif
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]);
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]);
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]);
PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0;
PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0;
#if defined(ENABLE_ITTI)
if (configuration->mnc >= 100) {
dummy_mnc[0] = (configuration->mnc / 100) % 10;
dummy_mnc[1] = (configuration->mnc / 10) % 10;
dummy_mnc[2] = (configuration->mnc / 1) % 10;
} else {
if (configuration->mnc_digit_length == 2) {
dummy_mnc[0] = (configuration->mnc / 10) % 10;
dummy_mnc[1] = (configuration->mnc / 1) % 10;
dummy_mnc[2] = 0xf;
} else {
dummy_mnc[0] = (configuration->mnc / 100) % 100;
dummy_mnc[1] = (configuration->mnc / 10) % 10;
dummy_mnc[2] = (configuration->mnc / 1) % 10;
}
}
#else
dummy_mnc[0] = 0;
dummy_mnc[1] = 1;
dummy_mnc[2] = 0xf;
#endif
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]);
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]);
if (dummy_mnc[2] != 0xf) {
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[2]);
}
//still set to "notReserved" as in the previous case
PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=LTE_PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved;
*attachWithoutPDN_Connectivity = 0;
PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity;
ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.plmn_IdentityList_r13.list,&PLMN_identity_info_NB_IoT);
// 16 bits = 2 byte
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte
//lefts as it is?
#if defined(ENABLE_ITTI)
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (configuration->tac >> 8) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (configuration->tac >> 0) & 0xff;
#else
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01;
#endif
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0;
// 28 bits --> i have to use 32 bits = 4 byte
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte?
#if defined(ENABLE_ITTI)
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (configuration->cell_identity >> 20) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (configuration->cell_identity >> 12) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (configuration->cell_identity >> 4) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (configuration->cell_identity << 4) & 0xf0;
#else
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10;
#endif
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4;
//Still set to "notBarred" as in the previous case
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=LTE_SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred;
//Still Set to "notAllowed" like in the previous case
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=LTE_SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed;
(*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589
(*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 =-22; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value)
(*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(LTE_P_Max_t));
*((*sib1_NB_IoT)->p_Max_r13) = 23;
//FIXME
(*sib1_NB_IoT)->freqBandIndicator_r13 =
#if defined(ENABLE_ITTI)
configuration->eutra_band[CC_id];
#else
5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode)
#endif
// Now, follow the scheduler SIB configuration
// There is only one sib2+sib3 common setting
schedulingInfo_NB_IoT.si_Periodicity_r13= LTE_SchedulingInfo_NB_r13__si_Periodicity_r13_rf64; //SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; // (to be set to 64)
schedulingInfo_NB_IoT.si_RepetitionPattern_r13= LTE_SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every4thRF; //This Indicates the starting radio frames within the SI window used for SI message transmission.
schedulingInfo_NB_IoT.si_TB_r13= LTE_SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits
// This is for SIB2/3
/*SIB3 --> There is no mapping information of SIB2 since it is always present
* in the first SystemInformation message
* listed in the schedulingInfoList list.
* */
sib_type_NB_IoT=LTE_SIB_Type_NB_r13_sibType3_NB_r13;
ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT.sib_MappingInfo_r13.list,&sib_type_NB_IoT);
ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT);
//printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13);
#if defined(ENABLE_ITTI)
if (configuration->frame_type[CC_id] == TDD)
#endif
{
//FIXME in NB-IoT mandatory to be FDD --> so must give an error
LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct?
exit(-1);
}
//FIXME which value chose for the following parameter
*offset =1;
//FIXME which value chose for the following parameter
(*sib1_NB_IoT)->si_WindowLength_r13=LTE_SystemInformationBlockType1_NB__si_WindowLength_r13_ms160;
(*sib1_NB_IoT)->si_RadioFrameOffset_r13=offset;
/////optional parameters, decide to use at future
/*
//system value tag
(*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13));
asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list);
ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI);
// downlink bitmap
(*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13));
((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING;
// CRS power offset
*nrs_CRS_PowerOffset= 0;
(*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset;
*/
*eutraControlRegionSize = 2;
(*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize;
#ifdef XER_PRINT //generate xml files
xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message);
#endif
//bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13 = **sib1_NB_IoT;
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_NB,
NULL,
(void*)bcch_message,
carrier->SIB1_NB_IoT,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
if (enc_rval.encoded==-1) {
return(-1);
}
return((enc_rval.encoded+7)/8);
}
/*do_SIB1_NB*/
uint8_t do_SIB1_NB_IoT_x(uint8_t Mod_id, int CC_id,
rrc_eNB_carrier_data_NB_IoT_t *carrier,
uint16_t mcc,
uint16_t mnc,
uint16_t tac,
uint32_t cell_identity,
uint16_t band,
uint16_t mnc_digit_length,
uint32_t frame)
{
LTE_BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT);
LTE_SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT);
asn_enc_rval_t enc_rval;
LTE_PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT;
LTE_MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3];
LTE_SchedulingInfo_NB_r13_t schedulingInfo_NB_IoT;
LTE_SIB_Type_NB_r13_t sib_type_NB_IoT;
long* attachWithoutPDN_Connectivity = NULL;
attachWithoutPDN_Connectivity = CALLOC(1,sizeof(long));
//long *nrs_CRS_PowerOffset=NULL;
//nrs_CRS_PowerOffset = CALLOC(1, sizeof(long));
long *eutraControlRegionSize=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI)
eutraControlRegionSize = CALLOC(1,sizeof(long));
//long systemInfoValueTagSI = 0;
long *offset=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI)
offset = CALLOC(1,sizeof(long));
memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_NB_t));
bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_NB_PR_c1;
bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13;
memset(&schedulingInfo_NB_IoT,0,sizeof(LTE_SchedulingInfo_NB_r13_t));
memset(&sib_type_NB_IoT,0,sizeof(LTE_SIB_Type_NB_r13_t));
//allocation
*sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13;
/*TS 36.331 v14.2.0 pag 589
* hyperSFN-MSB
* Indicates the 8 most significant bits of the hyper-SFN. Together with the hyper-LSB in MIB-NB the complete HSFN is build up
*/
//FIXME see if correct
uint8_t hyperSFN_MSB = (uint8_t) ((frame>>2)& 0xff);
//XXX to be checked
(*sib1_NB_IoT)->hyperSFN_MSB_r13.buf = &hyperSFN_MSB;
(*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1;
(*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0;
memset(&PLMN_identity_info_NB_IoT,0,sizeof(LTE_PLMN_IdentityInfo_NB_r13_t));
PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc));
memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc));
asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0;
//left as it is???
#if defined(ENABLE_ITTI)
dummy_mcc[0] = (mcc / 100) % 10;
dummy_mcc[1] = (mcc / 10) % 10;
dummy_mcc[2] = (mcc / 1) % 10;
#else
dummy_mcc[0] = 0;
dummy_mcc[1] = 0;
dummy_mcc[2] = 1;
#endif
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]);
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]);
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]);
PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0;
PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0;
#if defined(ENABLE_ITTI)
if (mnc >= 100) {
dummy_mnc[0] = (mnc / 100) % 10;
dummy_mnc[1] = (mnc / 10) % 10;
dummy_mnc[2] = (mnc / 1) % 10;
} else {
if (mnc_digit_length == 2) {
dummy_mnc[0] = (mnc / 10) % 10;
dummy_mnc[1] = (mnc / 1) % 10;
dummy_mnc[2] = 0xf;
} else {
dummy_mnc[0] = (mnc / 100) % 100;
dummy_mnc[1] = (mnc / 10) % 10;
dummy_mnc[2] = (mnc / 1) % 10;
}
}
#else
dummy_mnc[0] = 0;
dummy_mnc[1] = 1;
dummy_mnc[2] = 0xf;
#endif
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]);
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]);
if (dummy_mnc[2] != 0xf) {
ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[2]);
}
//still set to "notReserved" as in the previous case
PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=LTE_PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved;
*attachWithoutPDN_Connectivity = 0;
PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity;
ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.plmn_IdentityList_r13.list,&PLMN_identity_info_NB_IoT);
// 16 bits = 2 byte
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte
//lefts as it is?
#if defined(ENABLE_ITTI)
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (tac >> 8) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (tac >> 0) & 0xff;
#else
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01;
#endif
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0;
// 28 bits --> i have to use 32 bits = 4 byte
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte?
#if defined(ENABLE_ITTI)
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (cell_identity >> 20) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (cell_identity >> 12) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (cell_identity >> 4) & 0xff;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (cell_identity << 4) & 0xf0;
#else
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10;
#endif
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4;
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4;
//Still set to "notBarred" as in the previous case
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=LTE_SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred;
//Still Set to "notAllowed" like in the previous case
(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=LTE_SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed;
(*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589
(*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 =-22; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value)
(*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(LTE_P_Max_t));
*((*sib1_NB_IoT)->p_Max_r13) = 23;
//FIXME
(*sib1_NB_IoT)->freqBandIndicator_r13 =
#if defined(ENABLE_ITTI)
band;
#else
5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode)
#endif
// Now, follow the scheduler SIB configuration
// There is only one sib2+sib3 common setting
schedulingInfo_NB_IoT.si_Periodicity_r13= LTE_SchedulingInfo_NB_r13__si_Periodicity_r13_rf64; //SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; // (to be set to 64)
schedulingInfo_NB_IoT.si_RepetitionPattern_r13= LTE_SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every4thRF; //This Indicates the starting radio frames within the SI window used for SI message transmission.
schedulingInfo_NB_IoT.si_TB_r13= LTE_SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits
// This is for SIB2/3
/*SIB3 --> There is no mapping information of SIB2 since it is always present
* in the first SystemInformation message
* listed in the schedulingInfoList list.
* */
sib_type_NB_IoT=LTE_SIB_Type_NB_r13_sibType3_NB_r13;
ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT.sib_MappingInfo_r13.list,&sib_type_NB_IoT);
ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT);
//printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13);
/*
#if defined(ENABLE_ITTI)
if (configuration->frame_type[CC_id] == TDD)
#endif
{
//FIXME in NB-IoT mandatory to be FDD --> so must give an error
LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct?
exit(-1);
}
*/
//FIXME which value chose for the following parameter
*offset =1;
//FIXME which value chose for the following parameter
(*sib1_NB_IoT)->si_WindowLength_r13=LTE_SystemInformationBlockType1_NB__si_WindowLength_r13_ms160;
(*sib1_NB_IoT)->si_RadioFrameOffset_r13=offset;
/////optional parameters, decide to use at future
/*
//system value tag
(*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13));
asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list);
ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI);
// downlink bitmap
(*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13));
((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING;
// CRS power offset
*nrs_CRS_PowerOffset= 0;
(*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset;
*/
*eutraControlRegionSize = 2;
(*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize;
#ifdef XER_PRINT //generate xml files
xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message);
#endif
//bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13 = **sib1_NB_IoT;
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_NB,
NULL,
(void*)bcch_message,
carrier->SIB1_NB_IoT,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
if (enc_rval.encoded==-1) {
return(-1);
}
return((enc_rval.encoded+7)/8);
}
/*SIB23_NB_IoT*/
//to be clarified is it is possible to carry SIB2 and SIB3 in the same SI message for NB-IoT?
uint8_t do_SIB23_NB_IoT(uint8_t Mod_id,
int CC_id,
rrc_eNB_carrier_data_NB_IoT_t *carrier,//MP: this is already a carrier[CC_id]
NbIoTRrcConfigurationReq *configuration ) //openair2/COMMON/rrc_messages_types.h
{
struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part;
struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part;
LTE_BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB
LTE_SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT;
LTE_SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT;
asn_enc_rval_t enc_rval;
LTE_RACH_Info_NB_r13_t rach_Info_NB_IoT;
LTE_NPRACH_Parameters_NB_r13_t *nprach_parameters;
//optional
long *connEstFailOffset = NULL;
connEstFailOffset = CALLOC(1, sizeof(long));
// RSRP_ThresholdsNPRACH_InfoList_NB_r13_t *rsrp_ThresholdsPrachInfoList;
// RSRP_Range_t rsrp_range;
LTE_ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition;
struct LTE_NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config;
struct LTE_DL_GapConfig_NB_r13 *dl_Gap;
long *srs_SubframeConfig;
srs_SubframeConfig= CALLOC(1, sizeof(long));
if (bcch_message) {
memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_NB_t));
} else {
LOG_E(RRC,"[NB-IoT %d] BCCH_MESSAGE_NB is null, exiting\n", Mod_id);
exit(-1);
}
//before schould be allocated memory somewhere?
// if (!carrier->sib2_NB_IoT) {
// LOG_E(RRC,"[NB-IoT %d] sib2_NB_IoT is null, exiting\n", Mod_id);
// exit(-1);
// }
//
// if (!carrier->sib3_NB_IoT) {
// LOG_E(RRC,"[NB-IoT %d] sib3_NB_IoT is null, exiting\n", Mod_id);
// exit(-1);
// }
LOG_I(RRC,"[NB-IoT %d] Configuration SIB2/3\n", Mod_id);
sib2_NB_part = CALLOC(1,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
sib3_NB_part = CALLOC(1,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
memset(sib2_NB_part,0,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
memset(sib3_NB_part,0,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
sib2_NB_part->present = LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13;
sib3_NB_part->present = LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13;
//may bug if not correct allocation of memory
carrier->sib2_NB_IoT = &sib2_NB_part->choice.sib2_r13;
carrier->sib3_NB_IoT = &sib3_NB_part->choice.sib3_r13;
sib2_NB_IoT = carrier->sib2_NB_IoT;
sib3_NB_IoT = carrier->sib3_NB_IoT;
nprach_parameters = (LTE_NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(LTE_NPRACH_Parameters_NB_r13_t));
memset(&nprach_parameters[0],0,sizeof(LTE_NPRACH_Parameters_NB_r13_t));
memset(&nprach_parameters[1],0,sizeof(LTE_NPRACH_Parameters_NB_r13_t));
memset(&nprach_parameters[2],0,sizeof(LTE_NPRACH_Parameters_NB_r13_t));
/// SIB2-NB-----------------------------------------
//Barring is manage by ab-Enabled in MIB-NB (but is not a struct as ac-BarringInfo in LTE legacy)
//RACH Config. Common--------------------------------------------------------------
sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.preambleTransMax_CE_r13 =
configuration->rach_preambleTransMax_CE_NB[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.powerRampingStep =
configuration->rach_powerRampingStep_NB[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.preambleInitialReceivedTargetPower =
configuration->rach_preambleInitialReceivedTargetPower_NB[CC_id];
rach_Info_NB_IoT.ra_ResponseWindowSize_r13 = configuration->rach_raResponseWindowSize_NB[CC_id];
rach_Info_NB_IoT.mac_ContentionResolutionTimer_r13 = configuration-> rach_macContentionResolutionTimer_NB[CC_id];
//rach_infoList max size = maxNPRACH-Resources-NB-r13 = 3
ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.rach_InfoList_r13.list,&rach_Info_NB_IoT);
//TS 36.331 pag 614 --> if not present the value to infinity sould be used
*connEstFailOffset = 0;
sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.connEstFailOffset_r13 = connEstFailOffset; /*OPTIONAL*/
// BCCH-Config-NB-IoT----------------------------------------------------------------
sib2_NB_IoT->radioResourceConfigCommon_r13.bcch_Config_r13.modificationPeriodCoeff_r13
= configuration->bcch_modificationPeriodCoeff_NB[CC_id];
// PCCH-Config-NB-IoT-----------------------------------------------------------------
sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.defaultPagingCycle_r13
= configuration->pcch_defaultPagingCycle_NB[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.nB_r13 = configuration->pcch_nB_NB[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.npdcch_NumRepetitionPaging_r13 = configuration-> pcch_npdcch_NumRepetitionPaging_NB[CC_id];
//NPRACH-Config-NB-IoT-----------------------------------------------------------------
sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13 = NULL;
sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_CP_Length_r13 = configuration->nprach_CP_Length[CC_id];
/*OPTIONAL*/
// =CALLOC(1, sizeof(struct RSRP_ThresholdsNPRACH_InfoList_NB_r13)); //fatto uguale dopo
// rsrp_ThresholdsPrachInfoList = sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13;
// rsrp_range = configuration->nprach_rsrp_range_NB;
// ASN_SEQUENCE_ADD(&rsrp_ThresholdsPrachInfoList->list,rsrp_range);
// According configuration to set the 3 CE level configuration setting, for the initial testing, only consider the CE 0, since there is only one set of parameters.
nprach_parameters[0].nprach_Periodicity_r13 = configuration->nprach_Periodicity[CC_id];
nprach_parameters[0].nprach_StartTime_r13 = configuration->nprach_StartTime[CC_id];
nprach_parameters[0].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[CC_id];
nprach_parameters[0].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[CC_id];
nprach_parameters[0].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[CC_id];
nprach_parameters[0].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart[CC_id];
nprach_parameters[0].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB[CC_id];
nprach_parameters[0].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[CC_id];
nprach_parameters[0].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[CC_id];
nprach_parameters[0].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[CC_id];
nprach_parameters[1].nprach_Periodicity_r13 = configuration->nprach_Periodicity[CC_id];
nprach_parameters[1].nprach_StartTime_r13 = configuration->nprach_StartTime[CC_id];
nprach_parameters[1].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[CC_id];
nprach_parameters[1].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[CC_id];
nprach_parameters[1].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[CC_id];
nprach_parameters[1].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart[CC_id];
nprach_parameters[1].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB[CC_id];
nprach_parameters[1].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[CC_id];
nprach_parameters[1].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[CC_id];
nprach_parameters[1].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[CC_id];
nprach_parameters[2].nprach_Periodicity_r13 = configuration->nprach_Periodicity[CC_id];
nprach_parameters[2].nprach_StartTime_r13 = configuration->nprach_StartTime[CC_id];
nprach_parameters[2].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[CC_id];
nprach_parameters[2].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[CC_id];
nprach_parameters[2].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[CC_id];
nprach_parameters[2].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart[CC_id];
nprach_parameters[2].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB[CC_id];
nprach_parameters[2].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[CC_id];
nprach_parameters[2].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[CC_id];
nprach_parameters[2].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[CC_id];
//nprach_parameterList have a max size of 3 possible nprach configuration (see maxNPRACH_Resources_NB_r13)
ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[0]);
ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[1]);
ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[2]);
// NPDSCH-Config NB-IOT
sib2_NB_IoT->radioResourceConfigCommon_r13.npdsch_ConfigCommon_r13.nrs_Power_r13= configuration->npdsch_nrs_Power[CC_id];
//NPUSCH-Config NB-IoT----------------------------------------------------------------
//list of size 3 (see maxNPRACH_Resources_NB_r13)
ack_nack_repetition = configuration-> npusch_ack_nack_numRepetitions_NB[CC_id]; //is an enumerative
ASN_SEQUENCE_ADD(&(sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ack_NACK_NumRepetitions_Msg4_r13.list) ,&ack_nack_repetition);
*srs_SubframeConfig = configuration->npusch_srs_SubframeConfig_NB[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.srs_SubframeConfig_r13= srs_SubframeConfig; /*OPTIONAL*/
/*OPTIONAL*/
dmrs_config = CALLOC(1,sizeof(struct LTE_NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13));
dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13[CC_id];
dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13[CC_id];
/*OPTIONAL
* -define the base sequence for a DMRS sequence in a cell with multi tone transmission (3,6,12) see TS 36.331 NPUSCH-Config-NB
* -if not defined will be calculated based on the cellID once we configure the phy layer (rrc_mac_config_req) through the config_sib2 */
dmrs_config->threeTone_BaseSequence_r13 = NULL;
dmrs_config->sixTone_BaseSequence_r13 = NULL;
dmrs_config->twelveTone_BaseSequence_r13 = NULL;
sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.dmrs_Config_r13 = dmrs_config;
//ulReferenceSignalsNPUSCH
/*Reference Signal (RS) for UL in NB-IoT is called DRS (Demodulation Reference Signal)
* sequence-group hopping can be enabled or disabled by means of the cell-specific parameter groupHoppingEnabled_r13
* sequence-group hopping can be disabled for certain specific UE through the parameter groupHoppingDisabled (physicalConfigDedicated)
* groupAssignmentNPUSCH--> is used for generate the sequence-shift pattern
*/
sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupHoppingEnabled_r13= configuration->npusch_groupHoppingEnabled[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13 =configuration->npusch_groupAssignmentNPUSCH_r13[CC_id];
//dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/
dl_Gap = CALLOC(1,sizeof(struct LTE_DL_GapConfig_NB_r13));
dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB[CC_id];
dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB[CC_id];
dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.dl_Gap_r13 = dl_Gap;
// uplinkPowerControlCommon - NB-IoT------------------------------------------------------
sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.p0_NominalNPUSCH_r13 = configuration->npusch_p0_NominalNPUSCH[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.deltaPreambleMsg3_r13 = configuration->deltaPreambleMsg3[CC_id];
sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.alpha_r13 = configuration->npusch_alpha[CC_id];
//no deltaFlist_PUCCH and no UL cyclic prefix
// UE Timers and Constants -NB-IoT--------------------------------------------------------
sib2_NB_IoT->ue_TimersAndConstants_r13.t300_r13 = configuration-> ue_TimersAndConstants_t300_NB;
sib2_NB_IoT->ue_TimersAndConstants_r13.t301_r13 = configuration-> ue_TimersAndConstants_t301_NB;
sib2_NB_IoT->ue_TimersAndConstants_r13.t310_r13 = configuration-> ue_TimersAndConstants_t310_NB;
sib2_NB_IoT->ue_TimersAndConstants_r13.t311_r13 = configuration-> ue_TimersAndConstants_t311_NB;
sib2_NB_IoT->ue_TimersAndConstants_r13.n310_r13 = configuration-> ue_TimersAndConstants_n310_NB;
sib2_NB_IoT->ue_TimersAndConstants_r13.n311_r13 = configuration-> ue_TimersAndConstants_n311_NB;
//other SIB2-NB Parameters--------------------------------------------------------------------------------
sib2_NB_IoT->freqInfo_r13.additionalSpectrumEmission_r13 = 1;
sib2_NB_IoT->freqInfo_r13.ul_CarrierFreq_r13 = NULL; /*OPTIONAL*/
sib2_NB_IoT->timeAlignmentTimerCommon_r13=LTE_TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120;
/*OPTIONAL*/
sib2_NB_IoT->multiBandInfoList_r13 = NULL;
/// SIB3-NB-------------------------------------------------------
sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=LTE_SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4;
sib3_NB_IoT->cellReselectionServingFreqInfo_r13.s_NonIntraSearch_r13=0; //or define in configuration?
sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_RxLevMin_r13 = -70;
//new
sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13 = CALLOC(1,sizeof(*sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13));
*(sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)= -22; //a caso
sib3_NB_IoT->intraFreqCellReselectionInfo_r13.p_Max_r13 = NULL;
sib3_NB_IoT->intraFreqCellReselectionInfo_r13.s_IntraSearchP_r13 = 31; // s_intraSearch --> s_intraSearchP!!! (they call in a different way)
sib3_NB_IoT->intraFreqCellReselectionInfo_r13.t_Reselection_r13=1;
//how to manage?
sib3_NB_IoT->freqBandInfo_r13 = NULL;
sib3_NB_IoT->multiBandInfoList_r13 = NULL;
///BCCH message (generate the SI message)
bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_NB_PR_c1;
bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13;
bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = LTE_SystemInformation_NB__criticalExtensions_PR_systemInformation_r13;
bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list.count=0;
ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list,
sib2_NB_part);
ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list,
sib3_NB_part);
#ifdef XER_PRINT
xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message);
#endif
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_NB,
NULL,
(void*)bcch_message,
carrier->SIB23_NB_IoT,
900);
printf("In Asn.1 SIB23\n");
for(int i=0;i<32;i++)
printf("%x ", carrier->SIB23_NB_IoT[i]);
printf("\n");
printf("(enc_rval.encoded+7)/8 = %ld\n",(enc_rval.encoded+7)/8);
// AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
// enc_rval.failed_type->name, enc_rval.encoded);
//#if defined(ENABLE_ITTI).....
#ifdef USER_MODE
LOG_D(RRC,"[NB-IoT] SystemInformation-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
#endif
if (enc_rval.encoded==-1) {
msg("[RRC] ASN1 : SI-NB encoding failed for SIB23_NB_IoT\n");
return(-1);
}
carrier->sib2_NB_IoT = sib2_NB_IoT;
carrier->sib3_NB_IoT = sib3_NB_IoT;
return((enc_rval.encoded+7)/8);
}
/*do_RRCConnectionSetup_NB_IoT--> the aim is to establish SRB1 and SRB1bis(implicitly), based on configuration setting up Msg 4*/
uint8_t do_RRCConnectionSetup_NB_IoT(
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP,
int CC_id,
uint8_t* const buffer, //Srb0.Tx_buffer.Payload
const uint8_t Transaction_id,
LTE_SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1
struct LTE_PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT)
{
asn_enc_rval_t enc_rval;
//uint8_t ecause=0;
//long* prioritySRB1 = NULL;
//long* prioritySRB1bis = NULL;
//BOOLEAN_t* logicalChannelSR_Prohibit = NULL; //pag 605
BOOLEAN_t* npusch_AllSymbols = NULL;
long* npusch_repetitions = NULL;
long* group_hopping_disabled = NULL;
// At the first moment of MSG4 testing we set NULL to those optional
#if 0
struct LTE_SRB_ToAddMod_NB_r13* SRB1_config_NB_IoT = NULL;
struct LTE_SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB_IoT = NULL;
struct LTE_SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB_IoT = NULL;
#endif
struct LTE_SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL;
struct LTE_SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL;
struct LTE_SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL;
LTE_PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL;
LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT;
LTE_RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL;
memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(LTE_DL_CCCH_Message_NB_t));
dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1;
dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13;
rrcConnectionSetup_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionSetup_r13;
if (*SRB_configList_NB_IoT)
{
free(*SRB_configList_NB_IoT);
}
*SRB_configList_NB_IoT = CALLOC(1,sizeof(LTE_SRB_ToAddModList_NB_r13_t));
#if 0
// SRB1--------------------
SRB1_config_NB_IoT = CALLOC(1,sizeof(*SRB1_config_NB_IoT));
SRB1_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1_rlc_config_NB_IoT));
SRB1_config_NB_IoT->rlc_Config_r13 = SRB1_rlc_config_NB_IoT;
SRB1_rlc_config_NB_IoT->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue;
SRB1_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//the only possible in NB_IoT
// apply the SRB1 configuration from configuration files
SRB1_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_timer_poll_retransmit_r13;
SRB1_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_max_retx_threshold_r13;
// musT be disabled--> SRB1 config pag 640 specs
SRB1_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL;
SRB1_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000;
SRB1_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8;
// musT be disabled--> SRB1 config pag 640 specs
SRB1_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 = NULL;
SRB1_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1_lchan_config_NB_IoT));
SRB1_config_NB_IoT->logicalChannelConfig_r13 = SRB1_lchan_config_NB_IoT;
SRB1_lchan_config_NB_IoT->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue;
// logical channel priority pag 605 (is 1 for SRB1 and for SRB1bis should be the same)
prioritySRB1 = CALLOC(1, sizeof(long));
*prioritySRB1 = 1;
SRB1_lchan_config_NB_IoT->choice.explicitValue.priority_r13 = prioritySRB1;
logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t));
*logicalChannelSR_Prohibit = 1;
// should be set to TRUE (specs pag 641)
SRB1_lchan_config_NB_IoT->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit;
// ADD SRB1
ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1_config_NB);
#endif
#if 1
// SRB1bis (The configuration for SRB1 and SRB1bis is the same) the only difference is the logical channel identity = 3 but not set here
SRB1bis_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_config_NB_IoT));
SRB1bis_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_rlc_config_NB_IoT));
SRB1bis_config_NB_IoT->rlc_Config_r13 = SRB1bis_rlc_config_NB_IoT;
SRB1bis_rlc_config_NB_IoT->present = LTE_SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue;
SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=LTE_RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT
// Set from ourself not configuration files
SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = LTE_T_PollRetransmit_NB_r13_ms250;
SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = LTE_UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8;
//musT be disabled--> SRB1 config pag 640 specs
SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL;
SRB1bis_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_lchan_config_NB_IoT));
SRB1bis_config_NB_IoT->logicalChannelConfig_r13 = SRB1bis_lchan_config_NB_IoT;
SRB1bis_lchan_config_NB_IoT->present = LTE_SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_defaultValue;
//prioritySRB1bis = CALLOC(1, sizeof(long));
//*prioritySRB1bis = 1; //same as SRB1?
//SRB1bis_lchan_config_NB_IoT->choice.explicitValue.priority_r13 = prioritySRB1bis;
//logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t));
//*logicalChannelSR_Prohibit = 1; //should be set to TRUE (specs pag 641)
//SRB1bis_lchan_config_NB_IoT->choice.defaultValue = 0;
//ADD SRB1bis
//MP: SRB_ToAddModList_NB_r13_t size = 1
ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1bis_config_NB_IoT);
#endif
// start PHY dedicate config
physicalConfigDedicated2_NB_IoT = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT));
*physicalConfigDedicated_NB_IoT = physicalConfigDedicated2_NB_IoT;
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13=NULL;
//physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13= CALLOC(1, sizeof(*physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13));
physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13));
physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13));
//physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13 = NULL;
physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13));
#if 0
// Carrier config dedicated set to NULL at this moment
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_CarrierFreq_r13.carrierFreq_r13=0;//random value set
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13));
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13->present=DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13;
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13));
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13->present = DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13;
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.inbandCarrierInfo_r13= NULL;
physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->ul_CarrierConfig_r13.ul_CarrierFreq_r13= NULL;
#endif
// NPDCCH
physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_NumRepetitions_r13 =LTE_NPDCCH_ConfigDedicated_NB_r13__npdcch_NumRepetitions_r13_r16;
physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_Offset_USS_r13 =LTE_NPDCCH_ConfigDedicated_NB_r13__npdcch_Offset_USS_r13_zero;
physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_StartSF_USS_r13=LTE_NPDCCH_ConfigDedicated_NB_r13__npdcch_StartSF_USS_r13_v4;
// NPUSCH
npusch_repetitions = CALLOC(1, sizeof(long));
*npusch_repetitions = LTE_ACK_NACK_NumRepetitions_NB_r13_r8;
physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->ack_NACK_NumRepetitions_r13= npusch_repetitions;
npusch_AllSymbols= CALLOC(1, sizeof(BOOLEAN_t));
*npusch_AllSymbols= 1; //TRUE
physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->npusch_AllSymbols_r13= npusch_AllSymbols;
group_hopping_disabled = CALLOC(1,sizeof(long));
*group_hopping_disabled= LTE_NPUSCH_ConfigDedicated_NB_r13__groupHoppingDisabled_r13_true;
physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->groupHoppingDisabled_r13=group_hopping_disabled;
// UplinkPowerControlDedicated
physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13->p0_UE_NPUSCH_r13 = 0;
//Fill the rrcConnectionSetup-NB message
rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value
rrcConnectionSetup_NB_IoT->criticalExtensions.present = LTE_RRCConnectionSetup_NB__criticalExtensions_PR_c1;
rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =LTE_RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ;
// carry only the phyiscal dedicate configuration
rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = *SRB_configList_NB_IoT;
rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL;
rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL;
rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13 = NULL;
rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = physicalConfigDedicated2_NB_IoT;
rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = NULL;
#ifdef XER_PRINT
xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg);
#endif
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB,
NULL,
(void*)&dl_ccch_msg_NB_IoT,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
#ifdef USER_MODE
// LOG_D(RRC,"RRCConnectionSetup-NB Encoded %d bits (%d bytes), ecause %d\n",
// enc_rval.encoded,(enc_rval.encoded+7)/8,ecause);
LOG_D(RRC,"RRCConnectionSetup-NB Encoded %d bits (%d bytes)\n",
enc_rval.encoded,(enc_rval.encoded+7)/8);
#endif
return((enc_rval.encoded+7)/8);
}
/*do_SecurityModeCommand - exactly the same as previous implementation*/
uint8_t do_SecurityModeCommand_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
uint8_t* const buffer,
const uint8_t Transaction_id,
const uint8_t cipheringAlgorithm,
const uint8_t integrityProtAlgorithm)
{
LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
asn_enc_rval_t enc_rval;
memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t));
dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.rrc_TransactionIdentifier = Transaction_id;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = LTE_SecurityModeCommand__criticalExtensions_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present =
LTE_SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8;
// the two following information could be based on the mod_id
dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm
= (LTE_CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved
dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm
= (e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm;
//only changed "asn_DEF_DL_DCCH_Message_NB"
#ifdef XER_PRINT
xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT);
#endif
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB,
NULL,
(void*)&dl_dcch_msg_NB_IoT,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
//#if defined(ENABLE_ITTI)
//# if !defined(DISABLE_XER_SPRINT)....
#ifdef USER_MODE
LOG_D(RRC,"[eNB %d] securityModeCommand-NB for UE %x Encoded %d bits (%d bytes)\n",
ctxt_pP->module_id,
ctxt_pP->rnti,
enc_rval.encoded,
(enc_rval.encoded+7)/8);
#endif
if (enc_rval.encoded==-1) {
LOG_E(RRC,"[eNB %d] ASN1 : securityModeCommand-NB encoding failed for UE %x\n",
ctxt_pP->module_id,
ctxt_pP->rnti);
return(-1);
}
return((enc_rval.encoded+7)/8);
}
/*do_UECapabilityEnquiry_NB_IoT - very similar to legacy lte*/
uint8_t do_UECapabilityEnquiry_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
uint8_t* const buffer,
const uint8_t Transaction_id
)
{
LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
//no RAT type in NB-IoT
asn_enc_rval_t enc_rval;
memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t));
dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.rrc_TransactionIdentifier = Transaction_id;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = LTE_UECapabilityEnquiry_NB__criticalExtensions_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present =
LTE_UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13;
//no ue_CapabilityRequest (list of RAT_Type)
//only changed "asn_DEF_DL_DCCH_Message_NB"
#ifdef XER_PRINT
xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT);
#endif
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB,
NULL,
(void*)&dl_dcch_msg_NB_IoT,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
//#if defined(ENABLE_ITTI)
//# if !defined(DISABLE_XER_SPRINT)....
#ifdef USER_MODE
LOG_D(RRC,"[eNB %d] UECapabilityEnquiry-NB for UE %x Encoded %d bits (%d bytes)\n",
ctxt_pP->module_id,
ctxt_pP->rnti,
enc_rval.encoded,
(enc_rval.encoded+7)/8);
#endif
if (enc_rval.encoded==-1) {
LOG_E(RRC,"[eNB %d] ASN1 : UECapabilityEnquiry-NB encoding failed for UE %x\n",
ctxt_pP->module_id,
ctxt_pP->rnti);
return(-1);
}
return((enc_rval.encoded+7)/8);
}
/*do_RRCConnectionReconfiguration_NB_IoT-->may convey information for resource configuration
* (including RBs, MAC main configuration and physical channel configuration)
* including any associated dedicated NAS information.*/
uint16_t do_RRCConnectionReconfiguration_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
uint8_t *buffer,
uint8_t Transaction_id,
LTE_SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1
LTE_DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default)
LTE_DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed
struct LTE_PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT,
LTE_MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT,
struct LTE_RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT)
{
//check on DRB_list if contains more than 2 DRB?
asn_enc_rval_t enc_rval;
LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
LTE_RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB;
memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t));
dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13;
rrcConnectionReconfiguration_NB = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReconfiguration_r13;
// RRCConnectionReconfiguration
rrcConnectionReconfiguration_NB->rrc_TransactionIdentifier = Transaction_id;
rrcConnectionReconfiguration_NB->criticalExtensions.present = LTE_RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1;
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =LTE_RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ;
//RAdioResourceconfigDedicated
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13 =
CALLOC(1,sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13));
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->srb_ToAddModList_r13 = SRB1_list_NB; //only SRB1
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToAddModList_r13 = DRB_list_NB_IoT;
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToReleaseList_r13 = DRB_list2_NB_IoT; //NULL
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->physicalConfigDedicated_r13 = physicalConfigDedicated_NB_IoT;
//FIXME may not used now
//rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->rlf_TimersAndConstants_r13
if (mac_MainConfig_NB_IoT!=NULL) {
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13 =
CALLOC(1, sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13));
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->present
=LTE_RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13;
//why memcopy only this one?
memcpy(&rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->choice.explicitValue_r13,
mac_MainConfig_NB_IoT, sizeof(*mac_MainConfig_NB_IoT));
} else {
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13=NULL;
}
//no measConfig, measIDlist
//no mobilityControlInfo
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.dedicatedInfoNASList_r13 = dedicatedInfoNASList_NB_IoT;
//mainly used for cell-reselection/handover purposes??
rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.fullConfig_r13 = NULL;
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB,
NULL,
(void*)&dl_dcch_msg_NB_IoT,
buffer,
RRC_BUF_SIZE);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
//changed only asn_DEF_DL_DCCH_Message_NB
#ifdef XER_PRINT
xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT);
#endif
//#if defined(ENABLE_ITTI)
//# if !defined(DISABLE_XER_SPRINT)...
LOG_I(RRC,"RRCConnectionReconfiguration-NB Encoded %ld bits (%ld bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
/*do_RRCConnectionReestablishmentReject - exactly the same as legacy LTE*/
uint8_t do_RRCConnectionReestablishmentReject_NB_IoT(
uint8_t Mod_id,
uint8_t* const buffer)
{
asn_enc_rval_t enc_rval;
LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT;
LTE_RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject;
memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(LTE_DL_CCCH_Message_NB_t));
dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1;
dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13;
rrcConnectionReestablishmentReject = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishmentReject_r13;
// RRCConnectionReestablishmentReject //exactly the same as LTE
rrcConnectionReestablishmentReject->criticalExtensions.present = LTE_RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8;
//Only change in "asn_DEF_DL_CCCH_Message_NB"
#ifdef XER_PRINT
xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT);
#endif
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB,
NULL,
(void*)&dl_ccch_msg_NB_IoT,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
//Only change in "asn_DEF_DL_CCCH_Message_NB"
#if defined(ENABLE_ITTI)
# if !defined(DISABLE_XER_SPRINT)
{
char message_string[20000];
size_t message_string_size;
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) {
MessageDef *msg_p;
msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText));
msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size;
memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p);
}
}
# endif
#endif
#ifdef USER_MODE
LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %d bits (%d bytes)\n",
enc_rval.encoded,(enc_rval.encoded+7)/8);
#endif
return((enc_rval.encoded+7)/8);
}
/*do_RRCConnectionReject_NB_IoT*/
uint8_t do_RRCConnectionReject_NB_IoT(
uint8_t Mod_id,
uint8_t* const buffer)
{
asn_enc_rval_t enc_rval;
LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT;
LTE_RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT;
memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(LTE_DL_CCCH_Message_NB_t));
dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1;
dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13;
rrcConnectionReject_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReject_r13;
// RRCConnectionReject-NB_IoT
rrcConnectionReject_NB_IoT->criticalExtensions.present = LTE_RRCConnectionReject_NB__criticalExtensions_PR_c1;
rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = LTE_RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13;
/* let's put an extended wait time of 1s for the moment */
rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.extendedWaitTime_r13 = 1;
//new-use of suspend indication
//If present, this field indicates that the UE should remain suspended and not release its stored context.
rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13=
CALLOC(1, sizeof(long));
*(rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13)=
LTE_RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true;
//Only Modified "asn_DEF_DL_CCCH_Message_NB"
#ifdef XER_PRINT
xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg);
#endif
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB,
NULL,
(void*)&dl_ccch_msg_NB_IoT,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %ld)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
#if defined(ENABLE_ITTI)
# if !defined(DISABLE_XER_SPRINT)
{
char message_string[20000];
size_t message_string_size;
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) {
MessageDef *msg_p;
msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText));
msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size;
memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p);
}
}
# endif
#endif
#ifdef USER_MODE
LOG_D(RRC,"RRCConnectionReject-NB Encoded %d bits (%d bytes)\n",
enc_rval.encoded,(enc_rval.encoded+7)/8);
#endif
return((enc_rval.encoded+7)/8);
}
//no do_MBSFNAreaConfig(..) in NB-IoT
//no do_MeasurementReport(..) in NB-IoT
/*do_DLInformationTransfer_NB*/
uint8_t do_DLInformationTransfer_NB_IoT(
uint8_t Mod_id,
uint8_t **buffer,
uint8_t transaction_id,
uint32_t pdu_length,
uint8_t *pdu_buffer)
{
ssize_t encoded;
LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
memset(&dl_dcch_msg_NB_IoT, 0, sizeof(LTE_DL_DCCH_Message_NB_t));
dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.rrc_TransactionIdentifier = transaction_id;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = LTE_DLInformationTransfer_NB__criticalExtensions_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = LTE_DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.size = pdu_length;
dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.buf = pdu_buffer;
encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer);
//only change in "asn_DEF_DL_DCCH_Message_NB"
#if defined(ENABLE_ITTI)
# if !defined(DISABLE_XER_SPRINT)
{
char message_string[10000];
size_t message_string_size;
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) {
MessageDef *msg_p;
msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText));
msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size;
memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p);
}
}
# endif
#endif
return encoded;
}
/*do_ULInformationTransfer*/
//for the moment is not needed (UE-SIDE)
/*OAI_UECapability_t *fill_ue_capability*/
/*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use?
uint8_t do_RRCConnectionReestablishment_NB_IoT(
uint8_t Mod_id,
uint8_t* const buffer,
const uint8_t Transaction_id,
const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed
LTE_SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured?
{
asn_enc_rval_t enc_rval;
LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT;
LTE_RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT;
memset(&dl_ccch_msg_NB_IoT, 0, sizeof(LTE_DL_CCCH_Message_NB_t));
dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1;
dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13;
rrcConnectionReestablishment_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishment_r13;
//rrcConnectionReestablishment_NB
rrcConnectionReestablishment_NB_IoT->rrc_TransactionIdentifier = Transaction_id;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = LTE_RRCConnectionReestablishment_NB__criticalExtensions_PR_c1;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = LTE_RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = SRB_list_NB_IoT;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13= NULL;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13= NULL;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = NULL;
rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.nextHopChainingCount_r13=0;
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB,
NULL,
(void*)&dl_ccch_msg_NB_IoT,
buffer,
RRC_BUF_SIZE);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
#ifdef XER_PRINT
xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT);
#endif
#if defined(ENABLE_ITTI)
#if !defined(DISABLE_XER_SPRINT)
{
char message_string[30000];
size_t message_string_size;
if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) {
MessageDef *msg_p;
msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText));
msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size;
memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size);
itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p);
}
}
#endif
#endif
LOG_I(RRC,"RRCConnectionReestablishment-NB Encoded %ld bits (%ld bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
}
/*do_RRCConnectionRelease_NB--> is used to command the release of an RRC connection*/
uint8_t do_RRCConnectionRelease_NB_IoT(
uint8_t Mod_id,
uint8_t *buffer,
const uint8_t Transaction_id)
{
asn_enc_rval_t enc_rval;
LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
LTE_RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT;
memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t));
dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1;
dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13;
rrcConnectionRelease_NB_IoT = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionRelease_r13;
// RRCConnectionRelease
rrcConnectionRelease_NB_IoT->rrc_TransactionIdentifier = Transaction_id;
rrcConnectionRelease_NB_IoT->criticalExtensions.present = LTE_RRCConnectionRelease_NB__criticalExtensions_PR_c1;
rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =LTE_RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ;
rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = LTE_ReleaseCause_NB_r13_other;
rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.redirectedCarrierInfo_r13 = NULL;
rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.extendedWaitTime_r13 = NULL;
//Why allocate memory for non critical extension?
rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension=CALLOC(1,
sizeof(*rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension));
enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB,
NULL,
(void*)&dl_dcch_msg_NB_IoT,
buffer,
RRC_BUF_SIZE);//check
return((enc_rval.encoded+7)/8);
}
// -----??????--------------------
#ifndef USER_MODE
int init_module_NB_IoT(void)
{
printk("Init asn1_msg_nb_iot module\n");
// A non 0 return means init_module failed; module can't be loaded.
return 0;
}
#if 0
void cleanup_module_NB_IoT(void)
{
printk("Stopping asn1_msg_nb_iot module\n");
}
EXPORT_SYMBOL(do_SIB1_NB_IoT);
EXPORT_SYMBOL(do_SIB23_NB_IoT);
EXPORT_SYMBOL(do_RRCConnectionRequest_NB_IoT);
EXPORT_SYMBOL(do_RRCConnectionSetupComplete_NB_IoT);
EXPORT_SYMBOL(do_RRCConnectionReconfigurationComplete_NB_IoT);
EXPORT_SYMBOL(do_RRCConnectionSetup_NB_IoT);
EXPORT_SYMBOL(do_RRCConnectionReestablishmentReject_NB_IoT);
EXPORT_SYMBOL(do_RRCConnectionReconfiguration_NB_IoT);
EXPORT_SYMBOL(asn_DEF_UL_DCCH_Message_NB);
EXPORT_SYMBOL(asn_DEF_UL_CCCH_Message_NB);
EXPORT_SYMBOL(asn_DEF_SystemInformation_NB_IoT);
EXPORT_SYMBOL(asn_DEF_DL_DCCH_Message_NB);
EXPORT_SYMBOL(asn_DEF_SystemInformationBlockType1_NB_IoT);
EXPORT_SYMBOL(asn_DEF_DL_CCCH_Message_NB);
EXPORT_SYMBOL(uper_decode_complete);
EXPORT_SYMBOL(uper_decode);
EXPORT_SYMBOL(transmission_mode_rrc);
#endif
#endif
//----------------------------------
......@@ -35,7 +35,7 @@
#include "rlc.h"
#include "extern_NB_IoT.h"
#include "LAYER2/MAC/defs_NB_IoT.h"
//#include "platform_types_NB_IoT.h"
#include "platform_types_NB_IoT.h"
uint8_t* generate_msg4_NB_IoT(rrc_eNB_carrier_data_NB_IoT_t *carrier);
......@@ -71,7 +71,59 @@ long *get_NB_IoT_SIB1_eutracontrolregionsize(void);
void init_testing_NB_IoT(uint8_t Mod_id, int CC_id, rrc_eNB_carrier_data_NB_IoT_t *carrier, NbIoTRrcConfigurationReq *configuration, uint32_t frame, uint32_t hyper_frame);
//defined in L2_interface/pdcp.c
//FIXME SRB1bis should bypass the pdcp
//Distinction between different SRBs will be done by means of rd_id
uint8_t rrc_data_req_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
const rb_id_t rb_idP,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_sizeP,
uint8_t* const buffer_pP,
const pdcp_transmission_mode_t modeP //when go through SRB1bis should be set as Transparent mode
);
//--------------------------------------------------
//XXX for the moment we not configure PDCP for SRB1bis (but used as it is SRB1)
//defined in pdcp.c
boolean_t rrc_pdcp_config_asn1_req_NB_IoT (
const protocol_ctxt_t* const ctxt_pP,
LTE_SRB_ToAddModList_NB_r13_t *const srb2add_list_pP,
LTE_DRB_ToAddModList_NB_r13_t *const drb2add_list_pP,
LTE_DRB_ToReleaseList_NB_r13_t *const drb2release_list_pP,
const uint8_t security_modeP,
uint8_t *const kRRCenc_pP,
uint8_t *const kRRCint_pP,
uint8_t *const kUPenc_pP,
rb_id_t *const defaultDRB,
long LCID
);
//--------------------------------------------------
//defined in rlc_rrc.c
rlc_op_status_t rrc_rlc_config_asn1_req_NB_IoT (
const protocol_ctxt_t * const ctxt_pP,
const LTE_SRB_ToAddModList_NB_r13_t * const srb2add_listP,
const LTE_DRB_ToAddModList_NB_r13_t * const drb2add_listP,
const LTE_DRB_ToReleaseList_NB_r13_t * const drb2release_listP,
srb1bis_flag_t srb1bis_flag
);
//-------------------------------------------------------------------------
/*-----------eNB procedures (rrc_eNB_NB_IoT.c)---------------*/
//---Initialization--------------
void openair_eNB_rrc_on_NB_IoT(
const protocol_ctxt_t* const ctxt_pP
);
/// Utilities------------------------------------------------
void rrc_eNB_free_mem_UE_context_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP
);
......@@ -32,7 +32,7 @@
/*NB-IoT include files*/
//#include "PHY/extern_NB_IoT.h"
#include "LAYER2/MAC/extern_NB_IoT.h"
//#include "RRC/LITE/proto_NB_IoT.h"
#include "RRC/NBIOT/proto_NB_IoT.h"
#include "defs_NB_IoT.h"
#include "openair1/SCHED_NBIOT/defs_NB_IoT.h"
#include "RRC/NBIOT/MESSAGES/asn1_msg_NB_IoT.h"
......@@ -118,6 +118,8 @@ mui_t rrc_eNB_mui_NB_IoT = 0;
// should be called when UE is lost by eNB
void rrc_eNB_free_UE_NB_IoT(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP)
//-----------------------------------------------------------------------------
......@@ -508,7 +510,7 @@ void rrc_eNB_generate_RRCConnectionSetup_NB_IoT(
//XXX MP:warning due to function still not completed at PHY (get_lte_frame_parms)
//XXX this approach is gone most probably
NB_IoT_DL_FRAME_PARMS *fp = get_NB_IoT_frame_parms(ctxt_pP->module_id,CC_id);
//NB_IoT_DL_FRAME_PARMS *fp = get_NB_IoT_frame_parms(ctxt_pP->module_id,CC_id);
T(T_ENB_RRC_CONNECTION_SETUP, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
......@@ -1965,7 +1967,7 @@ int rrc_eNB_decode_ccch_NB_IoT(
//InitialUE-Identity randomValue size should be 40bits = 5 byte
AssertFatal(rrcConnectionRequest_NB_IoT->ue_Identity_r13.choice.randomValue.size == 5,
"wrong InitialUE-Identity randomValue size, expected 5, provided %d",
"wrong InitialUE-Identity randomValue size, expected 5, provided %zd",
rrcConnectionRequest_NB_IoT->ue_Identity_r13.choice.randomValue.size);
memcpy(((uint8_t*) & random_value) + 3,
......@@ -2874,7 +2876,8 @@ void* rrc_enb_task_NB_IoT(
}
}
#if 0
#ifndef USER_MODE
EXPORT_SYMBOL(Rlc_info_am_config);
#endif
#endif
\ No newline at end of file
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