diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index a0ee33dc78c52b27a3a7922883957fe7fb27c4e4..a22babc33f4c1cd573f854d7abb52dac929257fc 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -314,7 +314,8 @@ file(GLOB rrc_h ${RRC_FULL_DIR}/*.h)
 set(rrc_h ${rrc_h} ${RRC_FULL_DIR}/asn1_constants.h)
 set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code
 add_library(RRC_LIB ${rrc_h} ${rrc_source}
-    ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg.c)
+    ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg.c
+    ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c)
 include_directories ("${RRC_FULL_DIR}")
 
 # add the command to generate the source code
@@ -1717,6 +1718,17 @@ if(NAS_UE)
 endif()
 
 
+# nbiot
+add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16")
+set (NBIOT_SOURCES
+    ${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c
+)
+add_library(NB_IoT MODULE ${NBIOT_SOURCES} )
+
+# shared library loader
+set (SHLIB_LOADER_SOURCES
+    ${OPENAIR_DIR}/common/utils/load_module_shlib.c
+)
 
 # Make lfds as a own source code (even if it is a outside library)
 # For better intergration with compilation flags & structure of cmake
@@ -1789,6 +1801,7 @@ include_directories("${NFAPI_DIR}/nfapi/inc")
 include_directories("${NFAPI_DIR}/sim_common/inc")
 include_directories("${NFAPI_DIR}/pnf_sim/inc")
 
+
 # System packages that are required
 # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/
 # or cmake provide a generic interface to pkg-config that widely used
@@ -1947,6 +1960,7 @@ add_executable(lte-softmodem
   ${OPENAIR_TARGETS}/RT/USER/lte-enb.c
   ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
   ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
+  ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
   ${OPENAIR_TARGETS}/COMMON/create_tasks.c
@@ -1985,6 +1999,7 @@ add_executable(lte-softmodem-nos1
   ${OPENAIR_TARGETS}/RT/USER/lte-enb.c
   ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
   ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
+  ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
   ${OPENAIR_TARGETS}/COMMON/create_tasks.c
diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1
index 5cdab5ffd8cae3b43bb41b6908924de5ec04985b..fe819c27162df2174c27cc2cc93aa250b00c3bd1 100755
--- a/cmake_targets/tools/fix_asn1
+++ b/cmake_targets/tools/fix_asn1
@@ -5,6 +5,7 @@
 
 RRC_Rel14=(
   "SystemInformation-r8-IEs.h" 4df485c5ddf2540eca271876cdc512caa19b0890 "fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff"
+  "SystemInformation-NB-r13-IEs.h" 6d91332d5c39205819b06e5e36efe62ff8e5b33b "fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff"
 )
 
 RRC_Rel10=(
diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff
new file mode 100644
index 0000000000000000000000000000000000000000..37ac4cd85855c7436de8d1ab89a25e7041b3c9c6
--- /dev/null
+++ b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff
@@ -0,0 +1,47 @@
+48a49,70
+> struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member {
+> 	SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present;
+> 	union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u {
+> 		SystemInformationBlockType2_NB_r13_t	 sib2_r13;
+> 		SystemInformationBlockType3_NB_r13_t	 sib3_r13;
+> 		SystemInformationBlockType4_NB_r13_t	 sib4_r13;
+> 		SystemInformationBlockType5_NB_r13_t	 sib5_r13;
+> 		SystemInformationBlockType14_NB_r13_t	 sib14_r13;
+> 		SystemInformationBlockType16_NB_r13_t	 sib16_r13;
+> 		/*
+> 		 * This type is extensible,
+> 		 * possible extensions are below.
+> 		 */
+> 		SystemInformationBlockType15_NB_r14_t	 sib15_v1430;
+> 		SystemInformationBlockType20_NB_r14_t	 sib20_v1430;
+> 		SystemInformationBlockType22_NB_r14_t	 sib22_v1430;
+> 	} choice;
+> 	
+> 	/* Context for parsing across buffer boundaries */
+> 	asn_struct_ctx_t _asn_ctx;
+> };
+> 
+52,72c74
+< 		A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member {
+< 			SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present;
+< 			union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u {
+< 				SystemInformationBlockType2_NB_r13_t	 sib2_r13;
+< 				SystemInformationBlockType3_NB_r13_t	 sib3_r13;
+< 				SystemInformationBlockType4_NB_r13_t	 sib4_r13;
+< 				SystemInformationBlockType5_NB_r13_t	 sib5_r13;
+< 				SystemInformationBlockType14_NB_r13_t	 sib14_r13;
+< 				SystemInformationBlockType16_NB_r13_t	 sib16_r13;
+< 				/*
+< 				 * This type is extensible,
+< 				 * possible extensions are below.
+< 				 */
+< 				SystemInformationBlockType15_NB_r14_t	 sib15_v1430;
+< 				SystemInformationBlockType20_NB_r14_t	 sib20_v1430;
+< 				SystemInformationBlockType22_NB_r14_t	 sib22_v1430;
+< 			} choice;
+< 			
+< 			/* Context for parsing across buffer boundaries */
+< 			asn_struct_ctx_t _asn_ctx;
+< 		} ) list;
+---
+> 		A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member) list;
diff --git a/common/ran_context.h b/common/ran_context.h
index c521c4f37654f4e04944b11364e4a9e8de16926b..18b309d268060e110a71f78801d1fdee7f92e829 100644
--- a/common/ran_context.h
+++ b/common/ran_context.h
@@ -48,6 +48,8 @@
 #include "NwGtpv1uPrivate.h"
 #include "gtpv1u_eNB_defs.h"
 
+#include "PHY/defs_L1_NB_IoT.h"
+#include "RRC/LITE/defs_NB_IoT.h"
 typedef struct {
   /// RAN context config file name
   char *config_file_name;
@@ -76,7 +78,7 @@ typedef struct {
   /// eNB context variables
   struct PHY_VARS_eNB_s ***eNB;
   /// NB_IoT L1 context variables
-  //struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT;
+  struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT;
   /// RRC context variables
   struct eNB_RRC_INST_s **rrc;
   /// NB_IoT RRC context variables
@@ -84,7 +86,7 @@ typedef struct {
   /// MAC context variables
   struct eNB_MAC_INST_s **mac;
   /// NB_IoT MAC context variables
-  //struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac;
+  struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac;
   /// GTPu descriptor 
   gtpv1u_data_t *gtpv1u_data_g;
   /// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces
diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h
index 592d4877af1ac87a95c67f9d4d2365b0c586e36d..e213d785f14ef1c94a41cb61a058d25e7982b6e4 100644
--- a/nfapi/oai_integration/nfapi_pnf.h
+++ b/nfapi/oai_integration/nfapi_pnf.h
@@ -21,7 +21,7 @@
 
 #if !defined(NFAPI_PNF_H__)
 #define NFAPI_PNF_H__
-
+int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
 void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
 
 #endif
diff --git a/openair1/PHY/CODING/defs_NB_IoT.h b/openair1/PHY/CODING/defs_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..17670ec8bc040dcd03bf73d0438c1fa09b4d1226
--- /dev/null
+++ b/openair1/PHY/CODING/defs_NB_IoT.h
@@ -0,0 +1,275 @@
+/*
+ * 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/CODING/defs_NB_IoT.h
+   purpose: Top-level definitions, data types and function prototypes for openairinterface coding blocks for NB-IoT
+   author: matthieu.kanj@b-com.com, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it
+   date: 29.06.2017
+*/
+
+#ifndef OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_
+#define OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_
+
+#include <stdint.h>  // for uint8/16/32_t
+
+/* check if this ifndef is required for NB-IoT ?!
+//#ifndef NO_OPENAIR1
+//#include "PHY/defs_NB_IoT.h"
+//#else
+//#include "PHY/TOOLS/time_meas.h"
+//#endif
+*/
+
+#define CRC24_A_NB_IoT 0
+#define CRC24_B_NB_IoT 1
+#define CRC16_NB_IoT 2
+#define CRC8_NB_IoT 3
+
+//#define MAX_TURBO_ITERATIONS_MBSFN 8  // no MBSFN
+#define MAX_TURBO_ITERATIONS_NB_IoT 4
+
+#define LTE_NULL_NB_IoT 2  // defined also in PHY/LTE_TRANSPORT/defs_NB_IoT.h
+
+/** \fn uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
+\brief This is the subblock interleaving algorithm for convolutionally coded blocks from 36-212 (Release 13.4, 2017).
+This function takes the d-sequence and generates the w-sequence.  The nu-sequence from 36-212 is implicit.
+\param D Number of input bits
+\param d Pointer to input (d-sequence, convolutional code output)
+\param w Pointer to output (w-sequence, interleaver output)
+\returns Interleaving matrix cardinality (\f$K_{\pi}\f$  from 36-212)
+*/
+uint32_t sub_block_interleaving_cc_NB_IoT(uint32_t D, uint8_t *d,uint8_t *w);
+
+/**
+\brief This is the NB-IoT rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI).  It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 )
+\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) for up to 8 segments
+\param E Number of coded channel bits
+\param w This is a pointer to the w-sequence (second interleaver output)
+\param e This is a pointer to the e-sequence (rate matching output, channel input/output bits)
+\returns \f$E\f$, the number of coded bits per segment */
+
+uint32_t lte_rate_matching_cc_NB_IoT(uint32_t RCC,      // RRC = 2
+				     				 uint16_t E,        // E = 1600
+				     				 uint8_t *w,	// length
+				    				 uint8_t *e);	// length 1600
+
+/** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti)
+\brief This function implements the LTE convolutional code of rate 1/3
+  with a constraint length of 7 bits. The inputs are bit packed in octets
+(from MSB to LSB). Trellis tail-biting is included here.
+@param numbits Number of bits to encode
+@param add_crc crc to be appended (8 bits) if add_crc = 1
+@param inPtr Pointer to input buffer
+@param outPtr Pointer to output buffer
+@param rnti RNTI for CRC scrambling
+*/
+
+void ccode_encode_NB_IoT (int32_t numbits,
+						  uint8_t add_crc,
+						  uint8_t *inPtr,
+						  uint8_t *outPtr,
+						  uint16_t rnti);
+
+/*!\fn void ccodelte_init(void)
+\brief This function initializes the generator polynomials for an LTE convolutional code.*/
+void ccodelte_init_NB_IoT(void);
+
+/*!\fn void crcTableInit(void)
+\brief This function initializes the different crc tables.*/
+void crcTableInit_NB_IoT (void);
+
+
+/*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen)
+\brief This computes a 24-bit crc ('a' variant for overall transport block)
+based on 3GPP UMTS/LTE specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits
+*/
+uint32_t crc24a_NB_IoT (uint8_t *inPtr, int32_t bitlen);
+
+/*!\fn uint32_t crc24b(uint8_t *inPtr, int32_t bitlen)
+\brief This computes a 24-bit crc ('b' variant for transport-block segments)
+based on 3GPP UMTS/LTE specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits
+*/
+uint32_t crc24b_NB_IoT (uint8_t *inPtr, int32_t bitlen);
+
+/*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen)
+\brief This computes a 16-bit crc based on 3GPP UMTS specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits*/
+uint32_t crc16_NB_IoT (uint8_t *inPtr, int32_t bitlen);
+
+/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen)
+\brief This computes a 8-bit crc based on 3GPP UMTS specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits*/
+uint32_t crc8_NB_IoT  (uint8_t *inPtr, int32_t bitlen);
+
+
+
+
+
+
+uint32_t crcbit_NB_IoT (uint8_t * ,
+                 		int32_t,
+                 		uint32_t);
+
+
+/*!\fn void phy_viterbi_lte_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n)
+\brief This routine performs a SIMD optmized Viterbi decoder for the LTE 64-state tail-biting convolutional code.
+@param y Pointer to soft input (coded on 8-bits but should be limited to 4-bit precision to avoid overflow)
+@param decoded_bytes Pointer to decoded output
+@param n Length of input/trellis depth in bits*/
+//void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n);
+void phy_viterbi_lte_sse2_NB_IoT(int8_t *y,uint8_t *decoded_bytes,uint16_t n);
+
+/** \fn void sub_block_deinterleaving_cc(uint32_t D, int8_t *d,int8_t *w)
+\brief This is the subblock deinterleaving algorithm for convolutionally-coded data from 36-212 (Release 8, 8.6 2009-03), pages 15-16.
+This function takes the w-sequence and generates the d-sequence.  The nu-sequence from 36-212 is implicit.
+\param D Number of input bits
+\param d Pointer to output (d-sequence, turbo code output)
+\param w Pointer to input (w-sequence, interleaver output)
+*/
+void sub_block_deinterleaving_cc_NB_IoT(uint32_t D,int8_t *d,int8_t *w);
+
+
+/*
+\brief This is the LTE rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI).  It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 )
+\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix)
+\param E This the number of coded bits allocated for channel
+\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds
+\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions
+\param soft_input This is a pointer to the soft channel output
+\returns \f$E\f$, the number of coded bits per segment
+*/
+void lte_rate_matching_cc_rx_NB_IoT(uint32_t RCC,
+                             		uint16_t E,
+                             		int8_t *w,
+                             		uint8_t *dummy_w,
+                             		int8_t *soft_input);
+
+/** \fn generate_dummy_w_cc(uint32_t D, uint8_t *w)
+\brief This function generates a dummy interleaved sequence (first row) for receiver (convolutionally-coded data), in order to identify the NULL positions used to make the matrix complete.
+\param D Number of systematic bits plus 4 (plus 4 for termination)
+\param w This is the dummy sequence (first row), it will contain zeros and at most 31 "LTE_NULL" values
+\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212)
+*/
+uint32_t generate_dummy_w_cc_NB_IoT(uint32_t D, uint8_t *w);
+
+/** \fn lte_segmentation(uint8_t *input_buffer,
+              uint8_t **output_buffers,
+            uint32_t B,
+            uint32_t *C,
+            uint32_t *Cplus,
+            uint32_t *Cminus,
+            uint32_t *Kplus,
+            uint32_t *Kminus,
+            uint32_t *F)
+\brief This function implements the LTE transport block segmentation algorithm from 36-212, V8.6 2009-03.
+@param input_buffer
+@param output_buffers
+@param B
+@param C
+@param Cplus
+@param Cminus
+@param Kplus
+@param Kminus
+@param F
+*/
+int32_t lte_segmentation_NB_IoT(uint8_t *input_buffer,
+                         		uint8_t **output_buffers,
+                         		uint32_t B,
+                         		uint32_t *C,
+                         		uint32_t *Cplus,
+                         		uint32_t *Cminus,
+                         		uint32_t *Kplus,
+                         		uint32_t *Kminus,
+                         		uint32_t *F);
+
+/** \fn void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w)
+\brief This is the subblock deinterleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16.
+This function takes the w-sequence and generates the d-sequence.  The nu-sequence from 36-212 is implicit.
+\param D Number of systematic bits plus 4 (plus 4 for termination)
+\param d Pointer to output (d-sequence, turbo code output)
+\param w Pointer to input (w-sequence, interleaver output)
+*/
+//*****************void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w);
+
+/**
+\brief This is the LTE rate matching algorithm for Turbo-coded channels (e.g. DLSCH,ULSCH).  It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 )
+\param RTC R^TC_subblock from subblock interleaver (number of rows in interleaving matrix)
+\param G This the number of coded transport bits allocated in sub-frame
+\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds
+\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions
+\param soft_input This is a pointer to the soft channel output
+\param C Number of segments (codewords) in the sub-frame
+\param Nsoft Total number of soft bits (from UE capabilities in 36-306)
+\param Mdlharq Number of HARQ rounds
+\param Kmimo MIMO capability for this DLSCH (0 = no MIMO)
+\param rvidx round index (0-3)
+\param clear 1 means clear soft buffer (start of HARQ round)
+\param Qm modulation order (2,4,6)
+\param Nl number of layers (1,2)
+\param r segment number
+\param E_out the number of coded bits per segment
+\returns 0 on success, -1 on failure
+*/
+
+// int lte_rate_matching_turbo_rx(uint32_t RTC,
+//                                uint32_t G,
+//                                int16_t *w,
+//                                uint8_t *dummy_w,
+//                                int16_t *soft_input,
+//                                uint8_t C,
+//                                uint32_t Nsoft,
+//                                uint8_t Mdlharq,
+//                                uint8_t Kmimo,
+//                                uint8_t rvidx,
+//                                uint8_t clear,
+//                                uint8_t Qm,
+//                                uint8_t Nl,
+//                                uint8_t r,
+//                                uint32_t *E_out);
+
+// uint32_t lte_rate_matching_turbo_rx_abs(uint32_t RTC,
+//                                         uint32_t G,
+//                                         double *w,
+//                                         uint8_t *dummy_w,
+//                                         double *soft_input,
+//                                         uint8_t C,
+//                                         uint32_t Nsoft,
+//                                         uint8_t Mdlharq,
+//                                         uint8_t Kmimo,
+//                                         uint8_t rvidx,
+//                                         uint8_t clear,
+//                                         uint8_t Qm,
+//                                         uint8_t Nl,
+//                                         uint8_t r,
+//                                         uint32_t *E_out);
+
+void ccode_encode_npdsch_NB_IoT (int32_t   numbits,
+								 uint8_t   *inPtr,
+								 uint8_t   *outPtr,
+								 uint32_t  crc);
+
+#endif /* OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ */
diff --git a/openair1/PHY/INIT/defs_NB_IoT.h b/openair1/PHY/INIT/defs_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8ead217807c6620704bd29fbe3c7fa6b5625cb6
--- /dev/null
+++ b/openair1/PHY/INIT/defs_NB_IoT.h
@@ -0,0 +1,77 @@
+/*
+ * 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
+ */
+
+
+#ifndef __INIT_DEFS_NB_IOT__H__
+#define __INIT_DEFS_NB_IOT__H__
+
+//#include "PHY/defs_NB_IoT.h"
+#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"  
+#include "nfapi_interface.h"  
+
+//#include "SystemInformationBlockType2.h"
+//#include "RadioResourceConfigCommonSIB.h"
+//#include "RadioResourceConfigDedicated.h"
+//#include "TDD-Config.h"
+//#include "MBSFN-SubframeConfigList.h"
+//#include "MobilityControlInfo.h"
+//#if defined(Rel10) || defined(Rel14)
+//#include "SCellToAddMod-r10.h"
+//#endif
+
+/*brief Configure LTE_DL_FRAME_PARMS with components derived after initial synchronization (MIB-NB decoding + primary/secondary synch).*/
+void phy_config_mib_eNB_NB_IoT(int  		Mod_id,
+						   	   int          eutra_band,
+						       int          Nid_cell,
+						       int          Ncp,
+						       int			Ncp_UL,
+						       int          p_eNB,
+						       uint16_t		EARFCN,
+						       uint16_t		prb_index, // NB_IoT_RB_ID,
+						       uint16_t 	operating_mode,
+						       uint16_t		control_region_size,
+						       uint16_t		eutra_NumCRS_ports);
+
+/*NB_phy_config_sib1_eNB is not needed since NB-IoT use only FDD mode*/
+
+/*brief Configure LTE_DL_FRAME_PARMS with components of SIB2-NB (at eNB).*/
+
+//void NB_phy_config_sib2_eNB(module_id_t                            Mod_id,
+//                         int                                		CC_id,
+//                         RadioResourceConfigCommonSIB_NB_r13_t      *radioResourceConfigCommon
+//                         );
+
+void phy_config_sib2_eNB_NB_IoT(uint8_t Mod_id,
+				nfapi_nb_iot_config_t *config,
+				nfapi_rf_config_t *rf_config,
+				nfapi_uplink_reference_signal_config_t* ul_nrs_config,
+				extra_phyConfig_t* extra_phy_parms);
+
+void phy_config_dedicated_eNB_NB_IoT(module_id_t Mod_id,
+				     rnti_t rnti,
+				     extra_phyConfig_t* extra_phy_parms); 
+
+// void phy_init_lte_top_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); 
+void phy_init_nb_iot_eNB(PHY_VARS_eNB_NB_IoT *phyvar);
+int l1_north_init_NB_IoT(void);
+
+#endif
+
diff --git a/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f0b7b8c4ce7fb48a2dcabc360d9756ddae98d7e
--- /dev/null
+++ b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+
+ *******************************************************************************/
+/*! \file PHY/LTE_REFSIG/defs_NB_IoT.c
+* \function called by lte_dl_cell_spec_NB_IoT.c ,	 TS 36-211, V13.4.0 2017-02
+* \author M. KANJ
+* \date 2017
+* \version 0.0
+* \company bcom
+* \email: matthieu.kanj@b-com.com
+* \note
+* \warning
+*/
+
+/* Definitions for NB_IoT Reference signals */
+
+#ifndef __LTE_REFSIG_DEFS_NB_IOT__H__
+#define __LTE_REFSIG_DEFS_NB_IOT__H__
+
+#include "PHY/defs_L1_NB_IoT.h"
+
+/** @ingroup _PHY_REF_SIG
+ * @{
+*/
+/*!\brief This function generates the LTE Gold sequence (36-211, Sec 7.2), specifically for DL reference signals.
+@param frame_parms LTE DL Frame parameters
+@param lte_gold_table pointer to table where sequences are stored
+@param Nid_cell Cell Id for NB_IoT (to compute sequences for local and adjacent cells) */
+
+void lte_gold_NB_IoT(NB_IoT_DL_FRAME_PARMS  *frame_parms,
+					 uint32_t 				lte_gold_table_NB_IoT[20][2][14],
+					 uint16_t 				Nid_cell);
+
+/*! \brief This function generates the Narrowband reference signal (NRS) sequence (36-211, Sec 6.10.1.1)
+@param phy_vars_eNB Pointer to eNB variables
+@param output Output vector for OFDM symbol (Frequency Domain)
+@param amp Q15 amplitude
+@param Ns Slot number (0..19)
+@param l symbol (0,1) - Note 1 means 3!
+@param p antenna index
+@param RB_IoT_ID the ID of the RB dedicated for NB_IoT
+*/
+int lte_dl_cell_spec_NB_IoT(PHY_VARS_eNB_NB_IoT  *phy_vars_eNB,
+                     		int32_t 			 *output,
+                     		short 				 amp,
+                     		unsigned char 		 Ns,
+                     		unsigned char 		 l,
+                     		unsigned char 		 p,
+					 		unsigned short 		 RB_IoT_ID); 
+
+
+unsigned int lte_gold_generic_NB_IoT(unsigned int  *x1,
+									 unsigned int  *x2,
+									 unsigned char reset);
+		
+void generate_ul_ref_sigs_rx_NB_IoT(void);
+
+void free_ul_ref_sigs_NB_IoT(void);
+			 
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea84f66de42e1e69fb765af2606c3c296d0aabbf
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file PHY/LTE_TRANSPORT/dci.h
+* \brief typedefs for LTE DCI structures from 36-212, V8.6 2009-03.  Limited to 5 MHz formats for the moment.Current LTE compliance V8.6 2009-03.
+* \author R. Knopp
+* \date 2011
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr
+* \note
+* \warning
+*/
+#ifndef __DCI_NB_IOT_H__
+#define __DCI_NB_IOT_H__
+
+//#ifndef USER_MODE
+//#include "PHY/types.h"
+//#else
+#include <stdint.h>
+//#endif
+
+typedef enum 
+{
+  DCIFormatN0 = 0,
+  DCIFormatN1,
+  DCIFormatN1_RA,//is for initial RA procedure (semi-static information) so maybe is not needed
+  DCIFormatN1_RAR,
+  DCIFormatN2,
+  DCIFormatN2_Ind,
+  DCIFormatN2_Pag,
+}DCI_format_NB_IoT_t;
+
+///  DCI Format Type 0 (180 kHz, 23 bits)
+struct DCIFormatN0{
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
+  uint8_t type;
+  /// Subcarrier indication, 6 bits
+  uint8_t scind;
+  /// Resourse Assignment (RU Assignment), 3 bits
+  uint8_t ResAssign;
+  /// Modulation and Coding Scheme, 4 bits
+  uint8_t mcs;
+  /// New Data Indicator, 1 bits
+  uint8_t ndi;
+  /// Scheduling Delay, 2 bits
+  uint8_t Scheddly;
+  /// Repetition Number, 3 bits
+  uint8_t RepNum;
+  /// Redundancy version for HARQ (only use 0 and 2), 1 bits
+  uint8_t rv;
+  /// DCI subframe repetition Number, 2 bits
+  uint8_t DCIRep;
+};
+
+typedef struct DCIFormatN0 DCIFormatN0_t;
+
+///  DCI Format Type N1 for User data
+struct DCIFormatN1{
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits
+  uint8_t type;
+  //NPDCCH order indicator (set to 0), 1 bits
+  uint8_t orderIndicator;
+  // Scheduling Delay,3 bits
+  uint8_t Scheddly;
+  // Resourse Assignment (RU Assignment),3 bits
+  uint8_t ResAssign;
+  // Modulation and Coding Scheme,4 bits
+  uint8_t mcs;
+  // Repetition Number,4 bits
+  uint8_t RepNum;
+  // New Data Indicator,1 bits
+  uint8_t ndi;
+  // HARQ-ACK resource,4 bits
+  uint8_t HARQackRes;
+  // DCI subframe repetition Number,2 bits
+  uint8_t DCIRep;
+};
+
+
+typedef struct DCIFormatN1 DCIFormatN1_t;
+
+///  DCI Format Type N1 for initial RA
+struct DCIFormatN1_RA{
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
+  uint8_t type;
+  //NPDCCH order indicator (set to 0),1 bits
+  uint8_t orderIndicator;
+  // Start number of NPRACH repetiiton, 2 bits
+  uint8_t Scheddly;
+  // Subcarrier indication of NPRACH, 6 bits
+  uint8_t scind;
+  // All the remainging bits, 13 bits
+  uint8_t remaingingBits;
+};
+
+typedef struct DCIFormatN1_RA DCIFormatN1_RA_t;
+
+///  DCI Format Type N1 for User data
+struct DCIFormatN1_RAR{
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits
+  uint8_t type;
+  //NPDCCH order indicator (set to 0), 1 bits
+  uint8_t orderIndicator;
+  // Scheduling Delay,3 bits
+  uint8_t Scheddly;
+  // Resourse Assignment (RU Assignment),3 bits
+  uint8_t ResAssign;
+  // Modulation and Coding Scheme,4 bits
+  uint8_t mcs;
+  // Repetition Number,4 bits
+  uint8_t RepNum;
+  // New Data Indicator,1 bits,reserved in the RAR
+  uint8_t ndi;
+  // HARQ-ACK resource,4 bits,reserved in the RAR
+  uint8_t HARQackRes;
+  // DCI subframe repetition Number,2 bits
+  uint8_t DCIRep;
+};
+
+typedef struct DCIFormatN1_RAR DCIFormatN1_RAR_t;
+
+//  DCI Format Type N2 for direct indication, 15 bits
+struct DCIFormatN2_Ind{
+  //Flag for paging(1)/direct indication(0), set to 0,1 bits
+  uint8_t type;
+  //Direct indication information, 8 bits
+  uint8_t directIndInf;
+  // Reserved information bits, 6 bits
+  uint8_t resInfoBits;
+};
+
+typedef struct DCIFormatN2_Ind DCIFormatN2_Ind_t;
+
+//  DCI Format Type N2 for Paging, 15 bits
+struct DCIFormatN2_Pag{
+  //Flag for paging(1)/direct indication(0), set to 1,1 bits
+  uint8_t type;
+  // Resourse Assignment (RU Assignment), 3 bits
+  uint8_t ResAssign;
+  // Modulation and Coding Scheme, 4 bits
+  uint8_t mcs;
+  // Repetition Number, 4 bits
+  uint8_t RepNum;
+  // Reserved 3 bits
+  uint8_t DCIRep;
+};
+
+typedef struct DCIFormatN2_Pag DCIFormatN2_Pag_t;
+
+typedef union DCI_CONTENT {
+ // 
+ DCIFormatN0_t DCIN0;
+ //
+ DCIFormatN1_t DCIN1;
+ //
+ DCIFormatN1_RA_t DCIN1_RA;
+ //
+ DCIFormatN1_RAR_t DCIN1_RAR;
+ //
+ DCIFormatN2_Ind_t DCIN2_Ind;
+ //
+ DCIFormatN2_Pag_t DCIN2_Pag;
+
+ }DCI_CONTENT;
+
+ /*Structure for packing*/
+
+ struct DCIN0{
+  /// DCI subframe repetition Number, 2 bits
+  uint8_t DCIRep:2;
+  /// New Data Indicator, 1 bits
+  uint8_t ndi:1;
+  /// Repetition Number, 3 bits
+  uint8_t RepNum:3;
+  /// Redundancy version for HARQ (only use 0 and 2), 1 bits
+  uint8_t rv:1;
+  /// Modulation and Coding Scheme, 4 bits
+  uint8_t mcs:4;
+  /// Scheduling Delay, 2 bits
+  uint8_t Scheddly:2;
+  /// Resourse Assignment (RU Assignment), 3 bits
+  uint8_t ResAssign:3;
+  /// Subcarrier indication, 6 bits
+  uint8_t scind:6;
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
+  uint8_t type:1;
+ } __attribute__ ((__packed__));
+
+ typedef struct DCIN0 DCIN0_t;
+#define sizeof_DCIN0_t 23
+
+struct DCIN1_RAR{
+  // DCI subframe repetition Number, 2 bits
+  uint8_t DCIRep:2;
+  // HARQ-ACK resource,4 bits
+  uint8_t HARQackRes:4; 
+  // New Data Indicator,1 bits
+  uint8_t ndi:1;
+  // Repetition Number, 4 bits
+  uint8_t RepNum:4;
+  // Modulation and Coding Scheme, 4 bits
+  uint8_t mcs:4;
+  // Resourse Assignment (RU Assignment), 3 bits
+  uint8_t ResAssign:3;
+  // Scheduling Delay, 3 bits
+  uint8_t Scheddly:3;
+  //NPDCCH order indicator (set to 0),1 bits
+  uint8_t orderIndicator:1;
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
+  uint8_t type:1;
+ } __attribute__ ((__packed__));
+
+ typedef struct DCIN1_RAR DCIN1_RAR_t;
+#define sizeof_DCIN1_RAR_t 23
+
+struct DCIN1{
+  // DCI subframe repetition Number, 2 bits
+  uint8_t DCIRep:2;
+  // HARQ-ACK resource,4 bits
+  uint8_t HARQackRes:4; 
+  // New Data Indicator,1 bits
+  uint8_t ndi:1;
+  // Repetition Number, 4 bits
+  uint8_t RepNum:4;
+  // Modulation and Coding Scheme, 4 bits
+  uint8_t mcs:4;
+  // Resourse Assignment (RU Assignment), 3 bits
+  uint8_t ResAssign:3;
+  // Scheduling Delay, 3 bits
+  uint8_t Scheddly:3;
+  //NPDCCH order indicator (set to 0),1 bits
+  uint8_t orderIndicator:1;
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
+  uint8_t type:1;
+ } __attribute__ ((__packed__));
+
+ typedef struct DCIN1 DCIN1_t;
+#define sizeof_DCIN1_t 23
+
+//  DCI Format Type N2 for direct indication, 15 bits
+struct DCIN2_Ind{
+  // Reserved information bits, 6 bits
+  uint8_t resInfoBits:6;
+  //Direct indication information, 8 bits
+  uint8_t directIndInf:8;
+  //Flag for paging(1)/direct indication(0), set to 0,1 bits
+  uint8_t type:1;
+} __attribute__ ((__packed__));;
+
+typedef struct DCIN2_Ind DCIN2_Ind_t;
+#define sizeof_DCIN2_Ind_t 15
+
+//  DCI Format Type N2 for Paging, 15 bits
+struct DCIN2_Pag{
+  // Reserved 3 bits
+  uint8_t DCIRep:3;
+  // Repetition Number, 4 bits
+  uint8_t RepNum:4;
+  // Modulation and Coding Scheme, 4 bits
+  uint8_t mcs:4;
+  // Resourse Assignment (RU Assignment), 3 bits
+  uint8_t ResAssign:3;
+  //Flag for paging(1)/direct indication(0), set to 1,1 bits
+  uint8_t type:1;
+} __attribute__ ((__packed__));;
+
+typedef struct DCIN2_Pag DCIN2_Pag_t;
+
+#define sizeof_DCIN2_Pag_t 15
+
+#define MAX_DCI_SIZE_BITS_NB_IoT 23
+
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..3574ba67405c271fefe0a43d01936fb49010efd6
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h
@@ -0,0 +1,787 @@
+/*******************************************************************************
+ 
+ *******************************************************************************/
+/*! \file PHY/LTE_TRANSPORT/defs_NB_IoT.h
+* \brief data structures for NPDSCH/NDLSCH/NPUSCH/NULSCH physical and transport channel descriptors (TX/RX) of NB-IoT
+* \author M. KANJ
+* \date 2017
+* \version 0.0
+* \company bcom
+* \email: matthieu.kanj@b-com.com
+* \note
+* \warning
+*/
+#ifndef __LTE_TRANSPORT_DEFS_NB_IOT__H__
+#define __LTE_TRANSPORT_DEFS_NB_IOT__H__
+////#include "PHY/defs.h"
+//#include "PHY/defs_nb_iot.h"
+#include "PHY/LTE_TRANSPORT/dci_NB_IoT.h"
+#include "PHY/impl_defs_lte_NB_IoT.h"
+#include "openair2/COMMON/platform_types.h"
+//#include "dci.h"
+#include "PHY/LTE_TRANSPORT/uci_NB_IoT.h"
+//#include "dci.h"
+//#include "uci.h"
+//#ifndef STANDALONE_COMPILE
+//#include "UTIL/LISTS/list.h"
+//#endif
+ 
+//#include "dci_nb_iot.h"
+
+//#define MOD_TABLE_QPSK_OFFSET 1
+//#define MOD_TABLE_16QAM_OFFSET 5
+//#define MOD_TABLE_64QAM_OFFSET 21
+//#define MOD_TABLE_PSS_OFFSET 85
+//
+//// structures below implement 36-211 and 36-212
+//
+//#define NSOFT 1827072
+#define LTE_NULL_NB_IoT 2
+//
+//// maximum of 3 segments before each coding block if data length exceeds 6144 bits.
+//
+#define MAX_NUM_DLSCH_SEGMENTS_NB_IoT 16
+//#define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS
+//#define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768)
+//#define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768)
+//
+//#define MAX_NUM_CHANNEL_BITS_NB_IOT (14*1200*6)  // 14 symbols, 1200 REs, 12 bits/RE
+//#define MAX_NUM_RE (14*1200)
+//
+//#if !defined(SI_RNTI)
+//#define SI_RNTI  (rnti_t)0xffff
+//#endif
+//#if !defined(M_RNTI)
+//#define M_RNTI   (rnti_t)0xfffd
+//#endif
+//#if !defined(P_RNTI)
+//#define P_RNTI   (rnti_t)0xfffe
+//#endif
+//#if !defined(CBA_RNTI)
+//#define CBA_RNTI (rnti_t)0xfff4
+//#endif
+//#if !defined(C_RNTI)
+//#define C_RNTI   (rnti_t)0x1234
+//#endif
+//
+//#define PMI_2A_11 0
+//#define PMI_2A_1m1 1
+//#define PMI_2A_1j 2
+//#define PMI_2A_1mj 3
+//
+//// for NB-IoT
+#define MAX_NUM_CHANNEL_BITS_NB_IoT 3360 			//14 symbols * 12 sub-carriers * 10 SF * 2bits/RE  // to check during real tests
+#define MAX_DL_SIZE_BITS_NB_IoT 680 				// in release 13 // in release 14 = 2048      // ??? **** not sure
+////#define MAX_NUM_CHANNEL_BITS_NB_IOT 3*680  			/// ??? ****not sure
+//
+//// to be created LTE_eNB_DLSCH_t --> is duplicated for each number of UE and then indexed in the table
+//
+//typedef struct {                              // LTE_DL_eNB_HARQ_t
+//  /// Status Flag indicating for this DLSCH (idle,active,disabled)
+//  SCH_status_t status;
+//  /// Transport block size
+//  uint32_t TBS;
+//  /// The payload + CRC size in bits, "B" from 36-212
+//  uint32_t B;        // keep this parameter
+//  /// Pointer to the payload
+//  uint8_t *b;   // keep this parameter
+//  /// Pointers to transport block segments
+//  //uint8_t *c[MAX_NUM_DLSCH_SEGMENTS];
+//  /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
+// // uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS];
+//  /// Frame where current HARQ round was sent
+//  uint32_t frame;
+//  /// Subframe where current HARQ round was sent
+//  uint32_t subframe;
+//  /// Index of current HARQ round for this DLSCH
+//  uint8_t round;
+//  /// MCS format for this DLSCH
+//  uint8_t mcs;
+//  /// Redundancy-version of the current sub-frame
+//  uint8_t rvidx;
+//  /// MIMO mode for this DLSCH
+//  MIMO_mode_t mimo_mode;
+//  /// Current RB allocation
+//  uint32_t rb_alloc[4];
+//  /// distributed/localized flag
+//  vrb_t vrb_type;
+//  /// Current subband PMI allocation
+//  uint16_t pmi_alloc;
+//  /// Current subband RI allocation
+//  uint32_t ri_alloc;
+//  /// Current subband CQI1 allocation
+//  uint32_t cqi_alloc1;
+//  /// Current subband CQI2 allocation
+//  uint32_t cqi_alloc2;
+//  /// Current Number of RBs
+//  uint16_t nb_rb;
+//  /// downlink power offset field
+//  uint8_t dl_power_off;
+//  /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
+//  uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IOT];
+//  /// data after scrambling
+//  uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IOT];
+//  /// length of the table e
+//  uint16_t length_e                 // new parameter
+//  /// Tail-biting convolutional coding outputs
+//  uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IOT))];  // new parameter
+//  /// Sub-block interleaver outputs
+//  uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IOT+24)];      // new parameter
+//  /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17, TM3-4)
+//  uint8_t Nl;
+//  /// Number of layers for this PDSCH transmission (TM8-10)
+//  uint8_t Nlayers;
+//  /// First layer for this PSCH transmission
+//  uint8_t first_layer;
+//} NB_IoT_DL_eNB_HARQ_t;
+
+typedef enum {
+
+  SCH_IDLE_NB_IoT,
+  ACTIVE_NB_IoT,
+  CBA_ACTIVE_NB_IoT,
+  DISABLED_NB_IoT
+
+} SCH_status_NB_IoT_t;
+
+
+typedef struct {
+  /// NB-IoT
+  SCH_status_NB_IoT_t   status;
+  /// The scheduling the NPDCCH and the NPDSCH transmission TS 36.213 Table 16.4.1-1
+  uint8_t               scheduling_delay;
+  /// The number of the subframe to transmit the NPDSCH Table TS 36.213 Table 16.4.1.3-1  (Nsf) (NB. in this case is not the index Isf)
+  uint8_t               resource_assignment;
+  /// is the index that determined the repeat number of NPDSCH through table TS 36.213 Table 16.4.1.3-2 / for SIB1-NB Table 16.4.1.3-3
+  uint8_t               repetition_number;
+  /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2
+  uint8_t               HARQ_ACK_resource;
+  /// Determined the repetition number value 0-3 (2 biut carried by the FAPI NPDCCH)
+  uint8_t               dci_subframe_repetitions;
+  /// modulation always QPSK Qm = 2 
+  uint8_t               modulation;
+  /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
+  uint8_t               e[MAX_NUM_CHANNEL_BITS_NB_IoT];
+  /// data after scrambling
+  uint8_t               s_e[MAX_NUM_CHANNEL_BITS_NB_IoT];
+  //length of the table e
+  uint16_t              length_e;                // new parameter
+  /// Tail-biting convolutional coding outputs
+  uint8_t               d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IoT))];  // new parameter
+  /// Sub-block interleaver outputs
+  uint8_t               w[3*3*(MAX_DL_SIZE_BITS_NB_IoT+24)];      // new parameter
+
+  /// Status Flag indicating for this DLSCH (idle,active,disabled)
+  //SCH_status_t status;
+  /// Transport block size
+  uint32_t              TBS;
+  /// The payload + CRC size in bits, "B" from 36-212
+  uint32_t              B;
+  /// Pointer to the payload
+  uint8_t               *b;
+  ///pdu of the ndlsch message
+  uint8_t               *pdu;
+  /// Frame where current HARQ round was sent
+  uint32_t              frame;
+  /// Subframe where current HARQ round was sent
+  uint32_t              subframe;
+  /// Index of current HARQ round for this DLSCH
+  uint8_t               round;
+  /// MCS format for this NDLSCH , TS 36.213 Table 16.4.1.5
+  uint8_t               mcs;
+  // we don't have code block segmentation / crc attachment / concatenation in NB-IoT R13 36.212 6.4.2
+  // we don't have beamforming in NB-IoT
+  //this index will be used mainly for SI message buffer
+   uint8_t               pdu_buffer_index;
+
+} NB_IoT_DL_eNB_HARQ_t;
+
+
+typedef struct {                                        // LTE_eNB_DLSCH_t
+ /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
+ uint32_t               *txdataF[8];
+ /// Allocated RNTI (0 means DLSCH_t is not currently used)
+ uint16_t               rnti;
+ /// Active flag for baseband transmitter processing
+ uint8_t                active;
+ /// Indicator of TX activation per subframe.  Used during PUCCH detection for ACK/NAK.
+ uint8_t                subframe_tx[10];
+ /// First CCE of last PDSCH scheduling per subframe.  Again used during PUCCH detection for ACK/NAK.
+ uint8_t                nCCE[10];
+ /// Current HARQ process id
+ uint8_t                current_harq_pid;
+ /// Process ID's per subframe.  Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids
+ uint8_t                harq_ids[10];
+ /// Window size (in outgoing transport blocks) for fine-grain rate adaptation
+ uint8_t                ra_window_size;
+ /// First-round error threshold for fine-grain rate adaptation
+ uint8_t                error_threshold;
+ /// Pointers to 8 HARQ processes for the DLSCH
+ NB_IoT_DL_eNB_HARQ_t   harq_process;
+ /// circular list of free harq PIDs (the oldest come first)
+ /// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE)
+ int                    harq_pid_freelist[10];
+ /// the head position of the free list (if list is free then head=tail)
+ int                    head_freelist;
+ /// the tail position of the free list
+ int                    tail_freelist;
+ /// Number of soft channel bits
+ uint32_t               G;
+ /// Codebook index for this dlsch (0,1,2,3)
+ uint8_t                codebook_index;
+ /// Maximum number of HARQ processes (for definition see 36-212 V8.6 2009-03, p.17)
+ uint8_t                Mdlharq;
+ /// Maximum number of HARQ rounds
+ uint8_t                Mlimit;
+ /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17)
+ uint8_t                Kmimo;
+ /// Nsoft parameter related to UE Category
+ uint32_t               Nsoft;
+ /// amplitude of PDSCH (compared to RS) in symbols without pilots
+ int16_t                sqrt_rho_a;
+ /// amplitude of PDSCH (compared to RS) in symbols containing pilots
+ int16_t                sqrt_rho_b;
+
+} NB_IoT_eNB_DLSCH_t;
+
+
+typedef struct {
+  /// HARQ process id
+  uint8_t   harq_id;
+  /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX
+  uint8_t   ack;
+  /// send status (for PUCCH)
+  uint8_t   send_harq_status;
+  /// nCCE (for PUCCH)
+  uint8_t   nCCE;
+  /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched
+  uint8_t   vDAI_DL;
+  /// DAI value detected from DCI0/4. 0xff indicates not touched
+  uint8_t   vDAI_UL;
+} harq_status_NB_IoT_t;
+
+typedef struct {
+  /// UL RSSI per receive antenna
+  int32_t             UL_rssi[NB_ANTENNAS_RX];
+  /// PUCCH1a/b power (digital linear)
+  uint32_t            Po_PUCCH;
+  /// PUCCH1a/b power (dBm)
+  int32_t             Po_PUCCH_dBm;
+  /// PUCCH1 power (digital linear), conditioned on below threshold
+  uint32_t            Po_PUCCH1_below;
+  /// PUCCH1 power (digital linear), conditioned on above threshold
+  uint32_t            Po_PUCCH1_above;
+  /// Indicator that Po_PUCCH has been updated by PHY
+  int32_t             Po_PUCCH_update;
+  /// DL Wideband CQI index (2 TBs)
+  uint8_t             DL_cqi[2];
+  /// DL Subband CQI index (from HLC feedback)
+  uint8_t             DL_subband_cqi[2][13];
+  /// DL PMI Single Stream
+  uint16_t            DL_pmi_single;
+  /// DL PMI Dual Stream
+  uint16_t            DL_pmi_dual;
+  /// Current RI
+  uint8_t             rank;
+  /// CRNTI of UE
+  uint16_t            crnti; ///user id (rnti) of connected UEs
+  /// Initial timing offset estimate from PRACH for RAR
+  int32_t             UE_timing_offset;
+  /// Timing advance estimate from PUSCH for MAC timing advance signalling
+  int32_t             timing_advance_update;
+  /// Current mode of UE (NOT SYCHED, RAR, PUSCH)
+  UE_MODE_NB_IoT_t    mode;
+  /// Current sector where UE is attached
+  uint8_t             sector;
+
+  /// dlsch l2 errors
+  uint32_t            dlsch_l2_errors[8];
+  /// dlsch trials per harq and round
+  uint32_t            dlsch_trials[8][8];
+  /// dlsch ACK/NACK per hard_pid and round
+  uint32_t            dlsch_ACK[8][8];
+  uint32_t            dlsch_NAK[8][8];
+
+  /// ulsch l2 errors per harq_pid
+  uint32_t            ulsch_errors[8];
+  /// ulsch l2 consecutive errors per harq_pid
+  uint32_t            ulsch_consecutive_errors; //[8];
+  /// ulsch trials/errors/fer per harq and round
+  uint32_t            nulsch_decoding_attempts[8][8];
+  uint32_t            ulsch_round_errors[8][8];
+  uint32_t            ulsch_decoding_attempts_last[8][8];
+  uint32_t            ulsch_round_errors_last[8][8];
+  uint32_t            ulsch_round_fer[8][8];
+  uint32_t            sr_received;
+  uint32_t            sr_total;
+
+  /// dlsch sliding count and total errors in round 0 are used to compute the dlsch_mcs_offset
+  uint32_t            dlsch_sliding_cnt;
+  uint32_t            dlsch_NAK_round0;
+  int8_t              dlsch_mcs_offset;
+
+  /// Target mcs1 after rate-adaptation (used by MAC layer scheduler)
+  uint8_t             dlsch_mcs1;
+  /// Target mcs2 after rate-adaptation (used by MAC layer scheduler)
+  uint8_t             dlsch_mcs2;
+  /// Total bits received from MAC on PDSCH
+  int                 total_TBS_MAC;
+  /// Total bits acknowledged on PDSCH
+  int                 total_TBS;
+  /// Total bits acknowledged on PDSCH (last interval)
+  int                 total_TBS_last;
+  /// Bitrate on the PDSCH [bps]
+  unsigned int        dlsch_bitrate;
+  //  unsigned int total_transmitted_bits;
+
+} NB_IoT_eNB_UE_stats;
+
+typedef struct {
+  /// Indicator of first transmission
+  uint8_t     first_tx;
+  /// Last Ndi received for this process on DCI (used for C-RNTI only)
+  uint8_t     DCINdi;
+  /// DLSCH status flag indicating
+  //SCH_status_t status;
+  /// Transport block size
+  uint32_t    TBS;
+  /// The payload + CRC size in bits
+  uint32_t    B;
+  /// Pointer to the payload
+  uint8_t     *b;
+  /// Pointers to transport block segments
+  uint8_t     *c[MAX_NUM_DLSCH_SEGMENTS_NB_IoT];
+  /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
+  uint32_t    RTC[MAX_NUM_DLSCH_SEGMENTS_NB_IoT];
+  /// Index of current HARQ round for this DLSCH
+  uint8_t     round;
+  /// MCS format for this DLSCH
+  uint8_t     mcs;
+  /// Qm (modulation order) for this DLSCH
+  uint8_t     Qm;
+  /// Redundancy-version of the current sub-frame
+  uint8_t     rvidx;
+  /// MIMO mode for this DLSCH
+ // MIMO_mode_t mimo_mode;
+  /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
+  int16_t     w[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)];
+  /// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
+  double      w_abs[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)];
+  /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
+  int16_t     *d[MAX_NUM_DLSCH_SEGMENTS_NB_IoT];
+  /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
+  uint32_t    C;
+  /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t    Cminus;
+  /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t    Cplus;
+  /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t    Kminus;
+  /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t    Kplus;
+  /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t    F;
+  /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17)
+  uint8_t     Nl;
+  /// current delta_pucch
+  int8_t      delta_PUCCH;
+  /// Number of soft channel bits
+  uint32_t    G;
+  /// Current Number of RBs
+  uint16_t    nb_rb;
+  /// Current subband PMI allocation
+  uint16_t    pmi_alloc;
+  /// Current RB allocation (even slots)
+  uint32_t    rb_alloc_even[4];
+  /// Current RB allocation (odd slots)
+  uint32_t    rb_alloc_odd[4];
+  /// distributed/localized flag
+  //vrb_t vrb_type;
+  /// downlink power offset field
+  uint8_t     dl_power_off;
+  /// trials per round statistics
+  uint32_t    trials[8];
+  /// error statistics per round
+  uint32_t    errors[8];
+  /// codeword this transport block is mapped to
+  uint8_t     codeword;
+
+} NB_IoT_DL_UE_HARQ_t;
+
+typedef struct {
+  /// RNTI
+  uint16_t              rnti;
+  /// Active flag for DLSCH demodulation
+  uint8_t               active;
+  /// Transmission mode
+  uint8_t               mode1_flag;
+  /// amplitude of PDSCH (compared to RS) in symbols without pilots
+  int16_t               sqrt_rho_a;
+  /// amplitude of PDSCH (compared to RS) in symbols containing pilots
+  int16_t               sqrt_rho_b;
+  /// Current HARQ process id threadRx Odd and threadRx Even
+  uint8_t               current_harq_pid;
+  /// Current subband antenna selection
+  uint32_t              antenna_alloc;
+  /// Current subband RI allocation
+  uint32_t              ri_alloc;
+  /// Current subband CQI1 allocation
+  uint32_t              cqi_alloc1;
+  /// Current subband CQI2 allocation
+  uint32_t              cqi_alloc2;
+  /// saved subband PMI allocation from last PUSCH/PUCCH report
+  uint16_t              pmi_alloc;
+  /// HARQ-ACKs
+  harq_status_NB_IoT_t  harq_ack;
+  /// Pointers to up to 8 HARQ processes
+  NB_IoT_DL_UE_HARQ_t   *harq_process;
+  /// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17
+  uint8_t               Mdlharq;
+  /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17)
+  uint8_t               Kmimo;
+  /// Nsoft parameter related to UE Category
+  uint32_t              Nsoft;
+  /// Maximum number of Turbo iterations
+  uint8_t               max_turbo_iterations;
+  /// number of iterations used in last turbo decoding
+  uint8_t               last_iteration_cnt;
+  /// accumulated tx power adjustment for PUCCH
+  int8_t                g_pucch;
+
+} NB_IoT_UE_DLSCH_t;
+
+//----------------------------------------------------------------------------------------------------------
+// NB-IoT
+//----------------------------------------------------------------------------------------------------
+
+//enum for distinguish the different type of ndlsch (may in the future will be not needed)
+typedef enum
+{
+
+  SIB1,
+  SI_Message,
+  RAR,
+  UE_Data
+
+}ndlsch_flag_t;
+
+
+
+typedef struct {
+  rnti_t          rnti;
+  //array containing the pdus of DCI
+  uint8_t         *a[2];
+  //Array containing encoded DCI data
+  uint8_t         *e[2];
+
+  //UE specific parameters
+  uint16_t        npdcch_NumRepetitions;
+
+  uint16_t        repetition_number;
+  //indicate the corresponding subframe within the repetition (set to 0 when a new NPDCCH pdu is received)
+  uint16_t        repetition_idx;
+
+  //  uint16_t npdcch_Offset_USS;
+  //  uint16_t npdcch_StartSF_USS;
+
+
+}NB_IoT_eNB_NPDCCH_t;
+
+
+typedef struct{
+
+  //Number of repetitions (R) for common search space (RAR and PAGING)
+  uint16_t    number_repetition_RA;
+  uint16_t    number_repetition_PAg;
+  //index of the current subframe among the repetition (set to 0 when we receive the new NPDCCH)
+  uint16_t    repetition_idx_RA;
+  uint16_t    repetition_idx_Pag;
+
+}NB_IoT_eNB_COMMON_NPDCCH_t;
+
+
+typedef struct {
+
+  /// Length of DCI in bits
+  uint8_t               dci_length;
+  /// Aggregation level only 1,2 in NB-IoT
+  uint8_t               L;
+  /// Position of first CCE of the dci
+  int                   firstCCE;
+  /// flag to indicate that this is a RA response
+  boolean_t      ra_flag;
+  /// rnti
+  rnti_t                rnti;
+  /// Format
+  DCI_format_NB_IoT_t   format;
+  /// DCI pdu
+  uint8_t               dci_pdu[8];
+
+} DCI_ALLOC_NB_IoT_t;
+
+
+typedef struct {
+  //delete the count for the DCI numbers,NUM_DCI_MAX should set to 2
+  uint32_t              num_npdcch_symbols;
+  ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission
+  /// see FAPI/NFAPI specs Table 4-45
+  uint8_t               npdcch_start_symbol;
+  uint8_t               Num_dci;
+  DCI_ALLOC_NB_IoT_t    dci_alloc[2] ;
+
+} DCI_PDU_NB_IoT;
+
+
+
+
+typedef struct {
+  /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
+  int32_t                 *txdataF[8];
+  /// dl channel estimates (estimated from ul channel estimates)
+  int32_t                 **calib_dl_ch_estimates;
+  /// Allocated RNTI (0 means DLSCH_t is not currently used)
+  uint16_t                rnti;
+  /// Active flag for baseband transmitter processing
+  uint8_t                 active;
+  /// Indicator of TX activation per subframe.  Used during PUCCH detection for ACK/NAK.
+  uint8_t                 subframe_tx[10];
+  /// First CCE of last PDSCH scheduling per subframe.  Again used during PUCCH detection for ACK/NAK.
+  uint8_t                 nCCE[10];
+  /*in NB-IoT there is only 1 HARQ process for each UE therefore no pid is required*/
+  /// The only HARQ process for the DLSCH
+  NB_IoT_DL_eNB_HARQ_t    *harq_process;
+  /// Number of soft channel bits
+  uint32_t                G;
+  /// Maximum number of HARQ rounds
+  uint8_t                 Mlimit;
+  /// Nsoft parameter related to UE Category
+  uint32_t                Nsoft;
+  /// amplitude of PDSCH (compared to RS) in symbols without pilots
+  int16_t                 sqrt_rho_a;
+  /// amplitude of PDSCH (compared to RS) in symbols containing pilots
+  int16_t                 sqrt_rho_b;
+  ///NB-IoT
+  /// may use in the npdsch_procedures
+  uint16_t                scrambling_sequence_intialization;
+  /// number of cell specific TX antenna ports assumed by the UE
+  uint8_t                 nrs_antenna_ports;
+
+  //This indicate the current subframe within the subframe interval between the NPDSCH transmission (Nsf*Nrep)
+  uint16_t                sf_index;
+  ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDSCH transmission
+  /// see FAPI/NFAPI specs Table 4-47
+  uint8_t                 npdsch_start_symbol;
+  /*SIB1-NB related parameters*/
+  ///flag for indicate if the current frame is the start of a new SIB1-NB repetition within the SIB1-NB period (0 = FALSE, 1 = TRUE)
+  uint8_t                 sib1_rep_start;
+  ///the number of the frame within the 16 continuous frame in which sib1-NB is transmitted (1-8 = 1st, 2nd ecc..) (0 = not foresees a transmission)
+  uint8_t                 relative_sib1_frame;
+  //Flag  used to discern among different NDLSCH structures (SIB1,SI,RA,UE-spec)
+  //(used inside the ndlsch procedure for distinguish the different type of data to manage also in term of repetitions and transmission over more subframes
+  ndlsch_flag_t           ndlsch_type;
+
+} NB_IoT_eNB_NDLSCH_t;
+
+typedef struct {
+  /// Length of CQI data under RI=1 assumption(bits)
+  uint8_t               Or1;
+  /// Rank information
+  uint8_t               o_RI[2];
+  /// Format of CQI data
+  UCI_format_NB_IoT_t   uci_format;
+  /// The value of DAI in DCI format 0
+  uint8_t               V_UL_DAI;
+  /// Pointer to CQI data
+  uint8_t               o[MAX_CQI_BYTES_NB_IoT];
+  /// CQI CRC status
+  uint8_t               cqi_crc_status;
+  /// PHICH active flag
+  uint8_t               phich_active;
+  /// PHICH ACK
+  uint8_t               phich_ACK;
+  /// Length of rank information (bits)
+  uint8_t               O_RI;
+  /// First Allocated RB
+  uint16_t              first_rb;
+  /// Current Number of RBs
+  uint16_t              nb_rb;
+  /// Determined the subcarrier allocation for the NPUSCH.(15, 3.75 KHz)
+  uint8_t               subcarrier_indication;
+  /// Determined the number of resource unit for the NPUSCH
+  uint8_t               resource_assignment;
+  /// Determined the scheduling delay for NPUSCH
+  uint8_t               scheduling_delay;
+  /// The number of the repetition number for NPUSCH Transport block
+  uint8_t               repetition_number;
+  /// Determined the repetition number value 0-3
+  uint8_t               dci_subframe_repetitions;
+  /// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK)
+  uint8_t               dci_alloc;
+  /// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI)
+  uint8_t               rar_alloc;
+  /// Status Flag indicating for this ULSCH (idle,active,disabled)
+  SCH_status_NB_IoT_t   status;
+  /// Subframe scheduling indicator (i.e. Transmission opportunity indicator)
+  uint8_t               subframe_scheduling_flag;
+  /// Transport block size
+  uint32_t              TBS;
+  /// The payload + CRC size in bits
+  uint32_t              B;
+  /// Number of soft channel bits
+  uint32_t              G;
+  /// Pointer to ACK
+  uint8_t               o_ACK[4];
+  /// Length of ACK information (bits)
+  uint8_t               O_ACK;
+  /// coded ACK bits
+  int16_t               q_ACK[MAX_ACK_PAYLOAD_NB_IoT];
+  /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
+  /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
+  int16_t               e[MAX_NUM_CHANNEL_BITS_NB_IoT] __attribute__((aligned(32)));
+  /// coded RI bits
+  int16_t               q_RI[MAX_RI_PAYLOAD_NB_IoT];
+  /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
+  int8_t                q[MAX_CQI_PAYLOAD_NB_IoT];
+  /// number of coded CQI bits after interleaving
+  uint8_t               o_RCC;
+  /// coded and interleaved CQI bits
+  int8_t                o_w[(MAX_CQI_BITS_NB_IoT+8)*3];
+  /// coded CQI bits
+  int8_t                o_d[96+((MAX_CQI_BITS_NB_IoT+8)*3)];
+  ///
+  uint32_t              C;
+  /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t              Cminus;
+  /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t              Cplus;
+  /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t              Kminus;
+  /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t              Kplus;
+  /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10)
+  uint32_t              F;
+  /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
+  //uint8_t h[MAX_NUM_CHANNEL_BITS];
+  /// SRS active flag
+  uint8_t               srs_active;
+  /// Pointer to the payload
+  uint8_t               *b;
+  /// Current Number of Symbols
+  uint8_t               Nsymb_pusch;
+  /// Index of current HARQ round for this ULSCH
+  uint8_t               round;
+  /// MCS format for this ULSCH
+  uint8_t               mcs;
+  /// Redundancy-version of the current sub-frame (value 0->RV0,value 1 ->RV2)
+  uint8_t               rvidx;
+  /// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27)
+  uint16_t              Msc_initial;
+  /// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27)
+  uint8_t               Nsymb_initial;
+  /// n_DMRS  for cyclic shift of DMRS (36.213 Table 9.1.2-2)
+  uint8_t               n_DMRS;
+  /// n_DMRS  for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling
+  /// This is needed for PHICH generation which
+  /// is done after a new scheduling
+  uint8_t               previous_n_DMRS;
+  /// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1)
+  uint8_t               n_DMRS2;
+  /// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up)
+  //  int calibration_flag;
+  /// delta_TF for power control
+  int32_t               delta_TF;
+  ///////////////////////////////////////////// 4 parameter added by vincent ///////////////////////////////////////////////
+  // NB_IoT: Nsymb_UL and Nslot_UL are defined in 36.211, Section 10.1.2.3, Table 10.1.2.3-1
+  // The number of symbol in a resource unit is given by Nsymb_UL*Nslot_UL
+  uint8_t               Nsymb_UL; 
+  // Number of NPUSCH slots
+  uint8_t               Nslot_UL; 
+  // Number of subcarrier for NPUSH, can be 1, 3, 6, 12
+  uint8_t               N_sc_RU; 
+  // Index of UL NB_IoT resource block
+  uint32_t              UL_RB_ID_NB_IoT; 
+  // Subcarrier indication fields, obtained through DCI, Section 16.5.1.1 in 36.213
+  uint16_t              I_sc; 
+  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+} NB_IoT_UL_eNB_HARQ_t;
+
+
+typedef struct {
+  /// Pointers to the HARQ processes for the NULSCH
+  NB_IoT_UL_eNB_HARQ_t    *harq_process;
+  /// Maximum number of HARQ rounds
+  uint8_t                 Mlimit;
+  /// Value 0 = npush format 1 (data) value 1 = npusch format 2 (ACK/NAK)
+  uint8_t                 npusch_format;
+  /// Flag to indicate that eNB awaits UE Msg3
+  uint8_t                 Msg3_active;
+  /// Flag to indicate that eNB should decode UE Msg3
+  uint8_t                 Msg3_flag;
+  /// Subframe for Msg3
+  uint8_t                 Msg3_subframe;
+  /// Frame for Msg3
+  uint32_t                Msg3_frame;
+  /// RNTI attributed to this ULSCH
+  uint16_t                rnti;
+  /// cyclic shift for DM RS
+  uint8_t                 cyclicShift;
+  /// cooperation flag
+  uint8_t                 cooperation_flag;
+  /// (only in-band mode), indicate the resource block overlap the SRS configuration of LTE
+  uint8_t                 N_srs;
+  ///
+  uint8_t                 scrambling_re_intialization_batch_index;
+  /// number of cell specific TX antenna ports assumed by the UE
+  uint8_t                 nrs_antenna_ports;
+  ///
+  uint16_t                scrambling_sequence_intialization;
+  ///
+  uint16_t                sf_index;
+  /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2
+  uint8_t                 HARQ_ACK_resource;
+
+  ///////////// kept from LTE ///////////////////////////////////////////////////
+
+  /// Maximum number of iterations used in eNB turbo decoder
+  uint8_t                 max_turbo_iterations;
+  /// ACK/NAK Bundling flag
+  uint8_t                 bundling;
+  /// beta_offset_cqi times 8
+  uint16_t                beta_offset_cqi_times8;
+  /// beta_offset_ri times 8
+  uint16_t                beta_offset_ri_times8;
+  /// beta_offset_harqack times 8
+  uint16_t                beta_offset_harqack_times8;
+  /// num active cba group
+  uint8_t                 num_active_cba_groups;
+  /// allocated CBA RNTI for this ulsch
+  uint16_t                cba_rnti[4];//NUM_MAX_CBA_GROUP];
+  #ifdef LOCALIZATION
+  /// epoch timestamp in millisecond
+  int32_t                 reference_timestamp_ms;
+  /// aggregate physical states every n millisecond
+  int32_t                 aggregation_period_ms;
+  /// a set of lists used for localization
+  struct                  list loc_rss_list[10], loc_rssi_list[10], loc_subcarrier_rss_list[10], loc_timing_advance_list[10], loc_timing_update_list[10];
+  struct                  list tot_loc_rss_list, tot_loc_rssi_list, tot_loc_subcarrier_rss_list, tot_loc_timing_advance_list, tot_loc_timing_update_list;
+  #endif
+
+} NB_IoT_eNB_NULSCH_t;
+
+#define NPBCH_A 34
+
+typedef struct {
+  //the 2 LSB of the hsfn (the MSB are indicated by the SIB1-NB)
+  uint16_t  h_sfn_lsb;
+
+  uint8_t   npbch_d[96+(3*(16+NPBCH_A))];
+  uint8_t   npbch_w[3*3*(16+NPBCH_A)];
+  uint8_t   npbch_e[1600];
+  ///pdu of the npbch message
+  uint8_t   *pdu;
+
+} NB_IoT_eNB_NPBCH_t;
+
+
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
index 46689a9aaa0473a14cda15cedea92db8896c9a65..7682045ae1307ca6a10ee83ef071091f7e28528d 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -40,7 +40,7 @@
 //#define DEBUG_LLR_SIC
 
 
-int16_t zero[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0};
+int16_t zeros[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0};
 int16_t ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
 #if defined(__x86_64__) || defined(__i386__)
 __m128i rho_rpi __attribute__ ((aligned(16)));
diff --git a/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e3a55eacc1cc292a1cd66cf1b35a8fec373ae4c
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h
@@ -0,0 +1,362 @@
+/*
+ * 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/proto.h
+ * \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03
+ * \author R. Knopp, F. Kaltenberger
+ * \date 2011
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+#ifndef __LTE_TRANSPORT_PROTO_NB_IOT__H__
+#define __LTE_TRANSPORT_PROTO_NB_IOT__H__
+#include "PHY/defs_L1_NB_IoT.h"
+//#include <math.h>
+
+//NPSS
+
+int generate_npss_NB_IoT(int32_t                **txdataF,
+                         short                  amp,
+                         NB_IoT_DL_FRAME_PARMS  *frame_parms,
+                         unsigned short         symbol_offset,          // symbol_offset should equal to 3 for NB-IoT 
+                         unsigned short         slot_offset,
+                         unsigned short         RB_IoT_ID);             // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
+
+//NSSS
+
+int generate_sss_NB_IoT(int32_t                **txdataF,
+                        int16_t                amp,
+                        NB_IoT_DL_FRAME_PARMS  *frame_parms, 
+                        uint16_t               symbol_offset,             // symbol_offset = 3 for NB-IoT 
+                        uint16_t               slot_offset, 
+                        unsigned short         frame_number,        // new attribute (Get value from higher layer), it does not exist for LTE
+                        unsigned short         RB_IoT_ID);          // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
+
+//*****************Vincent part for Cell ID estimation from NSSS ******************// 
+
+int rx_nsss_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int32_t *tot_metric); 
+
+int nsss_extract_NB_IoT(PHY_VARS_UE_NB_IoT *ue,
+            NB_IoT_DL_FRAME_PARMS *frame_parms,
+            int32_t **nsss_ext,
+            int l);
+
+//NRS
+
+void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT  *phy_vars_eNB,
+                            int32_t              **txdataF,
+                            int16_t              amp,
+                            uint16_t             Ntti,                // Ntti = 10
+                            unsigned short       RB_IoT_ID,       // RB reserved for NB-IoT
+                            unsigned short       With_NSSS);      // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal
+
+
+//NPBCH
+
+int allocate_npbch_REs_in_RB(NB_IoT_DL_FRAME_PARMS  *frame_parms,
+                             int32_t                **txdataF,
+                             uint32_t               *jj,
+                             uint32_t               symbol_offset,
+                             uint8_t                *x0,
+                             uint8_t                pilots,
+                             int16_t                amp,
+                             unsigned short         id_offset,
+                             uint32_t               *re_allocated);
+
+
+int generate_npbch(NB_IoT_eNB_NPBCH_t     *eNB_npbch,
+                   int32_t                **txdataF,
+                   int                    amp,
+                   NB_IoT_DL_FRAME_PARMS  *frame_parms,
+                   uint8_t                *npbch_pdu,
+                   uint8_t                frame_mod64,
+                   unsigned short         NB_IoT_RB_ID);
+
+
+void npbch_scrambling(NB_IoT_DL_FRAME_PARMS  *frame_parms,
+                      uint8_t                *npbch_e,
+                      uint32_t               length);
+
+// Functions below implement 36-211 and 36-212
+
+/*Function to pack the DCI*/ 
+// newly added function for NB-IoT , does not exist for LTE
+void add_dci_NB_IoT(DCI_PDU_NB_IoT    *DCI_pdu,
+                    void              *pdu,
+                    rnti_t            rnti,
+                    unsigned char     dci_size_bytes,
+                    unsigned char     aggregation, 
+                    unsigned char     dci_size_bits,
+                    unsigned char     dci_fmt,
+                    uint8_t           npdcch_start_symbol);
+
+
+/*Use the UL DCI Information to configure PHY and also Pack the DCI*/
+int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT     *eNB,
+                                              eNB_rxtx_proc_NB_IoT_t  *proc,
+                                              DCI_CONTENT             *DCI_Content,
+                                              uint16_t                rnti,
+                                              DCI_format_NB_IoT_t     dci_format,
+                                              uint8_t                 UE_id,
+                                              uint8_t                 aggregation,
+									                            uint8_t                 npdcch_start_symbol);
+
+
+/*Use the DL DCI Information to configure PHY and also Pack the DCI*/
+int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT    *eNB,
+                                              int                    frame,
+                                              uint8_t                subframe,
+                                              DCI_CONTENT            *DCI_Content,
+                                              uint16_t               rnti,
+                                              DCI_format_NB_IoT_t    dci_format,
+                                              NB_IoT_eNB_NDLSCH_t    *ndlsch,
+                                              NB_IoT_DL_FRAME_PARMS  *frame_parms,
+                                              uint8_t                aggregation,
+									                            uint8_t                npdcch_start_symbol);
+
+
+/*Function for DCI encoding, scrambling, modulation*/
+uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t     *npdcch,
+						                    uint8_t                 Num_dci,
+                                DCI_ALLOC_NB_IoT_t      *dci_alloc,
+                                int16_t                 amp,
+                                NB_IoT_DL_FRAME_PARMS   *fp,
+                                int32_t                 **txdataF,
+                                uint32_t                subframe,
+						                    uint8_t                 npdcch_start_symbol);
+
+/*!
+  \brief Decoding of PUSCH/ACK/RI/ACK from 36-212.
+  @param phy_vars_eNB Pointer to eNB top-level descriptor
+  @param proc Pointer to RXTX proc variables
+  @param UE_id ID of UE transmitting this PUSCH
+  @param subframe Index of subframe for PUSCH
+  @param control_only_flag Receive PUSCH with control information only
+  @param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213
+  @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
+  @returns 0 on success
+*/
+unsigned int  ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT     *phy_vars_eNB,
+                                    eNB_rxtx_proc_NB_IoT_t  *proc,
+                                    uint8_t                 UE_id,
+                                    uint8_t                 control_only_flag,
+                                    uint8_t                 Nbundled,
+                                    uint8_t                 llr8_flag);
+
+//NB-IoT version
+NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(//unsigned char Kmimo,
+                                          //unsigned char Mdlharq,
+                                          uint32_t Nsoft,
+                                          //unsigned char N_RB_DL,
+                                          uint8_t abstraction_flag,
+                                          NB_IoT_DL_FRAME_PARMS* frame_parms);
+
+
+NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t abstraction_flag);
+
+
+uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe);
+
+
+/** \brief Compute Q (modulation order) based on I_MCS for PUSCH.  Implements table 8.6.1-1 from 36.213.
+    @param I_MCS */
+
+//uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS);
+unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS, uint8_t N_sc_RU);
+
+/** \fn dlsch_encoding(PHY_VARS_eNB *eNB,
+    uint8_t *input_buffer,
+    LTE_DL_FRAME_PARMS *frame_parms,
+    uint8_t num_pdcch_symbols,
+    LTE_eNB_DLSCH_t *dlsch,
+    int frame,
+    uint8_t subframe)
+    \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are:
+    - CRC computation and addition
+    - Code block segmentation and sub-block CRC addition
+    - Channel coding (Turbo coding)
+    - Rate matching (sub-block interleaving, bit collection, selection and transmission
+    - Code block concatenation
+    @param eNB Pointer to eNB PHY context
+    @param input_buffer Pointer to input buffer for sub-frame
+    @param frame_parms Pointer to frame descriptor structure
+    @param num_pdcch_symbols Number of PDCCH symbols in this subframe
+    @param dlsch Pointer to dlsch to be encoded
+    @param frame Frame number
+    @param subframe Subframe number
+    @param rm_stats Time statistics for rate-matching
+    @param te_stats Time statistics for turbo-encoding
+    @param i_stats Time statistics for interleaving
+    @returns status
+*/
+
+int32_t dlsch_encoding_NB_IoT(unsigned char              *a,
+                              NB_IoT_eNB_DLSCH_t         *dlsch,
+                              uint8_t                    Nsf,        // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table)
+                              unsigned int               G,          // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation)
+                              time_stats_t               *rm_stats,
+                              time_stats_t               *te_stats,
+                              time_stats_t               *i_stats);
+
+
+void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT      *phy_vars_eNB,
+                     eNB_rxtx_proc_NB_IoT_t   *proc,
+                     uint8_t                  eNB_id,               // this is the effective sector id
+                     uint8_t                  UE_id,
+                     NB_IoT_eNB_NULSCH_t      **ulsch,
+                     uint8_t                  cooperation_flag);
+
+
+
+
+void ulsch_extract_rbs_single_NB_IoT(int32_t                **rxdataF,
+                                     int32_t                **rxdataF_ext,
+                                     // uint32_t               first_rb, 
+                                     //uint32_t               UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block 
+                                     uint8_t                N_sc_RU, // number of subcarriers in UL
+				     uint32_t               I_sc, // subcarrier indication field
+                                     uint32_t               nb_rb,
+                                     uint8_t                l,
+                                     uint8_t                Ns,
+                                     NB_IoT_DL_FRAME_PARMS  *frame_parms);
+
+void extract_CQI_NB_IoT(void *o,UCI_format_NB_IoT_t uci_format,NB_IoT_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode);
+
+//*****************Vincent part for nprach ******************//
+void RX_NPRACH_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_buffer); 
+
+uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, 
+                              int16_t *Rx_sub_sampled_buffer, 
+                              uint16_t sub_sampling_rate, 
+                              uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES, 
+                              uint32_t estimated_TA_coarse, 
+                              char coarse); 
+
+uint8_t NPRACH_detection_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_sub_sampled_buffer, uint16_t sub_sampling_rate, uint32_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES); 
+
+int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate);
+//************************************************************//
+//*****************Vincent part for ULSCH demodulation ******************//
+uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc); 
+
+void generate_grouphop_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); 
+
+void init_ul_hopping_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); 
+
+void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, 
+                                  NB_IoT_DL_FRAME_PARMS *frame_parms,
+                                  int32_t **rxdataF_comp, 
+                                  uint8_t UE_id,
+                                  uint8_t symbol, 
+                                  uint8_t Qm); 
+
+void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, 
+                                  NB_IoT_DL_FRAME_PARMS *frame_parms,
+                                  int32_t **rxdataF_comp, 
+                                  uint8_t UE_id,
+                                  uint8_t symbol); 
+
+int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, 
+                              NB_IoT_DL_FRAME_PARMS *frame_parms,
+                              int32_t **rxdataF_comp,
+                              int16_t *ulsch_llr,
+                              uint8_t symbol, 
+                              uint8_t uint8_t, 
+                              int16_t **llrp); 
+
+
+int32_t ulsch_qpsk_llr_NB_IoT(
+                              NB_IoT_DL_FRAME_PARMS *frame_parms,
+                              int32_t **rxdataF_comp,
+                              int16_t *ulsch_llr, 
+                              uint8_t symbol, 
+                              uint8_t nb_rb, 
+                              int16_t **llrp); 
+
+void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, 
+                        NB_IoT_DL_FRAME_PARMS *frame_parms,
+                        int32_t **rxdataF_comp, 
+                        uint8_t UE_id,
+                        uint8_t symbol); 
+//************************************************************// 
+
+//************************************************************//
+//*****************Vincent part for DLSCH demodulation ******************//
+
+int rx_npdsch_NB_IoT(PHY_VARS_UE_NB_IoT *ue,
+                      unsigned char eNB_id,
+                      unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
+                      uint32_t frame,
+                      uint8_t subframe,
+                      unsigned char symbol,
+                      unsigned char first_symbol_flag,
+                      unsigned char i_mod,
+                      unsigned char harq_pid); 
+
+unsigned short dlsch_extract_rbs_single_NB_IoT(int **rxdataF,
+                                        int **dl_ch_estimates,
+                                        int **rxdataF_ext,
+                                        int **dl_ch_estimates_ext,
+                                        unsigned short pmi,
+                                        unsigned char *pmi_ext,
+                                        unsigned int *rb_alloc,
+                                        unsigned char symbol,
+                                        unsigned char subframe,
+                                        uint32_t frame,
+                                        uint32_t high_speed_flag,
+                                        NB_IoT_DL_FRAME_PARMS *frame_parms); 
+
+void dlsch_channel_level_NB_IoT(int **dl_ch_estimates_ext,
+                                NB_IoT_DL_FRAME_PARMS *frame_parms,
+                                int32_t *avg,
+                                uint8_t symbol,
+                                unsigned short nb_rb); 
+
+void dlsch_channel_compensation_NB_IoT(int **rxdataF_ext,
+                                        int **dl_ch_estimates_ext,
+                                        int **dl_ch_mag,
+                                        int **dl_ch_magb,
+                                        int **rxdataF_comp,
+                                        int **rho,
+                                        NB_IoT_DL_FRAME_PARMS *frame_parms,
+                                        unsigned char symbol,
+                                        uint8_t first_symbol_flag,
+                                        unsigned char mod_order,
+                                        unsigned short nb_rb,
+                                        unsigned char output_shift,
+                                        PHY_MEASUREMENTS_NB_IoT *measurements); 
+
+int dlsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
+                           int32_t **rxdataF_comp,
+                           int16_t *dlsch_llr,
+                           uint8_t symbol,
+                           uint8_t first_symbol_flag,
+                           uint16_t nb_rb,
+                           int16_t **llr32p,
+                           uint8_t beamforming_mode); 
+
+//************************************************************//
+
+
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..b20635360d0b977b497fb60a7dab4ca76489901b
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h
@@ -0,0 +1,324 @@
+/*
+ * 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
+ */
+
+#ifndef __UCI_NB_IOT__H__
+#define __UCI_NB_IOT__H__
+//#include "PHY/types_NB_IoT.h"
+
+
+
+typedef enum {
+  ue_selected_NB_IoT,
+  wideband_cqi_rank1_2A_NB_IoT, //wideband_cqi_rank1_2A,
+  wideband_cqi_rank2_2A_NB_IoT, //wideband_cqi_rank2_2A,
+  HLC_subband_cqi_nopmi_NB_IoT, //HLC_subband_cqi_nopmi,
+  HLC_subband_cqi_rank1_2A_NB_IoT, //HLC_subband_cqi_rank1_2A,
+  HLC_subband_cqi_rank2_2A_NB_IoT, //HLC_subband_cqi_rank2_2A,
+  HLC_subband_cqi_modes123_NB_IoT, //HLC_subband_cqi_modes123
+  HLC_subband_cqi_mcs_CBA_NB_IoT, // MCS and RNTI, for contention-based acces
+  unknown_cqi_NB_IoT//
+} UCI_format_NB_IoT_t;
+
+// **********************************************1.5 MHz***************************************************************************
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:16;
+  uint32_t pmi:12;
+  uint32_t cqi1:4;
+}
+wideband_cqi_rank1_2A_1_5MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank1_2A_1_5MHz_NB_IoT 16
+
+typedef struct __attribute__((packed))
+{
+  uint16_t padding:2;
+  uint16_t pmi:6;
+  uint16_t cqi2:4;
+  uint16_t cqi1:4;
+}
+wideband_cqi_rank2_2A_1_5MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank2_2A_1_5MHz_NB_IoT 14
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:16;
+  uint32_t diffcqi1:12;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_nopmi_1_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_nopmi_1_5MHz_NB_IoT 16
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:14;
+  uint32_t pmi:2;
+  uint32_t diffcqi1:12;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT 18
+
+typedef struct __attribute__((packed))
+{
+  uint64_t padding:31;
+  uint64_t pmi:1;
+  uint64_t diffcqi2:12;
+  uint64_t cqi2:4;
+  uint64_t diffcqi1:12;
+  uint64_t cqi1:4;
+}
+HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT 33
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:16;
+  uint32_t diffcqi1:12;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_modes123_1_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_modes123_1_5MHz_NB_IoT 16
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:11;
+  uint32_t crnti:16;
+  uint32_t mcs:5;
+}
+HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT 21
+
+
+// **********************************************5 MHz***************************************************************************
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:14;
+  uint32_t pmi:14;
+  uint32_t cqi1:4;
+}
+wideband_cqi_rank1_2A_5MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank1_2A_5MHz_NB_IoT 18
+
+typedef struct __attribute__((packed))
+{
+  uint16_t padding:1;
+  uint16_t pmi:7;
+  uint16_t cqi2:4;
+  uint16_t cqi1:4;
+}
+wideband_cqi_rank2_2A_5MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank2_2A_5MHz_NB_IoT 15
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:14;
+  uint32_t diffcqi1:14;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_nopmi_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_nopmi_5MHz_NB_IoT 18
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:12;
+  uint32_t pmi:2;
+  uint32_t diffcqi1:14;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_rank1_2A_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank1_2A_5MHz_NB_IoT 20
+
+typedef struct __attribute__((packed))
+{
+  uint64_t padding:27;
+  uint64_t pmi:1;
+  uint64_t diffcqi2:14;
+  uint64_t cqi2:4;
+  uint64_t diffcqi1:14;
+  uint64_t cqi1:4;
+}
+HLC_subband_cqi_rank2_2A_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank2_2A_5MHz_NB_IoT 37
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:14;
+  uint32_t diffcqi1:14;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_modes123_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_modes123_5MHz_NB_IoT 18
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:11;
+  uint32_t crnti:16;
+  uint32_t mcs:5;
+}
+HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT 21
+
+// **********************************************10 MHz***************************************************************************
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:10;
+  uint32_t pmi:18;
+  uint32_t cqi1:4;
+}
+wideband_cqi_rank1_2A_10MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank1_2A_10MHz_NB_IoT 22
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:15;
+  uint32_t pmi:9;
+  uint32_t cqi2:4;
+  uint32_t cqi1:4;
+}
+wideband_cqi_rank2_2A_10MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank2_2A_10MHz_NB_IoT 17
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:10;
+  uint32_t diffcqi1:18;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_nopmi_10MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_nopmi_10MHz_NB_IoT 22
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:8;
+  uint32_t pmi:2;
+  uint32_t diffcqi1:18;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_rank1_2A_10MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank1_2A_10MHz_NB_IoT 24
+
+typedef struct __attribute__((packed))
+{
+  uint64_t padding:19;
+  uint64_t pmi:1;
+  uint64_t diffcqi2:18;
+  uint64_t cqi2:4;
+  uint64_t diffcqi1:18;
+  uint64_t cqi1:4;
+}
+HLC_subband_cqi_rank2_2A_10MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank2_2A_10MHz_NB_IoT 45
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:10;
+  uint32_t diffcqi1:18;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_modes123_10MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_modes123_10MHz_NB_IoT 22
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:11;
+  uint32_t crnti:16;
+  uint32_t mcs:5;
+}
+HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT 21
+
+// **********************************************20 MHz***************************************************************************
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:2;
+  uint32_t pmi:26;
+  uint32_t cqi1:4;
+}
+wideband_cqi_rank1_2A_20MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank1_2A_20MHz_NB_IoT 20
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:11;
+  uint32_t pmi:13;
+  uint32_t cqi2:4;
+  uint32_t cqi1:4;
+}
+wideband_cqi_rank2_2A_20MHz_NB_IoT ;
+#define sizeof_wideband_cqi_rank2_2A_20MHz_NB_IoT 21
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:2;
+  uint32_t diffcqi1:26;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_nopmi_20MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_nopmi_20MHz_NB_IoT 30
+
+typedef struct __attribute__((packed))
+{
+  //  uint32_t padding:12;
+  uint32_t pmi:2;
+  uint32_t diffcqi1:26;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_rank1_2A_20MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank1_2A_20MHz_NB_IoT 32
+
+typedef struct __attribute__((packed))
+{
+  uint64_t padding:3;
+  uint64_t pmi:1;
+  uint64_t diffcqi2:26;
+  uint64_t cqi2:4;
+  uint64_t diffcqi1:26;
+  uint64_t cqi1:4;
+}
+HLC_subband_cqi_rank2_2A_20MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_rank2_2A_20MHz_NB_IoT 61
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:2;
+  uint32_t diffcqi1:26;
+  uint32_t cqi1:4;
+}
+HLC_subband_cqi_modes123_20MHz_NB_IoT;
+#define sizeof_HLC_subband_cqi_modes123_20MHz_NB_IoT 30
+
+typedef struct __attribute__((packed))
+{
+  uint32_t padding:11;
+  uint32_t crnti:16;
+  uint32_t mcs:5;
+}
+HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT;
+
+#define sizeof_HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT 21
+
+#define MAX_CQI_PAYLOAD_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8*20)
+#define MAX_CQI_BITS_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8)
+#define MAX_CQI_BYTES_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT))
+#define MAX_ACK_PAYLOAD_NB_IoT 18
+#define MAX_RI_PAYLOAD_NB_IoT 6
+
+#endif
\ No newline at end of file
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index 1b6c1c91532f94b4d188fc5f2de3d623992a099b..eb86af916597fe0869af11ada340788751f301be 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -162,7 +162,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   int16_t **chest_t;
   int16_t **chest_f;
   int16_t *pusch_llr;
-  int16_t *pusch_comp;
+  int32_t *pusch_comp;
   int32_t *pucch1_comp;
   int32_t *pucch1_thres;
   int32_t *pucch1ab_comp;
@@ -200,7 +200,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates[eNB_id];
   chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id];
   pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr;
-  pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0];
+  pusch_comp = (int32_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0];
   pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id];
   pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id];
   pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id];
diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9368b76e350fb6061c21987f0e52fd5fa65bfb2
--- /dev/null
+++ b/openair1/PHY/defs_L1_NB_IoT.h
@@ -0,0 +1,1031 @@
+/*
+ * 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/defs.h
+ \brief Top-level defines and structure definitions
+ \author R. Knopp, F. Kaltenberger
+ \date 2011
+ \version 0.1
+ \company Eurecom
+ \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
+ \note
+ \warning
+*/
+#ifndef __PHY_DEFS_NB_IOT__H__
+#define __PHY_DEFS_NB_IOT__H__
+
+#define _GNU_SOURCE 
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include <math.h>
+#include "common_lib.h"
+#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
+
+//#include <complex.h>
+#include "assertions.h"
+#ifdef MEX
+# define msg mexPrintf
+#else
+# ifdef OPENAIR2
+#   if ENABLE_RAL
+#     include "collection/hashtable/hashtable.h"
+#     include "COMMON/ral_messages_types.h"
+#     include "UTIL/queue.h"
+#   endif
+#   include "log.h"
+#   define msg(aRGS...) LOG_D(PHY, ##aRGS)
+# else
+#   define msg printf
+# endif
+#endif
+//use msg in the real-time thread context
+#define msg_nrt printf
+//use msg_nrt in the non real-time context (for initialization, ...)
+#ifndef malloc16
+#  ifdef __AVX2__
+#    define malloc16(x) memalign(32,x)
+#  else
+#    define malloc16(x) memalign(16,x)
+#  endif
+#endif
+#define free16(y,x) free(y)
+#define bigmalloc malloc
+#define bigmalloc16 malloc16
+#define openair_free(y,x) free((y))
+#define PAGE_SIZE 4096
+
+//#ifdef SHRLIBDEV
+//extern int rxrescale;
+//#define RX_IQRESCALELEN rxrescale
+//#else
+//#define RX_IQRESCALELEN 15
+//#endif
+
+//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards.
+//! If no more memory is available, this function will terminate the program with an assertion error.
+//******************************************************************************************************
+/*
+static inline void* malloc16_clear( size_t size )
+{
+#ifdef __AVX2__
+  void* ptr = memalign(32, size);
+#else
+  void* ptr = memalign(16, size);
+#endif
+  DevAssert(ptr);
+  memset( ptr, 0, size );
+  return ptr;
+}
+
+*/
+
+
+// #define PAGE_MASK 0xfffff000
+// #define virt_to_phys(x) (x)
+
+// #define openair_sched_exit() exit(-1)
+
+
+// #define max(a,b)  ((a)>(b) ? (a) : (b))
+// #define min(a,b)  ((a)<(b) ? (a) : (b))
+
+
+// #define bzero(s,n) (memset((s),0,(n)))
+
+// #define cmax(a,b)  ((a>b) ? (a) : (b))
+// #define cmin(a,b)  ((a<b) ? (a) : (b))
+
+// #define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c))
+
+// /// suppress compiler warning for unused arguments
+// #define UNUSED(x) (void)x;
+
+
+#include "PHY/impl_defs_top_NB_IoT.h"
+//#include "impl_defs_top.h"
+//#include "impl_defs_lte.h"
+#include "PHY/impl_defs_lte_NB_IoT.h"
+
+#include "PHY/TOOLS/time_meas.h"
+//#include "PHY/CODING/defs.h"
+#include "PHY/CODING/defs_NB_IoT.h"
+#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
+//#include "PHY/TOOLS/defs.h"
+//#include "platform_types.h"
+///#include "openair1/PHY/LTE_TRANSPORT/defs_nb_iot.h"
+
+////////////////////////////////////////////////////////////////////#ifdef OPENAIR_LTE    (check if this is required)
+
+//#include "PHY/LTE_TRANSPORT/defs.h"
+#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
+#include <pthread.h>
+
+#include "targets/ARCH/COMMON/common_lib.h"
+#include "targets/COMMON/openairinterface5g_limits.h"
+
+#define NUM_DCI_MAX_NB_IoT 32
+
+#define NUMBER_OF_eNB_SECTORS_MAX_NB_IoT 3
+
+#define NB_BANDS_MAX_NB_IoT 8
+
+
+#ifdef OCP_FRAMEWORK
+#include <enums.h>
+#else
+typedef enum {normal_txrx_NB_IoT=0,rx_calib_ue_NB_IoT=1,rx_calib_ue_med_NB_IoT=2,rx_calib_ue_byp_NB_IoT=3,debug_prach_NB_IoT=4,no_L2_connect_NB_IoT=5,calib_prach_tx_NB_IoT=6,rx_dump_frame_NB_IoT=7,loop_through_memory_NB_IoT=8} runmode_NB_IoT_t;
+#endif
+/*
+enum transmission_access_mode {
+  NO_ACCESS=0,
+  POSTPONED_ACCESS,
+  CANCELED_ACCESS,
+  UNKNOWN_ACCESS,
+  SCHEDULED_ACCESS,
+  CBA_ACCESS};
+
+typedef enum  {
+  eNodeB_3GPP=0,   // classical eNodeB function
+  eNodeB_3GPP_BBU, // eNodeB with NGFI IF5
+  NGFI_RCC_IF4p5,  // NGFI_RCC (NGFI radio cloud center)
+  NGFI_RAU_IF4p5,
+  NGFI_RRU_IF5,    // NGFI_RRU (NGFI remote radio-unit,IF5)
+  NGFI_RRU_IF4p5   // NGFI_RRU (NGFI remote radio-unit,IF4p5)
+} eNB_func_t;
+
+typedef enum {
+  synch_to_ext_device=0,  // synch to RF or Ethernet device
+  synch_to_other          // synch to another source (timer, other CC_id)
+} eNB_timing_t;
+#endif
+*/
+typedef struct UE_SCAN_INFO_NB_IoT_s {
+  /// 10 best amplitudes (linear) for each pss signals
+  int32_t             amp[3][10];
+  /// 10 frequency offsets (kHz) corresponding to best amplitudes, with respect do minimum DL frequency in the band
+  int32_t             freq_offset_Hz[3][10];
+
+} UE_SCAN_INFO_NB_IoT_t;
+
+/// Top-level PHY Data Structure for RN
+typedef struct {
+  /// Module ID indicator for this instance
+  uint8_t             Mod_id;
+  uint32_t            frame;
+  // phy_vars_eNB_NB_IoT
+  // phy_vars ue
+  // cuurently only used to store and forward the PMCH
+  uint8_t             mch_avtive[10];
+  uint8_t             sync_area[10]; // num SF
+  NB_IoT_UE_DLSCH_t   *dlsch_rn_MCH[10];
+
+} PHY_VARS_RN_NB_IoT;
+/*
+#ifdef OCP_FRAMEWORK
+#include <enums.h>
+#else
+//typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5,calib_prach_tx=6,rx_dump_frame=7,loop_through_memory=8} runmode_t;
+*/
+// enum transmission_access_mode {
+//   NO_ACCESS=0,
+//   POSTPONED_ACCESS,
+//   CANCELED_ACCESS,
+//   UNKNOWN_ACCESS,
+//   SCHEDULED_ACCESS,
+//   CBA_ACCESS};
+
+typedef enum  {
+  eNodeB_3GPP_NB_IoT=0,   // classical eNodeB function
+  eNodeB_3GPP_BBU_NB_IoT, // eNodeB with NGFI IF5
+  NGFI_RCC_IF4p5_NB_IoT,  // NGFI_RCC (NGFI radio cloud center)
+  NGFI_RAU_IF4p5_NB_IoT,
+  NGFI_RRU_IF5_NB_IoT,    // NGFI_RRU (NGFI remote radio-unit,IF5)
+  NGFI_RRU_IF4p5_NB_IoT   // NGFI_RRU (NGFI remote radio-unit,IF4p5)
+} eNB_func_NB_IoT_t;
+
+typedef enum {
+
+  synch_to_ext_device_NB_IoT=0,  // synch to RF or Ethernet device
+  synch_to_other_NB_IoT          // synch to another source (timer, other CC_id)
+
+} eNB_timing_NB_IoT_t;
+////////////////////////////////////////////////////////////////////#endif
+
+
+typedef struct {
+
+  struct                        PHY_VARS_eNB_NB_IoT_s       *eNB;
+  NB_IoT_eNB_NDLSCH_t           *dlsch;
+  int                           G;
+
+} te_params_NB_IoT;
+
+
+typedef struct {
+
+  struct                        PHY_VARS_eNB_NB_IoT_s       *eNB;
+  int                           UE_id;
+  int                           harq_pid;
+  int                           llr8_flag;
+  int                           ret;
+
+} td_params_NB_IoT;
+
+
+/// Context data structure for RX/TX portion of subframe processing
+typedef struct {
+  /// timestamp transmitted to HW
+  openair0_timestamp    timestamp_tx;
+  /// subframe to act upon for transmission
+  int                   subframe_tx;
+  /// subframe to act upon for reception
+  int                   subframe_rx;
+  /// frame to act upon for transmission
+  int                   frame_tx;
+  /// frame to act upon for reception
+  int                   frame_rx;
+  /// \brief Instance count for RXn-TXnp4 processing thread.
+  /// \internal This variable is protected by \ref mutex_rxtx.
+  int                   instance_cnt_rxtx;
+  /// pthread structure for RXn-TXnp4 processing thread
+  pthread_t             pthread_rxtx;
+  /// pthread attributes for RXn-TXnp4 processing thread
+  pthread_attr_t        attr_rxtx;
+  /// condition variable for tx processing thread
+  pthread_cond_t        cond_rxtx;
+  /// mutex for RXn-TXnp4 processing thread
+  pthread_mutex_t       mutex_rxtx;
+  /// scheduling parameters for RXn-TXnp4 thread
+  struct                sched_param sched_param_rxtx;
+  /// NB-IoT for IF_Module
+  pthread_t             pthread_l2;
+  pthread_cond_t        cond_l2;
+  pthread_mutex_t       mutex_l2;
+  int                   instance_cnt_l2;
+  pthread_attr_t        attr_l2;
+
+} eNB_rxtx_proc_NB_IoT_t;
+/*
+typedef struct {
+  struct PHY_VARS_eNB_NB_IoT_s *eNB;
+  int UE_id;
+  int harq_pid;
+  int llr8_flag;
+  int ret;
+} td_params;
+
+typedef struct {
+  struct PHY_VARS_eNB_NB_IoT_s *eNB;
+  LTE_eNB_DLSCH_t *dlsch;
+  int G;
+} te_params;
+*/
+
+/// Context data structure for eNB subframe processing
+typedef struct eNB_proc_NB_IoT_t_s {
+  /// thread index
+  int                     thread_index;
+  /// timestamp received from HW
+  openair0_timestamp      timestamp_rx;
+  /// timestamp to send to "slave rru"
+  openair0_timestamp      timestamp_tx;
+  /// subframe to act upon for reception
+  int                     subframe_rx;
+  /// symbol mask for IF4p5 reception per subframe
+  uint32_t                symbol_mask[10];
+  /// subframe to act upon for PRACH
+  int                     subframe_prach;
+  /// frame to act upon for reception
+  int                     frame_rx;
+  /// frame to act upon for transmission
+  int                     frame_tx;
+  /// frame offset for secondary eNBs (to correct for frame asynchronism at startup)
+  int                     frame_offset;
+  /// frame to act upon for PRACH
+  int                     frame_prach;
+  /// \internal This variable is protected by \ref mutex_fep.
+  int                     instance_cnt_fep;
+  /// \internal This variable is protected by \ref mutex_td.
+  int                     instance_cnt_td;
+  /// \internal This variable is protected by \ref mutex_te.
+  int                     instance_cnt_te;
+  /// \brief Instance count for FH processing thread.
+  /// \internal This variable is protected by \ref mutex_FH.
+  int                     instance_cnt_FH;
+  /// \brief Instance count for rx processing thread.
+  /// \internal This variable is protected by \ref mutex_prach.
+  int                     instance_cnt_prach;
+  // instance count for over-the-air eNB synchronization
+  int                     instance_cnt_synch;
+  /// \internal This variable is protected by \ref mutex_asynch_rxtx.
+  int                     instance_cnt_asynch_rxtx;
+  /// pthread structure for FH processing thread
+  pthread_t               pthread_FH;
+  /// pthread structure for eNB single processing thread
+  pthread_t               pthread_single;
+  /// pthread structure for asychronous RX/TX processing thread
+  pthread_t               pthread_asynch_rxtx;
+  /// flag to indicate first RX acquisition
+  int                     first_rx;
+  /// flag to indicate first TX transmission
+  int                     first_tx;
+  /// pthread attributes for parallel fep thread
+  pthread_attr_t          attr_fep;
+  /// pthread attributes for parallel turbo-decoder thread
+  pthread_attr_t          attr_td;
+  /// pthread attributes for parallel turbo-encoder thread
+  pthread_attr_t          attr_te;
+  /// pthread attributes for FH processing thread
+  pthread_attr_t          attr_FH;
+  /// pthread attributes for single eNB processing thread
+  pthread_attr_t          attr_single;
+  /// pthread attributes for prach processing thread
+  pthread_attr_t          attr_prach;
+  /// pthread attributes for over-the-air synch thread
+  pthread_attr_t          attr_synch;
+  /// pthread attributes for asynchronous RX thread
+  pthread_attr_t          attr_asynch_rxtx;
+  /// scheduling parameters for parallel fep thread
+  struct                  sched_param sched_param_fep;
+  /// scheduling parameters for parallel turbo-decoder thread
+  struct                  sched_param sched_param_td;
+  /// scheduling parameters for parallel turbo-encoder thread
+  struct                  sched_param sched_param_te;
+  /// scheduling parameters for FH thread
+  struct                  sched_param sched_param_FH;
+  /// scheduling parameters for single eNB thread
+  struct                  sched_param sched_param_single;
+  /// scheduling parameters for prach thread
+  struct                  sched_param sched_param_prach;
+  /// scheduling parameters for over-the-air synchronization thread
+  struct                  sched_param sched_param_synch;
+  /// scheduling parameters for asynch_rxtx thread
+  struct                  sched_param sched_param_asynch_rxtx;
+  /// pthread structure for parallel fep thread
+  pthread_t               pthread_fep;
+  /// pthread structure for parallel turbo-decoder thread
+  pthread_t               pthread_td;
+  /// pthread structure for parallel turbo-encoder thread
+  pthread_t               pthread_te;
+  /// pthread structure for PRACH thread
+  pthread_t               pthread_prach;
+  /// pthread structure for eNB synch thread
+  pthread_t               pthread_synch;
+  /// condition variable for parallel fep thread
+  pthread_cond_t          cond_fep;
+  /// condition variable for parallel turbo-decoder thread
+  pthread_cond_t          cond_td;
+  /// condition variable for parallel turbo-encoder thread
+  pthread_cond_t          cond_te;
+  /// condition variable for FH thread
+  pthread_cond_t          cond_FH;
+  /// condition variable for PRACH processing thread;
+  pthread_cond_t          cond_prach;
+  // condition variable for over-the-air eNB synchronization
+  pthread_cond_t          cond_synch;
+  /// condition variable for asynch RX/TX thread
+  pthread_cond_t          cond_asynch_rxtx;
+  /// mutex for RU access to  processing (NPDSCH/PUSCH)
+  pthread_mutex_t mutex_RU;
+  /// mutex for parallel fep thread
+  pthread_mutex_t         mutex_fep;
+  /// mutex for parallel turbo-decoder thread
+  pthread_mutex_t         mutex_td;
+  /// mutex for parallel turbo-encoder thread
+  pthread_mutex_t         mutex_te;
+  /// mutex for FH
+  pthread_mutex_t         mutex_FH;
+  /// mutex for PRACH thread
+  pthread_mutex_t         mutex_prach;
+  // mutex for over-the-air eNB synchronization
+  pthread_mutex_t         mutex_synch;
+  /// mutex for RU access to NB-IoT processing (NPRACH)
+  pthread_mutex_t mutex_RU_PRACH;
+  /// mutex for asynch RX/TX thread
+  pthread_mutex_t         mutex_asynch_rxtx;
+  /// mask for RUs serving nbiot  (NPDSCH/NPUSCH)
+  int RU_mask;
+  /// mask for RUs serving nbiot (PRACH)
+  int RU_mask_prach;
+#ifdef Rel14
+  /// mask for RUs serving eNB (PRACH)
+  int RU_mask_prach_br;
+#endif
+  /// parameters for turbo-decoding worker thread
+  td_params_NB_IoT        tdp;
+  /// parameters for turbo-encoding worker thread
+  te_params_NB_IoT        tep;
+  /// number of slave threads
+  int                     num_slaves;
+  /// array of pointers to slaves
+  struct                  eNB_proc_NB_IoT_t_s           **slave_proc;
+  /// set of scheduling variables RXn-TXnp4 threads
+  // newly added for NB_IoT
+  eNB_rxtx_proc_NB_IoT_t  proc_rxtx[2];
+
+} eNB_proc_NB_IoT_t;
+
+
+/// Context data structure for RX/TX portion of subframe processing
+typedef struct {
+  /// index of the current UE RX/TX proc
+  int                   proc_id;
+  /// timestamp transmitted to HW
+  openair0_timestamp    timestamp_tx;
+  /// subframe to act upon for transmission
+  int                   subframe_tx;
+  /// subframe to act upon for reception
+  int                   subframe_rx;
+  /// frame to act upon for transmission
+  int                   frame_tx;
+  /// frame to act upon for reception
+  int                   frame_rx;
+  /// \brief Instance count for RXn-TXnp4 processing thread.
+  /// \internal This variable is protected by \ref mutex_rxtx.
+  int                   instance_cnt_rxtx;
+  /// pthread structure for RXn-TXnp4 processing thread
+  pthread_t             pthread_rxtx;
+  /// pthread attributes for RXn-TXnp4 processing thread
+  pthread_attr_t        attr_rxtx;
+  /// condition variable for tx processing thread
+  pthread_cond_t        cond_rxtx;
+  /// mutex for RXn-TXnp4 processing thread
+  pthread_mutex_t       mutex_rxtx;
+  /// scheduling parameters for RXn-TXnp4 thread
+  struct                sched_param sched_param_rxtx;
+  /// 
+  int                   sub_frame_start;
+  ///
+  int                   sub_frame_step;
+  ///
+  unsigned long long    gotIQs;
+
+} UE_rxtx_proc_NB_IoT_t;
+
+/// Context data structure for eNB subframe processing
+typedef struct {
+  /// Last RX timestamp
+  openair0_timestamp      timestamp_rx;
+  /// pthread attributes for main UE thread
+  pthread_attr_t          attr_ue;
+  /// scheduling parameters for main UE thread
+  struct                  sched_param sched_param_ue;
+  /// pthread descriptor main UE thread
+  pthread_t               pthread_ue;
+  /// \brief Instance count for synch thread.
+  /// \internal This variable is protected by \ref mutex_synch.
+  int                     instance_cnt_synch;
+  /// pthread attributes for synch processing thread
+  pthread_attr_t          attr_synch;
+  /// scheduling parameters for synch thread
+  struct                  sched_param sched_param_synch;
+  /// pthread descriptor synch thread
+  pthread_t               pthread_synch;
+  /// condition variable for UE synch thread;
+  pthread_cond_t          cond_synch;
+  /// mutex for UE synch thread
+  pthread_mutex_t         mutex_synch;
+  /// set of scheduling variables RXn-TXnp4 threads
+  UE_rxtx_proc_NB_IoT_t   proc_rxtx[2];
+
+} UE_proc_NB_IoT_t;
+
+
+
+/// Top-level PHY Data Structure for eNB
+typedef struct PHY_VARS_eNB_NB_IoT_s {
+  /// Module ID indicator for this instance
+  module_id_t                   Mod_id;
+  uint8_t                       configured;
+  eNB_proc_NB_IoT_t             proc;
+  int                           num_RU;
+  RU_t                          *RU_list[MAX_NUM_RU_PER_eNB];
+  /// Ethernet parameters for northbound midhaul interface (L1 to Mac)
+  eth_params_t         eth_params_n;
+  /// Ethernet parameters for fronthaul interface (upper L1 to Radio head)
+  eth_params_t         eth_params;
+  int                           single_thread_flag;
+  openair0_rf_map               rf_map;
+  int                           abstraction_flag;
+  openair0_timestamp            ts_offset;
+  // indicator for synchronization state of eNB
+  int                           in_synch;
+  // indicator for master/slave (RRU)
+  int                           is_slave;
+  // indicator for precoding function (eNB,3GPP_eNB_BBU)
+  int                           do_precoding;
+  IF_Module_NB_IoT_t            *if_inst_NB_IoT;
+  UL_IND_NB_IoT_t               UL_INFO_NB_IoT;
+  pthread_mutex_t               UL_INFO_mutex;
+  void                          (*do_prach)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int frame,int subframe);
+  void                          (*fep)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc);
+  int                           (*td)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int UE_id,int harq_pid,int llr8_flag);
+  int                           (*te)(struct PHY_VARS_eNB_NB_IoT_s *,uint8_t *,uint8_t,NB_IoT_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *);
+  void                          (*proc_uespec_rx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,const relaying_type_t_NB_IoT r_type);
+  void                          (*proc_tx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,relaying_type_t_NB_IoT r_type,PHY_VARS_RN_NB_IoT *rn);
+  void                          (*tx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc);
+  void                          (*rx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe);
+  int                           (*start_rf)(struct PHY_VARS_eNB_NB_IoT_s *eNB);
+  int                           (*start_if)(struct PHY_VARS_eNB_NB_IoT_s *eNB);
+  void                          (*fh_asynch)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe);
+  uint8_t                       local_flag;
+  uint32_t                      rx_total_gain_dB;
+  NB_IoT_DL_FRAME_PARMS         frame_parms;
+  PHY_MEASUREMENTS_eNB_NB_IoT   measurements[NUMBER_OF_eNB_SECTORS_MAX_NB_IoT]; /// Measurement variables
+  NB_IoT_eNB_COMMON             common_vars;
+  NB_IoT_eNB_SRS                srs_vars[NUMBER_OF_UE_MAX_NB_IoT];
+  NB_IoT_eNB_PBCH               pbch;
+  NB_IoT_eNB_PUSCH              *pusch_vars[NUMBER_OF_UE_MAX_NB_IoT];
+  NB_IoT_eNB_PRACH              prach_vars;
+  //LTE_eNB_DLSCH_t             *dlsch[NUMBER_OF_UE_MAX_NB_IoT][2];             // Nusers times two spatial streams
+  NB_IoT_eNB_NULSCH_t            *ulsch[NUMBER_OF_UE_MAX_NB_IoT+1];              // Nusers + number of RA (the ulsch[0] contains RAR)
+  //LTE_eNB_DLSCH_t             *dlsch_SI,*dlsch_ra;
+  //LTE_eNB_DLSCH_t             *dlsch_MCH;
+  NB_IoT_eNB_UE_stats           UE_stats[NUMBER_OF_UE_MAX_NB_IoT];
+  //LTE_eNB_UE_stats            *UE_stats_ptr[NUMBER_OF_UE_MAX_NB_IoT];
+  /// cell-specific reference symbols
+  uint32_t                      lte_gold_table_NB_IoT[20][2][14];
+  /// UE-specific reference symbols (p=5), TM 7
+  uint32_t                      lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX_NB_IoT][20][38];
+  /// UE-specific reference symbols (p=7...14), TM 8/9/10
+  uint32_t                      lte_gold_uespec_table[2][20][2][21];
+  /// mbsfn reference symbols
+  uint32_t                      lte_gold_mbsfn_table[10][3][42];
+  ///
+  uint32_t                      X_u[64][839];
+  ///
+  uint8_t                       pbch_pdu[4];                                      //PBCH_PDU_SIZE
+  ///
+  char                          eNB_generate_rar;
+  /// Indicator set to 0 after first SR
+  uint8_t                       first_sr[NUMBER_OF_UE_MAX_NB_IoT];
+
+  uint32_t                      max_peak_val;
+  ///
+  int                           max_eNB_id, max_sync_pos;
+  ///
+  int                           N_TA_offset;                        ///timing offset used in TDD
+  /// \brief sinr for all subcarriers of the current link (used only for abstraction).
+  /// first index: ? [0..N_RB_DL*12[
+  double                        *sinr_dB;
+  /// N0 (used for abstraction)
+  double                        N0;
+  ///
+  unsigned char                 first_run_timing_advance[NUMBER_OF_UE_MAX_NB_IoT];
+  unsigned char                 first_run_I0_measurements;
+
+  unsigned char                 cooperation_flag;                   // for cooperative communication
+
+  unsigned char                 is_secondary_eNB;                   // primary by default
+  unsigned char                 is_init_sync;                       /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system.
+  unsigned char                 has_valid_precoder;                 /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created.
+  unsigned char                 PeNB_id;                            /// id of Primary eNB
+  int                           rx_offset;                          /// Timing offset (used if is_secondary_eNB)
+
+  /// hold the precoder for NULL beam to the primary user
+  int                           **dl_precoder_SeNB[3];
+  ///
+  char                          log2_maxp;                          /// holds the maximum channel/precoder coefficient
+  /// if ==0 enables phy only test mode
+  int                           mac_enabled;
+  /// For emulation only (used by UE abstraction to retrieve DCI)
+  uint8_t                       num_common_dci[2];                  // num_dci in even/odd subframes
+  ///
+  uint8_t                       num_ue_spec_dci[2];                 // num_dci in even/odd subframes
+  ///
+  DCI_ALLOC_NB_IoT_t            dci_alloc[2][NUM_DCI_MAX_NB_IoT];   // dci_alloc from even/odd subframes
+  /////////////
+  // PDSCH Variables
+  PDSCH_CONFIG_DEDICATED_NB_IoT             pdsch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
+  // PUSCH Variables
+  PUSCH_CONFIG_DEDICATED_NB_IoT             pusch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
+  // PUCCH variables
+  PUCCH_CONFIG_DEDICATED_NB_IoT             pucch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
+  // UL-POWER-Control
+  UL_POWER_CONTROL_DEDICATED_NB_IoT         ul_power_control_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
+  // TPC
+  TPC_PDCCH_CONFIG_NB_IoT                   tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX_NB_IoT];
+  ///
+  TPC_PDCCH_CONFIG_NB_IoT                   tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX_NB_IoT];
+  // CQI reporting
+  CQI_REPORT_CONFIG_NB_IoT                  cqi_report_config[NUMBER_OF_UE_MAX_NB_IoT];
+  // SRS Variables
+  SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT     soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
+  ///
+  uint8_t                                   ncs_cell[20][7];
+  // Scheduling Request Config
+  SCHEDULING_REQUEST_CONFIG_NB_IoT          scheduling_request_config[NUMBER_OF_UE_MAX_NB_IoT];
+  // Transmission mode per UE
+  uint8_t                                   transmission_mode[NUMBER_OF_UE_MAX_NB_IoT];
+  /// cba_last successful reception for each group, used for collision detection
+  uint8_t                                   cba_last_reception[4];
+  // Pointers for active physicalConfigDedicated to be applied in current subframe
+  struct                                    PhysicalConfigDedicated                         *physicalConfigDedicated[NUMBER_OF_UE_MAX_NB_IoT];
+  //Pointers for actve physicalConfigDedicated for NB-IoT to be applied in current subframe
+  struct                                    PhysicalConfigDedicated_NB_r13                  *phy_config_dedicated_NB_IoT[NUMBER_OF_UE_MAX_NB_IoT];
+  ///
+  uint32_t                                  rb_mask_ul[4];
+  /// Information regarding TM5
+  MU_MIMO_mode_NB_IoT                       mu_mimo_mode[NUMBER_OF_UE_MAX_NB_IoT];
+  /// target_ue_dl_mcs : only for debug purposes
+  uint32_t                                  target_ue_dl_mcs;
+  /// target_ue_ul_mcs : only for debug purposes
+  uint32_t                                  target_ue_ul_mcs;
+  /// target_ue_dl_rballoc : only for debug purposes
+  uint32_t                                  ue_dl_rb_alloc;
+  /// target ul PRBs : only for debug
+  uint32_t                                  ue_ul_nb_rb;
+  ///check for Total Transmissions
+  uint32_t                                  check_for_total_transmissions;
+  ///check for MU-MIMO Transmissions
+  uint32_t                                  check_for_MUMIMO_transmissions;
+  ///check for SU-MIMO Transmissions
+  uint32_t                                  check_for_SUMIMO_transmissions;
+  ///check for FULL MU-MIMO Transmissions
+  uint32_t                                  FULL_MUMIMO_transmissions;
+  /// Counter for total bitrate, bits and throughput in downlink
+  uint32_t                                  total_dlsch_bitrate;
+  ///
+  uint32_t                                  total_transmitted_bits;
+  ///
+  uint32_t                                  total_system_throughput;
+  ///
+  int                                       hw_timing_advance;
+  ///
+  time_stats_t                       phy_proc;
+  time_stats_t                       phy_proc_tx;
+  time_stats_t                       phy_proc_rx;
+  time_stats_t                       rx_prach;
+
+  time_stats_t                       ofdm_mod_stats;
+  time_stats_t                       dlsch_encoding_stats;
+  time_stats_t                       dlsch_modulation_stats;
+  time_stats_t                       dlsch_scrambling_stats;
+  time_stats_t                       dlsch_rate_matching_stats;
+  time_stats_t                       dlsch_turbo_encoding_stats;
+  time_stats_t                       dlsch_interleaving_stats;
+
+  time_stats_t                       ofdm_demod_stats;
+  time_stats_t                       rx_dft_stats;
+  time_stats_t                       ulsch_channel_estimation_stats;
+  time_stats_t                       ulsch_freq_offset_estimation_stats;
+  time_stats_t                       ulsch_decoding_stats;
+  time_stats_t                       ulsch_demodulation_stats;
+  time_stats_t                       ulsch_rate_unmatching_stats;
+  time_stats_t                       ulsch_turbo_decoding_stats;
+  time_stats_t                       ulsch_deinterleaving_stats;
+  time_stats_t                       ulsch_demultiplexing_stats;
+  time_stats_t                       ulsch_llr_stats;
+  time_stats_t                       ulsch_tc_init_stats;
+  time_stats_t                       ulsch_tc_alpha_stats;
+  time_stats_t                       ulsch_tc_beta_stats;
+  time_stats_t                       ulsch_tc_gamma_stats;
+  time_stats_t                       ulsch_tc_ext_stats;
+  time_stats_t                       ulsch_tc_intl1_stats;
+  time_stats_t                       ulsch_tc_intl2_stats;
+
+  #ifdef LOCALIZATION
+  /// time state for localization
+  time_stats_t                       localization_stats;
+  #endif
+
+  int32_t                                   pucch1_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10];
+  int32_t                                   pucch1_stats[NUMBER_OF_UE_MAX_NB_IoT][10*1024];
+  int32_t                                   pucch1_stats_thres[NUMBER_OF_UE_MAX_NB_IoT][10*1024];
+  int32_t                                   pucch1ab_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10];
+  int32_t                                   pucch1ab_stats[NUMBER_OF_UE_MAX_NB_IoT][2*10*1024];
+  int32_t                                   pusch_stats_rb[NUMBER_OF_UE_MAX_NB_IoT][10240];
+  int32_t                                   pusch_stats_round[NUMBER_OF_UE_MAX_NB_IoT][10240];
+  int32_t                                   pusch_stats_mcs[NUMBER_OF_UE_MAX_NB_IoT][10240];
+  int32_t                                   pusch_stats_bsr[NUMBER_OF_UE_MAX_NB_IoT][10240];
+  int32_t                                   pusch_stats_BO[NUMBER_OF_UE_MAX_NB_IoT][10240];
+
+  /// RF and Interface devices per CC
+  openair0_device                           rfdevice;
+  openair0_device                           ifdevice;
+  /// Pointer for ifdevice buffer struct
+  if_buffer_t                               ifbuffer;
+
+  //------------------------
+  // NB-IoT
+  //------------------------
+
+  /*
+   * NUMBER_OF_UE_MAX_NB_IoT maybe in the future should be dynamic because could be very large and the memory may explode
+   * (is almost the indication of the number of UE context that we are storing at PHY layer)
+   *
+   * reasoning: the following data structure (ndlsch, nulsch ecc..) are used to store the context that should be transmitted in at least n+4 subframe later
+   * (the minimum interval between NPUSCH and the ACK for this)
+   * the problem is that in NB_IoT the ACK for the UPLINK is contained in the DCI through the NDI field (if this value change from the previous one then it means ACK)
+   * but may we could schedule this DCI long time later so may lots of contents shuld be stored (there is no concept of phich channel in NB-IoT)
+   * For the DL transmission the UE send a proper ACK/NACK message
+   *
+   * *the HARQ process should be killed when the NDI change
+   *
+   * *In the Structure for nulsch we should also store the information related to the subframe (because each time we should read it and understand what should be done
+   * in that subframe)
+   *
+   */
+
+
+  /*
+   * TIMING
+   * the entire transmission and scheduling are done for the "subframe" concept but the subframe = proc->subframe_tx (that in reality is the subframe_rx +4)
+   * (see USER/lte-enb/wakeup_rxtx )
+   *
+   * Related to FAPI:
+   * DCI and  DL_CONFIG.request (also more that 1) and MAC_PDU are transmitted in the same subframe (our assumption) so will be all contained in the schedule_response getting from the scheduler
+   * DCI0 and UL_CONFIG.request are transmitted in the same subframe (our assumption) so contained in the schedule_response
+   *
+   */
+
+  //TODO: check what should be NUMBER_OF_UE_MAX_NB_IoT value
+  NB_IoT_eNB_NPBCH_t        *npbch;
+  NB_IoT_eNB_NPDCCH_t       *npdcch[NUMBER_OF_UE_MAX_NB_IoT];
+  NB_IoT_eNB_NDLSCH_t       *ndlsch[NUMBER_OF_UE_MAX_NB_IoT][2];
+  NB_IoT_eNB_NULSCH_t       *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR
+  NB_IoT_eNB_NDLSCH_t       *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1;
+
+  NB_IoT_DL_FRAME_PARMS     frame_parms_NB_IoT;
+  // DCI for at most 2 DCI pdus
+  DCI_PDU_NB_IoT            *DCI_pdu;
+
+
+
+} PHY_VARS_eNB_NB_IoT;
+
+//#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg
+
+/// Top-level PHY Data Structure for UE
+typedef struct {
+  /// \brief Module ID indicator for this instance
+  uint8_t                       Mod_id;
+  /// \brief Mapping of CC_id antennas to cards
+  openair0_rf_map               rf_map;
+  //uint8_t local_flag;
+  /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach)
+  runmode_NB_IoT_t              mode;
+  /// \brief Indicator that UE should perform band scanning
+  int                           UE_scan;
+  /// \brief Indicator that UE should perform coarse scanning around carrier
+  int                           UE_scan_carrier;
+  /// \brief Indicator that UE is synchronized to an eNB
+  int                           is_synchronized;
+  /// Data structure for UE process scheduling
+  UE_proc_NB_IoT_t              proc;
+  /// Flag to indicate the UE shouldn't do timing correction at all
+  int                           no_timing_correction;
+  /// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna)
+  uint32_t                      tx_total_gain_dB;
+  /// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card.
+  uint32_t                      rx_total_gain_dB;
+  /// \brief Total gains with maximum RF gain stage (ExpressMIMO2/Lime)
+  uint32_t                      rx_gain_max[4];
+  /// \brief Total gains with medium RF gain stage (ExpressMIMO2/Lime)
+  uint32_t                      rx_gain_med[4];
+  /// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime)
+  uint32_t                      rx_gain_byp[4];
+  /// \brief Current transmit power
+  int16_t                       tx_power_dBm[10];
+  /// \brief Total number of REs in current transmission
+  int                           tx_total_RE[10];
+  /// \brief Maximum transmit power
+  int8_t                        tx_power_max_dBm;
+  /// \brief Number of eNB seen by UE
+  uint8_t                       n_connected_eNB;
+  /// \brief indicator that Handover procedure has been initiated
+  uint8_t                       ho_initiated;
+  /// \brief indicator that Handover procedure has been triggered
+  uint8_t                       ho_triggered;
+  /// \brief Measurement variables.
+  PHY_MEASUREMENTS_NB_IoT       measurements;
+  NB_IoT_DL_FRAME_PARMS         frame_parms;
+  /// \brief Frame parame before ho used to recover if ho fails.
+  NB_IoT_DL_FRAME_PARMS         frame_parms_before_ho;
+  NB_IoT_UE_COMMON              common_vars;
+
+  NB_IoT_UE_PDSCH     *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads
+  NB_IoT_UE_DLSCH_t   *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads
+  //Paging parameters
+  uint32_t                        IMSImod1024;
+  uint32_t                        PF;
+  uint32_t                        PO;
+  // For abstraction-purposes only
+  uint8_t                         sr[10];
+  uint8_t                         pucch_sel[10];
+  uint8_t                         pucch_payload[22];
+  //UE_MODE_t                     UE_mode[NUMBER_OF_CONNECTED_eNB_MAX];
+  //cell-specific reference symbols
+  uint32_t                        lte_gold_table[7][20][2][14];
+  //UE-specific reference symbols (p=5), TM 7
+  uint32_t                        lte_gold_uespec_port5_table[20][38];
+  //ue-specific reference symbols
+  uint32_t                        lte_gold_uespec_table[2][20][2][21];
+  //mbsfn reference symbols
+  uint32_t                        lte_gold_mbsfn_table[10][3][42];
+  ///
+  uint32_t                        X_u[64][839];
+  /// 
+  uint32_t                        high_speed_flag;
+  uint32_t                        perfect_ce;
+  int16_t                         ch_est_alpha;
+  int                             generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX];
+  ///
+  UE_SCAN_INFO_NB_IoT_t           scan_info[NB_BANDS_MAX_NB_IoT];
+  ///
+  char                            ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX];
+
+/*
+
+  unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX];
+  uint32_t  ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX];
+  unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX];
+  PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX];
+  int turbo_iterations, turbo_cntl_iterations;
+  /// \brief ?.
+  /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
+  uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX];
+  /// \brief ?.
+  /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
+  uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX];
+  /// \brief ?.
+  /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
+  uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX];
+  /// \brief ?.
+  /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
+  uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
+  int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
+  int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX];
+  unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX];
+  uint8_t               generate_prach;
+  uint8_t               prach_cnt;
+  uint8_t               prach_PreambleIndex;
+  //  uint8_t               prach_timer;
+  uint8_t               decode_SIB;
+  uint8_t               decode_MIB;
+  int              rx_offset; /// Timing offset
+  int              rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
+  int              timing_advance; ///timing advance signalled from eNB
+  int              hw_timing_advance;
+  int              N_TA_offset; ///timing offset used in TDD
+  /// Flag to tell if UE is secondary user (cognitive mode)
+  unsigned char    is_secondary_ue;
+  /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from.
+  unsigned char    has_valid_precoder;
+  /// hold the precoder for NULL beam to the primary eNB
+  int              **ul_precoder_S_UE;
+  /// holds the maximum channel/precoder coefficient
+  char             log2_maxp;
+*/
+  /// if ==0 enables phy only test mode
+  int              mac_enabled;
+  /// Flag to initialize averaging of PHY measurements
+  int              init_averaging;
+  /// \brief sinr for all subcarriers of the current link (used only for abstraction).
+  /// - first index: ? [0..12*N_RB_DL[
+  double           *sinr_dB;
+  /// \brief sinr for all subcarriers of first symbol for the CQI Calculation.
+  /// - first index: ? [0..12*N_RB_DL[
+  double           *sinr_CQI_dB;
+  /// sinr_effective used for CQI calulcation
+  double           sinr_eff;
+  /// N0 (used for abstraction)
+  double           N0;
+/*
+  /// PDSCH Varaibles
+  PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// PUSCH Varaibles
+  PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// PUSCH contention-based access vars
+  PUSCH_CA_CONFIG_DEDICATED  pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola
+
+  /// PUCCH variables
+
+  PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  uint8_t ncs_cell[20][7];
+
+  /// UL-POWER-Control
+  UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// TPC
+  TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX];
+  TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// CQI reporting
+  CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// SRS Variables
+  SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// Scheduling Request Config
+  SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// Transmission mode per eNB
+  uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  time_stats_t phy_proc;
+  time_stats_t phy_proc_tx;
+  time_stats_t phy_proc_rx[2];
+
+  uint32_t use_ia_receiver;
+
+  time_stats_t ofdm_mod_stats;
+  time_stats_t ulsch_encoding_stats;
+  time_stats_t ulsch_modulation_stats;
+  time_stats_t ulsch_segmentation_stats;
+  time_stats_t ulsch_rate_matching_stats;
+  time_stats_t ulsch_turbo_encoding_stats;
+  time_stats_t ulsch_interleaving_stats;
+  time_stats_t ulsch_multiplexing_stats;
+
+  time_stats_t generic_stat;
+  time_stats_t pdsch_procedures_stat;
+  time_stats_t dlsch_procedures_stat;
+
+  time_stats_t ofdm_demod_stats;
+  time_stats_t dlsch_rx_pdcch_stats;
+  time_stats_t rx_dft_stats;
+  time_stats_t dlsch_channel_estimation_stats;
+  time_stats_t dlsch_freq_offset_estimation_stats;
+  time_stats_t dlsch_decoding_stats[2];
+  time_stats_t dlsch_demodulation_stats;
+  time_stats_t dlsch_rate_unmatching_stats;
+  time_stats_t dlsch_turbo_decoding_stats;
+  time_stats_t dlsch_deinterleaving_stats;
+  time_stats_t dlsch_llr_stats;
+  time_stats_t dlsch_unscrambling_stats;
+  time_stats_t dlsch_rate_matching_stats;
+  time_stats_t dlsch_turbo_encoding_stats;
+  time_stats_t dlsch_interleaving_stats;
+  time_stats_t dlsch_tc_init_stats;
+  time_stats_t dlsch_tc_alpha_stats;
+  time_stats_t dlsch_tc_beta_stats;
+  time_stats_t dlsch_tc_gamma_stats;
+  time_stats_t dlsch_tc_ext_stats;
+  time_stats_t dlsch_tc_intl1_stats;
+  time_stats_t dlsch_tc_intl2_stats;
+  time_stats_t tx_prach;
+
+  /// RF and Interface devices per CC
+  openair0_device rfdevice;
+  time_stats_t dlsch_encoding_SIC_stats;
+  time_stats_t dlsch_scrambling_SIC_stats;
+  time_stats_t dlsch_modulation_SIC_stats;
+  time_stats_t dlsch_llr_stripping_unit_SIC_stats;
+  time_stats_t dlsch_unscrambling_SIC_stats;
+
+#if ENABLE_RAL
+  hash_table_t    *ral_thresholds_timed;
+  SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
+  SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
+#endif
+*/
+} PHY_VARS_UE_NB_IoT;
+
+
+
+#include "PHY/INIT/defs_NB_IoT.h"
+#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
+#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
+#endif //  __PHY_DEFS__H__
diff --git a/openair1/PHY/impl_defs_lte_NB_IoT.h b/openair1/PHY/impl_defs_lte_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ae6f59c7e8afc779c9c0726bdb271d769d819c9
--- /dev/null
+++ b/openair1/PHY/impl_defs_lte_NB_IoT.h
@@ -0,0 +1,813 @@
+/*
+ * 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/impl_defs_lte.h
+* \brief LTE Physical channel configuration and variable structure definitions
+* \author R. Knopp, F. Kaltenberger
+* \date 2011
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
+* \note
+* \warning
+*/
+
+#ifndef __PHY_IMPL_DEFS_NB_IOT__H__
+#define __PHY_IMPL_DEFS_NB_IOT__H__
+
+#include "types_NB_IoT.h"
+//#include "defs.h"
+
+typedef enum {TDD_NB_IoT=1,FDD_NB_IoT=0} NB_IoT_frame_type_t;
+typedef enum {EXTENDED_NB_IoT=1,NORMAL_NB_IoT=0} NB_IoT_prefix_type_t;
+typedef enum {SF_DL_NB_IoT, SF_UL_NB_IoT, SF_S_NB_IoT} NB_IoT_subframe_t;
+
+#define	A_SEQUENCE_OF(type)	A_SET_OF(type)
+
+#define	A_SET_OF(type)					\
+	struct {					\
+		type **array;				\
+		int count;	/* Meaningful size */	\
+		int size;	/* Allocated size */	\
+		void (*free)(type *);			\
+	}
+
+
+/////////////////////////
+  /// Union for \ref TPC_PDCCH_CONFIG::tpc_Index.
+typedef union {
+  /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]}
+  uint8_t indexOfFormat3;
+  /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]}
+  uint8_t indexOfFormat3A;
+} TPC_INDEX_NB_IoT_t;
+
+/// TPC-PDCCH-Config Information Element from 36.331 RRC spec
+typedef struct {
+  /// RNTI for power control using DCI format 3/3A, see TS 36.212. \vr{[0..65535]}
+  uint16_t rnti;
+  /// Index of N or M, see TS 36.212 (5.3.3.1.6 and 5.3.3.1.7), where N or M is dependent on the used DCI format (i.e. format 3 or 3a).
+  TPC_INDEX_NB_IoT_t tpc_Index;
+} TPC_PDCCH_CONFIG_NB_IoT;
+  /// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor.
+typedef enum {
+  //n2=0,
+  n4_n,
+  n6_n
+} ACKNAKREP_NB_IoT_t;
+
+/// Enumeration for \ref PUCCH_CONFIG_DEDICATED::tdd_AckNackFeedbackMode.
+typedef enum {
+  bundling_N=0,
+  multiplexing_N
+} ANFBmode_NB_IoT_t;
+
+/// PUCCH-ConfigDedicated from 36.331 RRC spec
+typedef struct {
+  /// Flag to indicate ACK NAK repetition activation, see TS 36.213 (10.1). \vr{[0..1]}
+  uint8_t ackNackRepetition;
+  /// Parameter: \f$N_\text{ANRep}\f$, see TS 36.213 (10.1).
+  ACKNAKREP_NB_IoT_t repetitionFactor;
+  /// Parameter: \f$n^{(1)}_\text{PUCCH,ANRep}\f$, see TS 36.213 (10.1). \vr{[0..2047]}
+  uint16_t n1PUCCH_AN_Rep;
+  /// Feedback mode, see TS 36.213 (7.3). \details Applied to both PUCCH and PUSCH feedback. For TDD, should always be set to bundling.
+  ANFBmode_NB_IoT_t tdd_AckNackFeedbackMode;
+} PUCCH_CONFIG_DEDICATED_NB_IoT;
+  // UE specific PUSCH configuration.
+typedef struct {
+  /// Parameter: \f$I^\text{HARQ-ACK}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-1). \vr{[0..15]}
+  uint16_t betaOffset_ACK_Index;
+  /// Parameter: \f$I^{RI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-2). \vr{[0..15]}
+  uint16_t betaOffset_RI_Index;
+  /// Parameter: \f$I^{CQI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-3). \vr{[0..15]}
+  uint16_t betaOffset_CQI_Index;
+} PUSCH_CONFIG_DEDICATED_NB_IoT;
+/// Enumeration for Parameter \f$P_A\f$ \ref PDSCH_CONFIG_DEDICATED::p_a.
+typedef enum {
+  //dBm6=0, ///< (dB-6) corresponds to -6 dB
+ // dBm477, ///< (dB-4dot77) corresponds to -4.77 dB
+ // dBm3,   ///< (dB-3) corresponds to -3 dB
+  //dBm177, ///< (dB-1dot77) corresponds to -1.77 dB
+  //dB0,    ///< corresponds to 0 dB
+ // dB1,    ///< corresponds to 1 dB
+  dB2_NB,    ///< corresponds to 2 dB
+  dB3_NB     ///< corresponds to 3 dB
+} PA_NB_IoT_t;
+
+/// PDSCH-ConfigDedicated from 36.331 RRC spec
+typedef struct {
+  /// Parameter: \f$P_A\f$, see TS 36.213 (5.2).
+  PA_NB_IoT_t p_a;
+} PDSCH_CONFIG_DEDICATED_NB_IoT;
+
+/// UplinkPowerControlDedicated Information Element from 36.331 RRC spec
+typedef struct {
+  /// Parameter: \f$P_\text{0\_UE\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dB. \vr{[-8..7]}\n This field is applicable for non-persistent scheduling, only.
+  int8_t p0_UE_PUSCH;
+  /// Parameter: Ks, see TS 36.213 (5.1.1.1). \vr{[0..1]}\n en0 corresponds to value 0 corresponding to state “disabled”. en1 corresponds to value 1.25 corresponding to “enabled”. \note the specification sais it is an enumerated value. \warning the enumeration values do not correspond to the given values in the specification (en1 should be 1.25).
+  uint8_t deltaMCS_Enabled;
+  /// Parameter: Accumulation-enabled, see TS 36.213 (5.1.1.1). \vr{[0..1]} 1 corresponds to "enabled" whereas 0 corresponds to "disabled".
+  uint8_t accumulationEnabled;
+  /// Parameter: \f$P_\text{0\_UE\_PUCCH}(1)\f$, see TS 36.213 (5.1.2.1), unit dB. \vr{[-8..7]}
+  int8_t p0_UE_PUCCH;
+  /// Parameter: \f$P_\text{SRS\_OFFSET}\f$, see TS 36.213 (5.1.3.1). \vr{[0..15]}\n For Ks=1.25 (\ref deltaMCS_Enabled), the actual parameter value is pSRS_Offset value - 3. For Ks=0, the actual parameter value is -10.5 + 1.5*pSRS_Offset value.
+  int8_t pSRS_Offset;
+  /// Specifies the filtering coefficient for RSRP measurements used to calculate path loss, as specified in TS 36.213 (5.1.1.1).\details The same filtering mechanism applies as for quantityConfig described in 5.5.3.2. \note the specification sais it is an enumerated value.
+  uint8_t filterCoefficient;
+} UL_POWER_CONTROL_DEDICATED_NB_IoT;
+
+/// Union for \ref TPC_PDCCH_CONFIG::tpc_Index.
+//typedef union {
+  /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]}
+ // uint8_t indexOfFormat3;
+  /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]}
+ // uint8_t indexOfFormat3A;
+//} TPC_INDEX_NB_IoT_t;
+
+/// CQI-ReportPeriodic
+typedef struct {
+  /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}, -1 indicates inactivity
+  int16_t cqi_PUCCH_ResourceIndex;
+  /// Parameter: CQI/PMI Periodicity and Offset Configuration Index \f$I_\text{CQI/PMI}\f$, see TS 36.213 (tables 7.2.2-1A and 7.2.2-1C). \vr{[0..1023]}
+  int16_t cqi_PMI_ConfigIndex;
+  /// Parameter: K, see 36.213 (4.2.2). \vr{[1..4]}
+  uint8_t K;
+  /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}, -1 indicates inactivity
+  int16_t ri_ConfigIndex;
+  /// Parameter: Simultaneous-AN-and-CQI, see TS 36.213 (10.1). \vr{[0..1]} 1 indicates that simultaneous transmission of ACK/NACK and CQI is allowed.
+  uint8_t simultaneousAckNackAndCQI;
+  /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C
+  uint16_t Npd;
+  /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C
+  uint16_t N_OFFSET_CQI;
+} CQI_REPORTPERIODIC_NB_IoT;
+
+/// Enumeration for parameter reporting mode \ref CQI_REPORT_CONFIG::cqi_ReportModeAperiodic.
+typedef enum {
+  //rm12=0,
+  //rm20=1,
+  //rm22=2,
+  rm30_N=3,
+  rm31_N=4
+} CQI_REPORTMODEAPERIODIC_NB_IoT;
+
+/// CQI-ReportConfig Information Element from 36.331 RRC spec
+typedef struct {
+  /// Parameter: reporting mode. Value rm12 corresponds to Mode 1-2, rm20 corresponds to Mode 2-0, rm22 corresponds to Mode 2-2 etc. PUSCH reporting modes are described in TS 36.213 [23, 7.2.1].
+  CQI_REPORTMODEAPERIODIC_NB_IoT cqi_ReportModeAperiodic;
+  /// Parameter: \f$\Delta_\text{offset}\f$, see TS 36.213 (7.2.3). \vr{[-1..6]}\n Actual value = IE value * 2 [dB].
+  int8_t nomPDSCH_RS_EPRE_Offset;
+  CQI_REPORTPERIODIC_NB_IoT CQI_ReportPeriodic;
+} CQI_REPORT_CONFIG_NB_IoT;
+
+/// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec
+typedef struct {
+  /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value.
+  uint8_t srs_Bandwidth;
+  /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value.
+  uint8_t srs_HoppingBandwidth;
+  /// Parameter: \f$n_\text{RRC}\f$, see TS 36.211 (5.5.3.2). \vr{[0..23]}
+  uint8_t freqDomainPosition;
+  /// Parameter: Duration, see TS 36.213 (8.2). \vr{[0..1]} 0 corresponds to "single" and 1 to "indefinite".
+  uint8_t duration;
+  /// Parameter: \f$k_\text{TC}\in\{0,1\}\f$, see TS 36.211 (5.5.3.2). \vr{[0..1]}
+  uint8_t transmissionComb;
+  /// Parameter: \f$I_\text{SRS}\f$, see TS 36.213 (table 8.2-1). \vr{[0..1023]}
+  uint16_t srs_ConfigIndex;
+  /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value.
+  uint8_t cyclicShift;
+  // Parameter: internal implementation: UE SRS configured
+  uint8_t srsConfigDedicatedSetup;
+  // Parameter: cell srs subframe for internal implementation
+  uint8_t srsCellSubframe;
+  // Parameter: ue srs subframe for internal implementation
+  uint8_t srsUeSubframe;
+} SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT;
+
+
+/// Enumeration for parameter SR transmission \ref SCHEDULING_REQUEST_CONFIG::dsr_TransMax.
+typedef enum {
+  //sr_n4=0,
+ // sr_n8=1,
+ // sr_n16=2,
+  sr_n32_N=3,
+  sr_n64_N=4
+} DSR_TRANSMAX_NB_IoT_t;
+
+/// SchedulingRequestConfig Information Element from 36.331 RRC spec
+typedef struct {
+  /// Parameter: \f$n^{(1)}_\text{PUCCH,SRI}\f$, see TS 36.213 (10.1). \vr{[0..2047]}
+  uint16_t sr_PUCCH_ResourceIndex;
+  /// Parameter: \f$I_\text{SR}\f$, see TS 36.213 (10.1). \vr{[0..155]}
+  uint8_t sr_ConfigIndex;
+  /// Parameter for SR transmission in TS 36.321 (5.4.4). \details The value n4 corresponds to 4 transmissions, n8 corresponds to 8 transmissions and so on.
+  DSR_TRANSMAX_NB_IoT_t dsr_TransMax;
+} SCHEDULING_REQUEST_CONFIG_NB_IoT;
+
+typedef struct {
+  /// Downlink Power offset field
+  uint8_t dl_pow_off;
+  ///Subband resource allocation field
+  uint8_t rballoc_sub[50];
+  ///Total number of PRBs indicator
+  uint8_t pre_nb_available_rbs;
+} MU_MIMO_mode_NB_IoT;
+////////////////////////
+
+typedef struct {
+
+    /// \brief Holds the received data in the frequency domain.
+    /// - first index: rx antenna [0..nb_antennas_rx[
+    /// - second index: symbol [0..28*ofdm_symbol_size[
+    int32_t **rxdataF;
+
+    /// \brief Hold the channel estimates in frequency domain.
+    /// - first index: eNB id [0..6] (hard coded)
+    /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+    /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
+    int32_t **dl_ch_estimates[7];
+
+    /// \brief Hold the channel estimates in time domain (used for tracking).
+    /// - first index: eNB id [0..6] (hard coded)
+    /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+    /// - third index: samples? [0..2*ofdm_symbol_size[
+    int32_t **dl_ch_estimates_time[7];
+}NB_IoT_UE_COMMON_PER_THREAD;
+
+typedef struct {
+  /// \brief Holds the transmit data in time domain.
+  /// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER.
+  /// - first index: tx antenna [0..nb_antennas_tx[
+  /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES[
+  int32_t **txdata;
+  /// \brief Holds the transmit data in the frequency domain.
+  /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
+  /// - first index: tx antenna [0..nb_antennas_tx[
+  /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX[
+  int32_t **txdataF;
+
+  /// \brief Holds the received data in time domain.
+  /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
+  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[
+  int32_t **rxdata;
+
+  NB_IoT_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[2];
+
+  /// holds output of the sync correlator
+  int32_t *sync_corr;
+  /// estimated frequency offset (in radians) for all subcarriers
+  int32_t freq_offset;
+  /// eNb_id user is synched to
+  int32_t eNb_id;
+} NB_IoT_UE_COMMON;
+
+typedef struct {
+  /// \brief Received frequency-domain signal after extraction.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **rxdataF_ext;
+  /// \brief Received frequency-domain ue specific pilots.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..12*N_RB_DL[
+  int32_t **rxdataF_uespec_pilots;
+  /// \brief Received frequency-domain signal after extraction and channel compensation.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **rxdataF_comp0;
+  /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round
+  /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
+  /// - second index: ? [0..7] (hard coded) accessed via \c round
+  /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - fourth index: ? [0..168*N_RB_DL[
+  int32_t **rxdataF_comp1[8][8];
+  /// \brief Downlink channel estimates extracted in PRBS.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_ch_estimates_ext;
+  /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round
+  /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
+  /// - second index: ? [0..7] (hard coded) accessed via \c round
+  /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - fourth index: ? [0..168*N_RB_DL[
+  int32_t **dl_ch_rho_ext[8][8];
+  /// \brief Downlink beamforming channel estimates in frequency domain.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
+  int32_t **dl_bf_ch_estimates;
+  /// \brief Downlink beamforming channel estimates.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_bf_ch_estimates_ext;
+  /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_ch_rho2_ext;
+  /// \brief Downlink PMIs extracted in PRBS and grouped in subbands.
+  /// - first index: ressource block [0..N_RB_DL[
+  uint8_t *pmi_ext;
+  /// \brief Magnitude of Downlink Channel first layer (16QAM level/First 64QAM level).
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_ch_mag0;
+  /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level).
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_ch_mag1[8][8];
+  /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level).
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_ch_magb0;
+  /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level).
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_ch_magb1[8][8];
+  /// \brief Cross-correlation of two eNB signals.
+  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// - second index: symbol [0..]
+  int32_t **rho;
+  /// never used... always send dl_ch_rho_ext instead...
+  int32_t **rho_i;
+  /// \brief Pointers to llr vectors (2 TBs).
+  /// - first index: ? [0..1] (hard coded)
+  /// - second index: ? [0..1179743] (hard coded)
+  int16_t *llr[2];
+  /// \f$\log_2(\max|H_i|^2)\f$
+  int16_t log2_maxh;
+    /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation
+  int16_t log2_maxh0;
+    /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation
+  int16_t log2_maxh1;
+  /// \brief LLR shifts for subband scaling.
+  /// - first index: ? [0..168*N_RB_DL[
+  uint8_t *llr_shifts;
+  /// \brief Pointer to LLR shifts.
+  /// - first index: ? [0..168*N_RB_DL[
+  uint8_t *llr_shifts_p;
+  /// \brief Pointers to llr vectors (128-bit alignment).
+  /// - first index: ? [0..0] (hard coded)
+  /// - second index: ? [0..]
+  int16_t **llr128;
+  /// \brief Pointers to llr vectors (128-bit alignment).
+  /// - first index: ? [0..0] (hard coded)
+  /// - second index: ? [0..]
+  int16_t **llr128_2ndstream;
+  //uint32_t *rb_alloc;
+  //uint8_t Qm[2];
+  //MIMO_mode_t mimo_mode;
+} NB_IoT_UE_PDSCH;
+
+/// NPRACH-ParametersList-NB-r13 from 36.331 RRC spec
+typedef struct NPRACH_Parameters_NB_IoT{
+  /// the period time for nprach
+  uint16_t nprach_Periodicity;
+  /// for the start time for the NPRACH resource from 40ms-2560ms
+  uint16_t nprach_StartTime;
+  /// for the subcarrier of set to the NPRACH preamble from n0 - n34
+  uint16_t nprach_SubcarrierOffset;
+  ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48)
+  uint16_t nprach_NumSubcarriers;
+  /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1
+  uint16_t nprach_SubcarrierMSG3_RangeStart;
+  /// The max preamble transmission attempt for the CE level from 1 - 128
+  uint16_t maxNumPreambleAttemptCE;
+  /// Number of NPRACH repetitions per attempt for each NPRACH resource
+  uint16_t numRepetitionsPerPreambleAttempt;
+  /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax)
+  uint16_t npdcch_NumRepetitions_RA;
+  /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4)
+  uint16_t npdcch_StartSF_CSS_RA;
+  /// Fractional period offset of starting subframe for NPDCCH common search space
+  uint16_t npdcch_Offset_RA;
+} nprach_parameters_NB_IoT_t;
+
+typedef struct{
+  nprach_parameters_NB_IoT_t list[3];
+}NPRACH_List_NB_IoT_t;
+
+typedef long RSRP_Range_t;
+
+typedef struct {
+  A_SEQUENCE_OF(RSRP_Range_t) list;
+}rsrp_ThresholdsNPrachInfoList;
+
+
+/// NPRACH_ConfigSIB-NB from 36.331 RRC spec
+typedef struct {
+  /// nprach_CP_Length_r13, for the CP length(unit us) only 66.7 and 266.7 is implemented
+  uint16_t nprach_CP_Length;
+  /// The criterion for UEs to select a NPRACH resource. Up to 2 RSRP threshold values can be signalled.  \vr{[1..2]}
+  struct rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList;
+  /// NPRACH Parameters List
+  NPRACH_List_NB_IoT_t nprach_ParametersList;
+
+} NPRACH_CONFIG_COMMON;
+
+/// NPDSCH-ConfigCommon from 36.331 RRC spec
+typedef struct {
+  ///see TS 36.213 (16.2). \vr{[-60..50]}\n Provides the downlink reference-signal EPRE. The actual value in dBm.
+  uint16_t nrs_Power;
+} NPDSCH_CONFIG_COMMON;
+
+typedef struct{
+  /// The base sequence of DMRS sequence in a cell for 3 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 12. Value 12 is not used.
+  uint16_t threeTone_BaseSequence;
+  /// Define 3 cyclic shifts for the 3-tone case, see TS 36.211 [21, 10.1.4.1.2].
+  uint16_t threeTone_CyclicShift;
+  /// The base sequence of DMRS sequence in a cell for 6 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 14. Value 14 is not used.
+  uint16_t sixTone_BaseSequence;
+  /// Define 4 cyclic shifts for the 6-tone case, see TS 36.211 [21, 10.1.4.1.2].
+  uint16_t sixTone_CyclicShift;
+  /// The base sequence of DMRS sequence in a cell for 12 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 30. Value 30 is not used.
+  uint16_t twelveTone_BaseSequence;
+
+}DMRS_CONFIG_t;
+
+/// UL-ReferenceSignalsNPUSCH from 36.331 RRC spec
+typedef struct {
+  /// Parameter: Group-hopping-enabled, see TS 36.211 (5.5.1.3). \vr{[0..1]}
+  uint8_t groupHoppingEnabled;
+  /// , see TS 36.211 (5.5.1.3). \vr{[0..29]}
+  uint8_t groupAssignmentNPUSCH;
+  /// Parameter: cyclicShift, see TS 36.211 (Table 5.5.2.1.1-2). \vr{[0..7]}
+  uint8_t cyclicShift;
+  /// nPRS for cyclic shift of DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification.
+  uint8_t nPRS[20];
+  /// group hopping sequence for DMRS, 36.211, Section 10.1.4.1.3. Second index corresponds to the four possible subcarrier configurations
+  uint8_t grouphop[20][4];
+  /// sequence hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification.
+  uint8_t seqhop[20];
+} UL_REFERENCE_SIGNALS_NPUSCH_t;
+
+
+/// PUSCH-ConfigCommon from 36.331 RRC spec.
+typedef struct {
+  /// Number of repetitions for ACK/NACK HARQ response to NPDSCH containing Msg4 per NPRACH resource, see TS 36.213 [23, 16.4.2].
+  uint8_t ack_NACK_NumRepetitions_Msg4[3];
+  /// SRS SubframeConfiguration. See TS 36.211 [21, table 5.5.3.3-1]. Value sc0 corresponds to value 0, sc1 to value 1 and so on.
+  uint8_t srs_SubframeConfig;
+  /// Parameter: \f$N^{HO}_{RB}\f$, see TS 36.211 (5.3.4). \vr{[0..98]}
+  DMRS_CONFIG_t dmrs_Config;
+  /// Ref signals configuration
+  UL_REFERENCE_SIGNALS_NPUSCH_t ul_ReferenceSignalsNPUSCH;
+
+} NPUSCH_CONFIG_COMMON;
+
+
+typedef struct{
+  /// See TS 36.213 [23, 16.2.1.1], unit dBm.
+  uint8_t p0_NominalNPUSCH;
+  /// See TS 36.213 [23, 16.2.1.1] where al0 corresponds to 0, al04 corresponds to value 0.4, al05 to 0.5, al06 to 0.6, al07 to 0.7, al08 to 0.8, al09 to 0.9 and al1 corresponds to 1. 
+  uint8_t alpha;
+  /// See TS 36.213 [23, 16.2.1.1]. Actual value = IE value * 2 [dB].
+  uint8_t deltaPreambleMsg3;
+}UplinkPowerControlCommon_NB_IoT;
+
+
+/* DL-GapConfig-NB-r13 */
+typedef struct {
+	uint16_t	 dl_GapThreshold;
+	uint16_t	 dl_GapPeriodicity;
+	uint16_t	 dl_GapDurationCoeff;
+} DL_GapConfig_NB_IoT;
+
+#define NBIOT_INBAND_LTEPCI 0
+#define NBIOT_INBAND_IOTPCI 1
+#define NBIOT_INGUARD       2
+#define NBIOT_STANDALONE    3
+
+
+typedef struct {
+  /// for inband, lte bandwidth
+  uint8_t LTE_N_RB_DL;
+  uint8_t LTE_N_RB_UL;
+  /// Cell ID
+  uint16_t Nid_cell;
+  /// shift of pilot position in one RB
+  uint8_t nushift;
+  /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0).
+  uint8_t node_id;
+  /// Frequency index of CBMIMO1 card
+  uint8_t freq_idx;
+  /// RX Frequency for ExpressMIMO/LIME
+  uint32_t carrier_freq[4];
+  /// TX Frequency for ExpressMIMO/LIME
+  uint32_t carrier_freqtx[4];
+  /// RX gain for ExpressMIMO/LIME
+  uint32_t rxgain[4];
+  /// TX gain for ExpressMIMO/LIME
+  uint32_t txgain[4];
+  /// RF mode for ExpressMIMO/LIME
+  uint32_t rfmode[4];
+  /// RF RX DC Calibration for ExpressMIMO/LIME
+  uint32_t rxdc[4];
+  /// RF TX DC Calibration for ExpressMIMO/LIME
+  uint32_t rflocal[4];
+  /// RF VCO calibration for ExpressMIMO/LIME
+  uint32_t rfvcolocal[4];
+  /// Turns on second TX of CBMIMO1 card
+  uint8_t dual_tx;
+  /// flag to indicate SISO transmission
+  uint8_t mode1_flag;
+  /// Indicator that 20 MHz channel uses 3/4 sampling frequency
+  //uint8_t threequarter_fs;
+  /// Size of FFT
+  uint16_t ofdm_symbol_size;
+  /// Number of prefix samples in all but first symbol of slot
+  uint16_t nb_prefix_samples;
+  /// Number of prefix samples in first symbol of slot
+  uint16_t nb_prefix_samples0;
+  /// Carrier offset in FFT buffer for first RE in PRB0
+  uint16_t first_carrier_offset;
+  /// Number of samples in a subframe
+  uint32_t samples_per_tti;
+  /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL)
+  uint16_t symbols_per_tti;
+  /// Number of Physical transmit antennas in node
+  uint8_t nb_antennas_tx;
+  /// Number of Receive antennas in node
+  uint8_t nb_antennas_rx;
+  /// Number of common transmit antenna ports in eNodeB (1 or 2)
+  uint8_t nb_antenna_ports_eNB;
+  /// Number of common receiving antenna ports in eNodeB (1 or 2)
+  uint8_t nb_antenna_ports_rx_eNB;
+  /// NPRACH Config Common (from 36-331 RRC spec)
+  NPRACH_CONFIG_COMMON nprach_config_common;
+  /// NPDSCH Config Common (from 36-331 RRC spec)
+  NPDSCH_CONFIG_COMMON npdsch_config_common;
+  /// PUSCH Config Common (from 36-331 RRC spec)
+  NPUSCH_CONFIG_COMMON npusch_config_common;
+  /// UL Power Control (from 36-331 RRC spec)
+  UplinkPowerControlCommon_NB_IoT ul_power_control_config_common;
+  /// DL Gap
+  DL_GapConfig_NB_IoT DL_gap_config;
+  /// Size of SI windows used for repetition of one SI message (in frames)
+  uint8_t SIwindowsize;
+  /// Period of SI windows used for repetition of one SI message (in frames)
+  uint16_t SIPeriod;
+  int                 eutra_band;
+  uint32_t            dl_CarrierFreq;
+  uint32_t            ul_CarrierFreq;
+  // CE level to determine the NPRACH Configuration (one CE for each NPRACH config.)
+  uint8_t             CE;
+
+  /*
+   * index of the PRB assigned to NB-IoT carrier in in-band/guard-band operating mode
+   */
+  unsigned short NB_IoT_RB_ID;
+
+
+  /*Following FAPI approach:
+   * 0 = in-band with same PCI
+   * 1 = in-band with diff PCI
+   * 2 = guard band
+   * 3 =stand alone
+   */
+  uint16_t operating_mode;
+  /*
+   * Only for In-band operating mode with same PCI
+   * its measured in number of OFDM symbols
+   * allowed values:
+   * 1, 2, 3, 4(this value is written in FAPI specs but not exist in TS 36.331 v14.2.1 pag 587)
+   * -1 (we put this value when is not defined - other operating mode)
+   */
+  uint16_t control_region_size;
+
+  /*Number of EUTRA CRS antenna ports (AP)
+   * valid only for in-band different PCI mode
+   * value 0 = indicates the same number of AP as NRS APs
+   * value 1 = four CRS APs
+   */
+  uint16_t eutra_NumCRS_ports;
+
+  /* Subcarrier bandwidth
+  0 -> 3.75 kHz
+  1 -> 15 kHz
+  */
+  uint8_t subcarrier_spacing; 
+
+} NB_IoT_DL_FRAME_PARMS;
+
+typedef struct {
+  /// \brief Pointers (dynamic) to the received data in the time domain.
+  /// - first index: rx antenna [0..nb_antennas_rx]
+  /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti]
+  int32_t **rxdata;
+  /// \brief Pointers (dynamic) to the received data in the frequency domain.
+  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti]
+  int32_t **rxdataF;
+  /// \brief holds the transmit data in the frequency domain.
+  /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports.
+  /// - third index: sample [0..]
+  int32_t **txdataF; 
+} NB_IoT_eNB_COMMON;
+
+typedef struct {
+  /// \brief Holds the transmit data in the frequency domain.
+  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
+  int32_t **txdata;
+  /// \brief Holds the receive data in the frequency domain.
+  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
+  int32_t **rxdata[3];
+  /// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset.
+  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// - second index: sample [0..samples_per_tti[
+  int32_t **rxdata_7_5kHz[3];
+  /// \brief Holds the received data in the frequency domain.
+  /// - first index: rx antenna [0..nb_antennas_rx[
+  /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
+  int32_t **rxdataF[3];
+  /// \brief Holds output of the sync correlator.
+  /// - first index: sample [0..samples_per_tti*10[
+  uint32_t *sync_corr[3];
+} NB_IoT_RU_COMMON;
+
+typedef struct {
+  /// \brief Hold the channel estimates in frequency domain based on SRS.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..ofdm_symbol_size[
+  int32_t **srs_ch_estimates[3];
+  /// \brief Hold the channel estimates in time domain based on SRS.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..2*ofdm_symbol_size[
+  int32_t **srs_ch_estimates_time[3];
+  /// \brief Holds the SRS for channel estimation at the RX.
+  /// - first index: ? [0..ofdm_symbol_size[
+  int32_t *srs;
+} NB_IoT_eNB_SRS;
+
+typedef struct {
+  /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..2*ofdm_symbol_size[
+  /// - third index (definition from phy_init_lte_eNB()): ? [0..24*N_RB_UL*frame_parms->symbols_per_tti[
+  /// \warning inconsistent third index definition
+  int32_t **rxdataF_ext[3];
+  /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **rxdataF_ext2[3];
+  /// \brief Hold the channel estimates in time domain based on DRS.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..4*ofdm_symbol_size[
+  int32_t **drs_ch_estimates_time[3];
+  /// \brief Hold the channel estimates in frequency domain based on DRS.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **drs_ch_estimates[3];
+  /// \brief Hold the channel estimates for UE0 in case of Distributed Alamouti Scheme.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **drs_ch_estimates_0[3];
+  /// \brief Hold the channel estimates for UE1 in case of Distributed Almouti Scheme.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **drs_ch_estimates_1[3];
+  /// \brief Holds the compensated signal.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **rxdataF_comp[3];
+  /// \brief Hold the compensated data (y)*(h0*) in case of Distributed Alamouti Scheme.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **rxdataF_comp_0[3];
+  /// \brief Hold the compensated data (y*)*(h1) in case of Distributed Alamouti Scheme.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **rxdataF_comp_1[3];
+  /// \brief ?.
+  /// - first index: sector id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_mag[3];
+  /// \brief ?.
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_magb[3];
+  /// \brief Hold the channel mag for UE0 in case of Distributed Alamouti Scheme.
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_mag_0[3];
+  /// \brief Hold the channel magb for UE0 in case of Distributed Alamouti Scheme.
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_magb_0[3];
+  /// \brief Hold the channel mag for UE1 in case of Distributed Alamouti Scheme.
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_mag_1[3];
+  /// \brief Hold the channel magb for UE1 in case of Distributed Alamouti Scheme.
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: rx antenna id [0..nb_antennas_rx[
+  /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+  int32_t **ul_ch_magb_1[3];
+  /// measured RX power based on DRS
+  int ulsch_power[2];
+  /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme
+  int ulsch_power_0[2];
+  /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme
+  int ulsch_power_1[2];
+  /// \brief llr values.
+  /// - first index: ? [0..1179743] (hard coded)
+  int16_t *llr;
+#ifdef LOCALIZATION
+  /// number of active subcarrier for a specific UE
+  int32_t active_subcarrier;
+  /// subcarrier power in dBm
+  int32_t *subcarrier_power;
+#endif
+} NB_IoT_eNB_PUSCH;
+
+#define PBCH_A_NB_IoT 24
+typedef struct {
+  uint8_t pbch_d[96+(3*(16+PBCH_A_NB_IoT))];
+  uint8_t pbch_w[3*3*(16+PBCH_A_NB_IoT)];
+  uint8_t pbch_e[1920];
+} NB_IoT_eNB_PBCH;
+
+
+typedef enum {
+  /// TM1
+  SISO_NB_IoT=0,
+  /// TM2
+  ALAMOUTI_NB_IoT=1,
+  /// TM3
+  LARGE_CDD_NB_IoT=2,
+  /// the next 6 entries are for TM5
+  UNIFORM_PRECODING11_NB_IoT=3,
+  UNIFORM_PRECODING1m1_NB_IoT=4,
+  UNIFORM_PRECODING1j_NB_IoT=5,
+  UNIFORM_PRECODING1mj_NB_IoT=6,
+  PUSCH_PRECODING0_NB_IoT=7,
+  PUSCH_PRECODING1_NB_IoT=8,
+  /// the next 3 entries are for TM4
+  DUALSTREAM_UNIFORM_PRECODING1_NB_IoT=9,
+  DUALSTREAM_UNIFORM_PRECODINGj_NB_IoT=10,
+  DUALSTREAM_PUSCH_PRECODING_NB_IoT=11,
+  TM7_NB_IoT=12,
+  TM8_NB_IoT=13,
+  TM9_10_NB_IoT=14
+} MIMO_mode_NB_IoT_t;
+
+typedef struct {
+  /// \brief ?.
+  /// first index: ? [0..1023] (hard coded)
+  int16_t *prachF;
+  /// \brief ?.
+  /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
+  /// second index: ? [0..ofdm_symbol_size*12[
+  int16_t *rxsigF[64];
+  /// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs)
+  /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
+  /// second index: ? [0..2047] (hard coded)
+  int16_t *prach_ifft[64];
+} NB_IoT_eNB_PRACH;
+
+typedef enum {
+  NOT_SYNCHED_NB_IoT=0,
+  PRACH_NB_IoT=1,
+  RA_RESPONSE_NB_IoT=2,
+  PUSCH_NB_IoT=3,
+  RESYNCH_NB_IoT=4
+} UE_MODE_NB_IoT_t;
+
+
+#endif
diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..e512ec02155c8e7780856ab6dd677d638043e1f0
--- /dev/null
+++ b/openair1/PHY/impl_defs_top_NB_IoT.h
@@ -0,0 +1,541 @@
+/*
+ * 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/impl_defs_top.h
+* \brief More defines and structure definitions
+* \author R. Knopp, F. Kaltenberger
+* \date 2011
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
+* \note
+* \warning
+*/
+
+#ifndef __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__
+#define __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__
+
+
+#include "openairinterface5g_limits.h"
+/** @defgroup _ref_implementation_ OpenAirInterface LTE Implementation
+ * @{
+
+ * @defgroup _PHY_RF_INTERFACE_ PHY - RF Interface
+ * @ingroup _PHY_RF_INTERFACE_
+ * @{
+ * @defgroup _GENERIC_PHY_RF_INTERFACE_ Generic PHY - RF Interface
+ * @defgroup _USRP_PHY_RF_INTERFACE_    PHY - USRP RF Interface
+ * @defgroup _BLADERF_PHY_RF_INTERFACE_    PHY - BLADERF RF Interface
+ * @defgroup _LMSSDR_PHY_RF_INTERFACE_    PHY - LMSSDR RF Interface
+ * @}
+ *
+ * @ingroup _ref_implementation_
+ * @{
+ * This module is responsible for defining the generic interface between PHY and RF Target
+ * @}
+ 
+ * @defgroup _openair1_ openair1 Reference Implementation 
+ * @ingroup _ref_implementation_
+ * @{
+
+
+ * @defgroup _physical_layer_ref_implementation_ Physical Layer Reference Implementation
+ * @ingroup _openair1_
+ * @{
+
+
+ * @defgroup _PHY_STRUCTURES_ Basic Structures and Memory Initialization
+ * @ingroup _physical_layer_ref_implementation_
+ * @{
+ * This module is responsible for defining and initializing the PHY variables during static configuration of OpenAirInterface.
+ * @}
+
+ * @defgroup _PHY_DSP_TOOLS_ DSP Tools
+ * @ingroup _physical_layer_ref_implementation_
+ * @{
+ * This module is responsible for basic signal processing related to inner-MODEM processing.
+ * @}
+
+ * @defgroup _PHY_MODULATION_ Modulation and Demodulation
+ * @ingroup _physical_layer_ref_implementation_
+ * @{
+ * This module is responsible for procedures related to OFDMA modulation and demodulation.
+ * @}
+
+ * @defgroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ Parameter Estimation
+ * @ingroup _physical_layer_ref_implementation_
+ * @{
+ * This module is responsible for procedures related to OFDMA frequency-domain channel estimation for LTE Downlink Channels.
+ * @}
+
+ * @defgroup _PHY_CODING_BLOCKS_ Channel Coding/Decoding Functions
+ * @ingroup _physical_layer_ref_implementation_
+ * @{
+ * This module is responsible for procedures related to channel coding/decoding, rate-matching, segementation and interleaving.
+ * @}
+
+ * @defgroup _PHY_TRANSPORT_ Transport/Physical Channel Processing
+ * @ingroup _physical_layer_ref_implementation_
+ * @{
+ * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels.
+ * @}
+
+ * @defgroup _PHY_PROCEDURES_ Physical Layer Procedures
+ * @ingroup _physical_layer_ref_implementation_
+ * @{
+ * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels.
+ * @}
+
+ * @}
+ * @}
+ * @}
+ */
+
+//#include "types.h"
+
+/*
+
+
+#define NUMBER_OF_OFDM_CARRIERS (frame_parms->ofdm_symbol_size)
+#define NUMBER_OF_SYMBOLS_PER_FRAME (frame_parms->symbols_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)
+#define NUMBER_OF_USEFUL_CARRIERS (12*frame_parms->N_RB_DL)
+#define NUMBER_OF_ZERO_CARRIERS (NUMBER_OF_OFDM_CARRIERS-NUMBER_OF_USEFUL_CARRIERS)
+#define NUMBER_OF_USEFUL_CARRIERS_BYTES (NUMBER_OF_USEFUL_CARRIERS>>2)
+#define HALF_NUMBER_OF_USEFUL_CARRIERS (NUMBER_OF_USEFUL_CARRIERS>>1)
+#define HALF_NUMBER_OF_USEFUL_CARRIERS_BYTES (HALF_NUMBER_OF_USEFUL_CARRIERS>>2)
+#define FIRST_CARRIER_OFFSET (HALF_NUMBER_OF_USEFUL_CARRIERS+NUMBER_OF_ZERO_CARRIERS)
+#define NUMBER_OF_OFDM_SYMBOLS_PER_SLOT (NUMBER_OF_SYMBOLS_PER_FRAME/LTE_SLOTS_PER_FRAME)
+
+#ifdef EMOS
+#define EMOS_SCH_INDEX 1
+#endif //EMOS
+
+#define EXTENSION_TYPE (PHY_config->PHY_framing.Extension_type)
+
+#define NUMBER_OF_OFDM_CARRIERS_BYTES   NUMBER_OF_OFDM_CARRIERS*4
+//#define NUMBER_OF_USEFUL_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS*4
+#define HALF_NUMBER_OF_USER_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS/2
+
+#define CYCLIC_PREFIX_LENGTH (frame_parms->nb_prefix_samples)
+#define CYCLIC_PREFIX_LENGTH_SAMPLES (CYCLIC_PREFIX_LENGTH*2)
+#define CYCLIC_PREFIX_LENGTH_BYTES (CYCLIC_PREFIX_LENGTH*4)
+#define CYCLIC_PREFIX_LENGTH0 (frame_parms->nb_prefix_samples0)
+#define CYCLIC_PREFIX_LENGTH_SAMPLES0 (CYCLIC_PREFIX_LENGTH0*2)
+#define CYCLIC_PREFIX_LENGTH_BYTES0 (CYCLIC_PREFIX_LENGTH0*4)
+
+#define OFDM_SYMBOL_SIZE_SAMPLES ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH)*2)   // 16-bit units (i.e. real samples)
+#define OFDM_SYMBOL_SIZE_SAMPLES0 ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH0)*2)   // 16-bit units (i.e. real samples)
+#define OFDM_SYMBOL_SIZE_SAMPLES_MAX 4096   // 16-bit units (i.e. real samples)
+#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES (OFDM_SYMBOL_SIZE_SAMPLES/2)                   // 32-bit units (i.e. complex samples)
+#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0 (OFDM_SYMBOL_SIZE_SAMPLES0/2)                   // 32-bit units (i.e. complex samples)
+#define OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX ((NUMBER_OF_OFDM_CARRIERS)*2)
+#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX/2)
+#define OFDM_SYMBOL_SIZE_BYTES (OFDM_SYMBOL_SIZE_SAMPLES*2)
+#define OFDM_SYMBOL_SIZE_BYTES0 (OFDM_SYMBOL_SIZE_SAMPLES0*2)
+#define OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX*2)
+
+#define SLOT_LENGTH_BYTES (frame_parms->samples_per_tti<<1) // 4 bytes * samples_per_tti/2
+#define SLOT_LENGTH_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX * NUMBER_OF_OFDM_SYMBOLS_PER_SLOT)
+
+#define FRAME_LENGTH_COMPLEX_SAMPLES (frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)
+#define FRAME_LENGTH_SAMPLES (FRAME_LENGTH_COMPLEX_SAMPLES*2)
+#define FRAME_LENGTH_SAMPLES_NO_PREFIX (NUMBER_OF_SYMBOLS_PER_FRAME*OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX)
+#define FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX (FRAME_LENGTH_SAMPLES_NO_PREFIX/2)
+
+#define NUMBER_OF_CARRIERS_PER_GROUP (NUMBER_OF_USEFUL_CARRIERS/NUMBER_OF_FREQUENCY_GROUPS)
+
+#define RX_PRECISION (16)
+#define LOG2_RX_PRECISION (4)
+#define RX_OUTPUT_SHIFT (4)
+
+
+#define SAMPLE_SIZE_BYTES    2                                           // 2 bytes/real sample
+
+#define FRAME_LENGTH_BYTES   (FRAME_LENGTH_SAMPLES * SAMPLE_SIZE_BYTES)  // frame size in bytes
+#define FRAME_LENGTH_BYTES_NO_PREFIX   (FRAME_LENGTH_SAMPLES_NO_PREFIX * SAMPLE_SIZE_BYTES)  // frame size in bytes
+
+
+#define FFT_SCALE_FACTOR     8                                           // Internal Scaling for FFT
+#define DMA_BLKS_PER_SLOT    (SLOT_LENGTH_BYTES/2048)                    // Number of DMA blocks per slot
+#define SLOT_TIME_NS         (SLOT_LENGTH_SAMPLES*(1e3)/7.68)            // slot time in ns
+
+#define NB_ANTENNA_PORTS_ENB  6                                         // total number of eNB antenna ports
+
+#ifdef EXMIMO
+#define TARGET_RX_POWER 55    // Target digital power for the AGC
+#define TARGET_RX_POWER_MAX 55    // Maximum digital power, such that signal does not saturate (value found by simulation)
+#define TARGET_RX_POWER_MIN 50    // Minimum digital power, anything below will be discarded (value found by simulation)
+#else
+#define TARGET_RX_POWER 50    // Target digital power for the AGC
+#define TARGET_RX_POWER_MAX 65    // Maximum digital power, such that signal does not saturate (value found by simulation)
+#define TARGET_RX_POWER_MIN 35    // Minimum digital power, anything below will be discarded (value found by simulation)
+#endif
+
+//the min and max gains have to match the calibrated gain table
+//#define MAX_RF_GAIN 160
+//#define MIN_RF_GAIN 96
+#define MAX_RF_GAIN 200
+#define MIN_RF_GAIN 80
+
+#define PHY_SYNCH_OFFSET ((OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)-1)  // OFFSET of BEACON SYNCH
+#define PHY_SYNCH_MIN_POWER 1000
+#define PHY_SYNCH_THRESHOLD 100
+
+*/
+
+#define ONE_OVER_SQRT2_Q15_NB_IoT 23170
+
+/*
+#define ONE_OVER_2_Q15 16384
+
+// QAM amplitude definitions
+
+/// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$)
+#define QAM16_n1 20724
+/// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$)
+#define QAM16_n2 10362
+
+///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{42}\f$)
+#define QAM64_n1 20225
+///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{42}\f$)
+#define QAM64_n2 10112
+///Third Amplitude for QAM64 (\f$ 2^{15} \times 1/\sqrt{42}\f$)
+#define QAM64_n3 5056
+
+/// First Amplitude for QAM16 for TM5 (\f$ 2^{15} \times 2/sqrt(20)\f$)
+#define QAM16_TM5_n1 14654
+/// Second Amplitude for QAM16 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{20}\f$)
+#define QAM16_TM5_n2 7327
+
+///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{84}\f$)
+#define QAM64_TM5_n1 14301
+///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{84}\f$)
+#define QAM64_TM5_n2 7150
+///Third Amplitude for QAM64 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{84}\f$)
+#define QAM64_TM5_n3 3575
+
+
+#ifdef BIT8_RXMUX
+#define PERROR_SHIFT 0
+#else
+#define PERROR_SHIFT 10
+#endif
+
+#define BIT8_TX_SHIFT 2
+#define BIT8_TX_SHIFT_DB 12
+
+//#define CHBCH_RSSI_MIN -75
+
+#ifdef BIT8_TX
+#define AMP 128
+#else
+#define AMP 512//1024 //4096
+#endif
+
+#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
+#define AMP_OVER_2 (AMP>>1)
+
+/// Threshold for PUCCH Format 1 detection
+#define PUCCH1_THRES 0
+/// Threshold for PUCCH Format 1a/1b detection
+#define PUCCH1a_THRES 4
+
+/// Data structure for transmission.
+typedef struct {
+  /// RAW TX sample buffer
+  char *TX_DMA_BUFFER[2];
+} TX_VARS ;
+
+/// Data structure for reception.
+typedef struct {
+  /// RAW TX sample buffer
+  char *TX_DMA_BUFFER[2];
+  /// RAW RX sample buffer
+  int *RX_DMA_BUFFER[2];
+} TX_RX_VARS;
+
+//! \brief Extension Type /
+typedef enum {
+  CYCLIC_PREFIX,
+  CYCLIC_SUFFIX,
+  ZEROS,
+  NONE
+} Extension_t;
+	
+/// Measurement Variables
+*/
+#define NUMBER_OF_SUBBANDS_MAX_NB_IoT 13
+/*
+#define NUMBER_OF_HARQ_PID_MAX 8
+
+#define MAX_FRAME_NUMBER 0x400
+#include "openairinterface5g_limits.h"
+
+#define NUMBER_OF_RN_MAX 3
+typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t;
+
+typedef struct {
+  //unsigned int   rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];     //! estimated received signal power (linear)
+  //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];  //! estimated received signal power (dB)
+  //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX];              //! estimated avg received signal power (dB)
+
+  // RRC measurements
+  uint32_t rssi;
+  int n_adj_cells;
+  unsigned int adj_cell_id[6];
+  uint32_t rsrq[7];
+  uint32_t rsrp[7];
+  float rsrp_filtered[7]; // after layer 3 filtering
+  float rsrq_filtered[7];
+  // common measurements
+  //! estimated noise power (linear)
+  unsigned int   n0_power[NB_ANTENNAS_RX];
+  //! estimated noise power (dB)
+  unsigned short n0_power_dB[NB_ANTENNAS_RX];
+  //! total estimated noise power (linear)
+  unsigned int   n0_power_tot;
+  //! total estimated noise power (dB)
+  unsigned short n0_power_tot_dB;
+  //! average estimated noise power (linear)
+  unsigned int   n0_power_avg;
+  //! average estimated noise power (dB)
+  unsigned short n0_power_avg_dB;
+  //! total estimated noise power (dBm)
+  short n0_power_tot_dBm;
+
+  // UE measurements
+  //! estimated received spatial signal power (linear)
+  int            rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2];
+  //! estimated received spatial signal power (dB)
+  unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2];
+
+  /// estimated received signal power (sum over all TX antennas)
+  //int            wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  int            rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  /// estimated received signal power (sum over all TX antennas)
+  //int            wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+
+  /// estimated received signal power (sum over all TX/RX antennas)
+  int            rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW
+  /// estimated received signal power (sum over all TX/RX antennas)
+  unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW
+
+  //! estimated received signal power (sum of all TX/RX antennas, time average)
+  int            rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX];
+  //! estimated received signal power (sum of all TX/RX antennas, time average, in dB)
+  unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// SINR (sum of all TX/RX antennas, in dB)
+  int            wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX];
+  /// SINR (sum of all TX/RX antennas, time average, in dB)
+  int            wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  //! estimated rssi (dBm)
+  short          rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX];
+  //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
+  int            rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2];
+  //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
+  int            rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2];
+
+  /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams)
+  int            precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4];
+  /// Subband CQI per RX antenna (= SINR)
+  int            subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX];
+  /// Total Subband CQI  (= SINR)
+  int            subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX];
+  /// Subband CQI in dB (= SINR dB)
+  int            subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX];
+  /// Total Subband CQI
+  int            subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX];
+  /// Wideband PMI for each RX antenna
+  int            wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  /// Wideband PMI for each RX antenna
+  int            wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  ///Subband PMI for each RX antenna
+  int            subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX];
+  ///Subband PMI for each RX antenna
+  int            subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX];
+  /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas)
+  unsigned char           selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX];
+  /// Wideband Rank indication
+  unsigned char  rank[NUMBER_OF_CONNECTED_eNB_MAX];
+  /// Number of RX Antennas
+  unsigned char  nb_antennas_rx;
+  /// DLSCH error counter
+  // short          dlsch_errors;
+
+} PHY_MEASUREMENTS;
+*/
+typedef enum {no_relay_NB_IoT=1,unicast_relay_type1_NB_IoT,unicast_relay_type2_NB_IoT, multicast_relay_NB_IoT} relaying_type_t_NB_IoT;
+typedef struct {
+  //unsigned int   rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];     //! estimated received signal power (linear)
+  //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];  //! estimated received signal power (dB)
+  //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX];              //! estimated avg received signal power (dB)
+
+  // RRC measurements
+  uint32_t rssi;
+  int n_adj_cells;
+  unsigned int adj_cell_id[6];
+  uint32_t rsrq[7];
+  uint32_t rsrp[7];
+  float rsrp_filtered[7]; // after layer 3 filtering
+  float rsrq_filtered[7];
+  // common measurements
+  //! estimated noise power (linear)
+  unsigned int   n0_power[NB_ANTENNAS_RX];
+  //! estimated noise power (dB)
+  unsigned short n0_power_dB[NB_ANTENNAS_RX];
+  //! total estimated noise power (linear)
+  unsigned int   n0_power_tot;
+  //! total estimated noise power (dB)
+  unsigned short n0_power_tot_dB;
+  //! average estimated noise power (linear)
+  unsigned int   n0_power_avg;
+  //! average estimated noise power (dB)
+  unsigned short n0_power_avg_dB;
+  //! total estimated noise power (dBm)
+  short n0_power_tot_dBm;
+
+  // UE measurements
+  //! estimated received spatial signal power (linear)
+  int            rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2];
+  //! estimated received spatial signal power (dB)
+  unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2];
+
+  /// estimated received signal power (sum over all TX antennas)
+  //int            wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  int            rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  /// estimated received signal power (sum over all TX antennas)
+  //int            wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+
+  /// estimated received signal power (sum over all TX/RX antennas)
+  int            rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW
+  /// estimated received signal power (sum over all TX/RX antennas)
+  unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW
+
+  //! estimated received signal power (sum of all TX/RX antennas, time average)
+  int            rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX];
+  //! estimated received signal power (sum of all TX/RX antennas, time average, in dB)
+  unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  /// SINR (sum of all TX/RX antennas, in dB)
+  int            wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX];
+  /// SINR (sum of all TX/RX antennas, time average, in dB)
+  int            wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX];
+
+  //! estimated rssi (dBm)
+  short          rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX];
+  //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
+  int            rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2];
+  //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
+  int            rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2];
+
+  /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams)
+  int            precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4];
+  /// Subband CQI per RX antenna (= SINR)
+  int            subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT];
+  /// Total Subband CQI  (= SINR)
+  int            subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT];
+  /// Subband CQI in dB (= SINR dB)
+  int            subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT];
+  /// Total Subband CQI
+  int            subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT];
+  /// Wideband PMI for each RX antenna
+  int            wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  /// Wideband PMI for each RX antenna
+  int            wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];
+  ///Subband PMI for each RX antenna
+  int            subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX];
+  ///Subband PMI for each RX antenna
+  int            subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX];
+  /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas)
+  unsigned char           selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT];
+  /// Wideband Rank indication
+  unsigned char  rank[NUMBER_OF_CONNECTED_eNB_MAX];
+  /// Number of RX Antennas
+  unsigned char  nb_antennas_rx;
+  /// DLSCH error counter
+  // short          dlsch_errors;
+
+} PHY_MEASUREMENTS_NB_IoT;
+
+
+typedef struct {
+  //unsigned int   rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];     //! estimated received signal power (linear)
+  //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX];  //! estimated received signal power (dB)
+  //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX];              //! estimated avg received signal power (dB)
+
+  // common measurements
+  //! estimated noise power (linear)
+  unsigned int   n0_power[NB_ANTENNAS_RX];
+  //! estimated noise power (dB)
+  unsigned short n0_power_dB[NB_ANTENNAS_RX];
+  //! total estimated noise power (linear)
+  unsigned int   n0_power_tot;
+  //! estimated avg noise power (dB)
+  unsigned short n0_power_tot_dB;
+  //! estimated avg noise power (dB)
+  short n0_power_tot_dBm;
+  //! estimated avg noise power per RB per RX ant (lin)
+  unsigned short n0_subband_power[NB_ANTENNAS_RX][100];
+  //! estimated avg noise power per RB per RX ant (dB)
+  unsigned short n0_subband_power_dB[NB_ANTENNAS_RX][100];
+  //! estimated avg noise power per RB (dB)
+  short n0_subband_power_tot_dB[100];
+  //! estimated avg noise power per RB (dBm)
+  short n0_subband_power_tot_dBm[100];
+  // eNB measurements (per user)
+  //! estimated received spatial signal power (linear)
+  unsigned int   rx_spatial_power[NUMBER_OF_UE_MAX_NB_IoT][2][2];
+  //! estimated received spatial signal power (dB)
+  unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX_NB_IoT][2][2];
+  //! estimated rssi (dBm)
+  short          rx_rssi_dBm[NUMBER_OF_UE_MAX_NB_IoT];
+  //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
+  int            rx_correlation[NUMBER_OF_UE_MAX_NB_IoT][2];
+  //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
+  int            rx_correlation_dB[NUMBER_OF_UE_MAX_NB_IoT][2];
+
+  /// Wideband CQI (= SINR)
+  int            wideband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX];
+  /// Wideband CQI in dB (= SINR dB)
+  int            wideband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX];
+  /// Wideband CQI (sum of all RX antennas, in dB)
+  char           wideband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT];
+  /// Subband CQI per RX antenna and RB (= SINR)
+  int            subband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100];
+  /// Total Subband CQI and RB (= SINR)
+  int            subband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT][100];
+  /// Subband CQI in dB and RB (= SINR dB)
+  int            subband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100];
+  /// Total Subband CQI and RB
+  int            subband_cqi_tot_dB[NUMBER_OF_UE_MAX_NB_IoT][100];
+
+} PHY_MEASUREMENTS_eNB_NB_IoT;
+/*
+#define MCS_COUNT 28
+#define MCS_TABLE_LENGTH_MAX 64
+*/
+#endif //__PHY_IMPLEMENTATION_DEFS_H__ 
+/**@} 
+*/
diff --git a/openair1/PHY/types_NB_IoT.h b/openair1/PHY/types_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8a6ea501e7170a031143840bed37a85552a09ad
--- /dev/null
+++ b/openair1/PHY/types_NB_IoT.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+#ifndef __openair_TYPES_NB_IOT_H__
+#define __openair_TYPES_NB_IOT_H__
+
+#ifdef USER_MODE
+#include <stdint.h>
+#else
+#include <linux/types.h>
+#endif
+
+
+#endif /*__openair_TYPES_NB_IOT_H__ */
diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c
index 79af3c128e74d5c7178436ae1fffaefc273f98c4..4730eed613198c04a2ced09ae6e6b6d3fc947fcc 100644
--- a/openair1/SCHED/prach_procedures.c
+++ b/openair1/SCHED/prach_procedures.c
@@ -36,6 +36,7 @@
 #include "SCHED/extern.h"
 #include "nfapi_interface.h"
 #include "fapi_l1.h"
+#include "nfapi_pnf.h"
 #include "UTIL/LOG/log.h"
 #include "UTIL/LOG/vcd_signal_dumper.h"
 
diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h
index f4004bdbf991c4c87bec639aacfb13d3071caf76..4debccc7b05075ce37e830420336551a29c6c323 100644
--- a/openair2/COMMON/platform_constants.h
+++ b/openair2/COMMON/platform_constants.h
@@ -77,6 +77,10 @@
 
 #define MAX_MANAGED_ENB_PER_MOBILE  2
 
+///NB-IOT
+#define NB_RB_MAX_NB_IOT  (maxDRB_NB_r13 + 3) //MP: NB_IoT --> 2(DRB)+3(SRBs - 2 is not used) = 5
+
+
 #define DEFAULT_RAB_ID 1
 
 #define NB_RB_MAX      (maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */
diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h
index be3d18c996126583c79b6df83f84754a34116dac..08ea93f427add5aa6dbd032e54180848cb3e85da 100644
--- a/openair2/COMMON/rrc_messages_def.h
+++ b/openair2/COMMON/rrc_messages_def.h
@@ -54,6 +54,7 @@ MESSAGE_DEF(RRC_STATE_IND,              MESSAGE_PRIORITY_MED,       RrcStateInd,
 //-------------------------------------------------------------------------------------------//
 // eNB: ENB_APP -> RRC messages
 MESSAGE_DEF(RRC_CONFIGURATION_REQ,      MESSAGE_PRIORITY_MED,       RrcConfigurationReq,        rrc_configuration_req)
+MESSAGE_DEF(NBIOTRRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED,       NbIoTRrcConfigurationReq,   nbiotrrc_configuration_req)
 
 // UE: NAS -> RRC messages
 MESSAGE_DEF(NAS_KENB_REFRESH_REQ,       MESSAGE_PRIORITY_MED,       NasKenbRefreshReq,          nas_kenb_refresh_req)
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 6fd0a0411363a1d0903dad4d5a45f223aeb37183..9bd25d3b3aa52075eaf3acf5f5c51b0f9f7581b5 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -62,6 +62,8 @@ typedef UL_DCCH_Message_t       RrcUlDcchMessage;
 
 #define RRC_CONFIGURATION_REQ(mSGpTR)   (mSGpTR)->ittiMsg.rrc_configuration_req
 
+#define NBIOTRRC_CONFIGURATION_REQ(mSGpTR)   (mSGpTR)->ittiMsg.nbiotrrc_configuration_req
+
 #define NAS_KENB_REFRESH_REQ(mSGpTR)    (mSGpTR)->ittiMsg.nas_kenb_refresh_req
 #define NAS_CELL_SELECTION_REQ(mSGpTR)  (mSGpTR)->ittiMsg.nas_cell_selection_req
 #define NAS_CONN_ESTABLI_REQ(mSGpTR)    (mSGpTR)->ittiMsg.nas_conn_establi_req
@@ -167,6 +169,77 @@ typedef struct RrcConfigurationReq_s {
   long                    ue_TimersAndConstants_n311[MAX_NUM_CCs];
   long                    ue_TransmissionMode[MAX_NUM_CCs];
 } RrcConfigurationReq;
+#define MAX_NUM_NBIOT_CELEVELS    3
+typedef struct NbIoTRrcConfigurationReq_s {
+  uint32_t            cell_identity;
+
+  uint16_t            tac;
+
+  uint16_t	      mcc;
+  uint16_t	      mnc;
+  uint8_t	      mnc_digit_length;
+  lte_frame_type_t	  frame_type;
+  uint8_t                 tdd_config;
+  uint8_t                 tdd_config_s;
+  lte_prefix_type_t       prefix_type;
+  lte_prefix_type_t	  prefix_type_UL;
+  int16_t                 eutra_band;
+  uint32_t                downlink_frequency;
+  int32_t                 uplink_frequency_offset;
+  int16_t                 Nid_cell;// for testing, change later
+  int16_t                 N_RB_DL;// for testing, change later
+  //RACH
+  long					  rach_raResponseWindowSize_NB;
+  long					  rach_macContentionResolutionTimer_NB;
+  long					  rach_powerRampingStep_NB;
+  long					  rach_preambleInitialReceivedTargetPower_NB;
+  long					  rach_preambleTransMax_CE_NB;
+  //BCCH
+  long					  bcch_modificationPeriodCoeff_NB;
+  //PCCH
+  long					  pcch_defaultPagingCycle_NB;
+  long					  pcch_nB_NB;
+  long					  pcch_npdcch_NumRepetitionPaging_NB;
+  //NPRACH
+  long					  nprach_CP_Length;
+  long					  nprach_rsrp_range;
+  long					  nprach_Periodicity[MAX_NUM_NBIOT_CELEVELS];
+  long					  nprach_StartTime[MAX_NUM_NBIOT_CELEVELS];
+  long					  nprach_SubcarrierOffset[MAX_NUM_NBIOT_CELEVELS];
+  long					  nprach_NumSubcarriers[MAX_NUM_NBIOT_CELEVELS];
+  long					  numRepetitionsPerPreambleAttempt_NB[MAX_NUM_NBIOT_CELEVELS];
+  long					  nprach_SubcarrierMSG3_RangeStart;
+  long					  maxNumPreambleAttemptCE_NB;
+  long					  npdcch_NumRepetitions_RA[MAX_NUM_NBIOT_CELEVELS];
+  long					  npdcch_StartSF_CSS_RA[MAX_NUM_NBIOT_CELEVELS];
+  long					  npdcch_Offset_RA[MAX_NUM_NBIOT_CELEVELS];
+  //NPDSCH
+  long					  npdsch_nrs_Power;
+  //NPUSCH
+  long					  npusch_ack_nack_numRepetitions_NB;
+  long					  npusch_srs_SubframeConfig_NB;
+  long					  npusch_threeTone_CyclicShift_r13;
+  long					  npusch_sixTone_CyclicShift_r13;
+  BOOLEAN_t				  npusch_groupHoppingEnabled;
+  long					  npusch_groupAssignmentNPUSCH_r13;
+
+  //DL_GapConfig
+  long					  dl_GapThreshold_NB;
+  long	 				  dl_GapPeriodicity_NB;
+  long	 				  dl_GapDurationCoeff_NB;
+  //Uplink power control Common
+  long					  npusch_p0_NominalNPUSCH;
+  long					  npusch_alpha;
+  long					  deltaPreambleMsg3;
+  //UE timers and constants
+  long					  ue_TimersAndConstants_t300_NB;
+  long					  ue_TimersAndConstants_t301_NB;
+  long					  ue_TimersAndConstants_t310_NB;
+  long					  ue_TimersAndConstants_t311_NB;
+  long					  ue_TimersAndConstants_n310_NB;
+  long					  ue_TimersAndConstants_n311_NB;
+} NbIoTRrcConfigurationReq;
+
 
 // UE: NAS -> RRC messages
 typedef kenb_refresh_req_t      NasKenbRefreshReq;
diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h
index 530365828dbaca39d594d5d278efb3cc73b29727..92d1ff4128fb5413dbd71de4e98eed9157eac15b 100644
--- a/openair2/COMMON/tasks_def.h
+++ b/openair2/COMMON/tasks_def.h
@@ -40,6 +40,10 @@ SUB_TASK_DEF(TASK_L2L1,     TASK_PDCP_ENB,              200)
 
 ///   Radio Resource Control task
 TASK_DEF(TASK_RRC_ENB,  TASK_PRIORITY_MED,          200)
+
+// Define here for now
+TASK_DEF(TASK_RRC_ENB_NB_IoT,  TASK_PRIORITY_MED,          200)
+
 ///   S1ap task
 /// RAL task for ENB
 TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200)
diff --git a/openair2/ENB_APP/nbiot_config.c b/openair2/ENB_APP/NB_IoT_config.c
similarity index 98%
rename from openair2/ENB_APP/nbiot_config.c
rename to openair2/ENB_APP/NB_IoT_config.c
index 3862a0140330326b0663c7fa1175be6428d303f5..09e22ef8457b17578be6f03b9a17e4d3b8988607 100644
--- a/openair2/ENB_APP/nbiot_config.c
+++ b/openair2/ENB_APP/NB_IoT_config.c
@@ -33,13 +33,6 @@
 #include "log.h"
 #include "log_extern.h"
 #include "assertions.h"
-#include "enb_config.h"
-#include "UTIL/OTG/otg.h"
-#include "UTIL/OTG/otg_externs.h"
-#if defined(OAI_EMU)
-# include "OCG.h"
-# include "OCG_extern.h"
-#endif
 #if defined(ENABLE_ITTI)
 # include "intertask_interface.h"
 # if defined(ENABLE_USE_MME)
@@ -47,16 +40,14 @@
 #   include "sctp_eNB_task.h"
 # endif
 #endif
-#include "sctp_default_values.h"
 #include "SystemInformationBlockType2.h"
-#include "LAYER2/MAC/extern.h"
+
 #include "PHY/extern.h"
 #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
-
 #include "common/config/config_userapi.h"
 #include "RRC_config_tools.h"
 #include "RRC_paramsvalues.h"
-#include "nbiot_paramdef.h"
+#include "NB_IoT_paramdef.h"
 #include "L1_paramdef.h"
 #include "MACRLC_paramdef.h"
 #include "LAYER2/MAC/proto_NB_IoT.h"
diff --git a/openair2/ENB_APP/nbiot_config.h b/openair2/ENB_APP/NB_IoT_config.h
similarity index 100%
rename from openair2/ENB_APP/nbiot_config.h
rename to openair2/ENB_APP/NB_IoT_config.h
diff --git a/openair2/ENB_APP/NB_IoT_interface.c b/openair2/ENB_APP/NB_IoT_interface.c
new file mode 100644
index 0000000000000000000000000000000000000000..30ffbb3bb550f6fdcb1cc19075e120df2dac5d9b
--- /dev/null
+++ b/openair2/ENB_APP/NB_IoT_interface.c
@@ -0,0 +1,58 @@
+/*
+ * 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.1  (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 openair2/ENB_APP/NB_IoT_interface.c
+ * \brief: load library implementing coding/decoding algorithms
+ * \date 2018
+ * \version 0.1
+ * \note
+ * \warning
+ */
+#define _GNU_SOURCE 
+#include <sys/types.h>
+
+
+#include "openair1/PHY/extern.h"
+#include "common/utils/load_module_shlib.h" 
+#define NBIOT_INTERFACE_SOURCE
+#include "NB_IoT_interface.h"
+
+
+
+
+int load_NB_IoT(void) {
+ int ret;
+ RCConfig_NbIoT_f_t RCConfig;
+ loader_shlibfunc_t shlib_fdesc[]=NBIOT_INTERFACE_FLIST; 
+
+     ret=load_module_shlib(NBIOT_MODULENAME,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t));
+     if (ret) {
+        return ret;
+     }
+     RCConfig = get_shlibmodule_fptr(NBIOT_MODULENAME,NBIOT_RCCONFIG_FNAME );
+     if (RCConfig == NULL) {
+        return -1;
+     } 
+ 
+     RCConfig(&RC);
+return 0;
+}
+
diff --git a/openair2/ENB_APP/NB_IoT_interface.h b/openair2/ENB_APP/NB_IoT_interface.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3454b077bc1cc64aa514c5abed78c7a8c53138e
--- /dev/null
+++ b/openair2/ENB_APP/NB_IoT_interface.h
@@ -0,0 +1,50 @@
+/*
+ *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.1  (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 openair2/ENB_APP/NB_IoT_interface.h
+ * \brief: api interface for nb-iot application
+ * \date 2018
+ * \version 0.1
+ * \note
+ * \warning
+ */
+#ifndef NBIOT_INTERFACE_H
+#define NBIOT_INTERFACE_H
+
+
+#define NBIOT_MODULENAME "NB_IoT"
+
+typedef void(*RCConfig_NbIoT_f_t)(RAN_CONTEXT_t *RC);
+#define NBIOT_RCCONFIG_FNAME "RCConfig_NbIoT"
+
+#ifdef NBIOT_INTERFACE_SOURCE
+
+#define NBIOT_INTERFACE_FLIST {\
+{NBIOT_RCCONFIG_FNAME,NULL},\
+}
+
+#else /* NBIOT_INTERFACE_SOURCE */
+
+extern int load_NB_IoT(void); 
+
+#endif
+
+#endif
diff --git a/openair2/ENB_APP/nbiot_paramdef.h b/openair2/ENB_APP/NB_IoT_paramdef.h
similarity index 100%
rename from openair2/ENB_APP/nbiot_paramdef.h
rename to openair2/ENB_APP/NB_IoT_paramdef.h
diff --git a/openair2/LAYER2/MAC/config_NB_IoT.h b/openair2/LAYER2/MAC/config_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e497e3b0f407b9c3da8fd7d357375a5596f8422
--- /dev/null
+++ b/openair2/LAYER2/MAC/config_NB_IoT.h
@@ -0,0 +1,301 @@
+
+/*! \file config_NB_IoT.h
+ * \brief configured structures used by scheduler
+ * \author  NTUST BMW Lab./
+ * \date 2017
+ * \email: 
+ * \version 1.0
+ *
+ */
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+//#include "NB_IoT_Message_definitions.h"
+
+#define NUMBER_OF_SIBS_MAX_NB_IoT 6
+
+///MIB
+typedef enum operationModeInf{
+    iNB_IoTand_SamePCI_r13          = 1,
+    iNB_IoTand_DifferentPCI_r13     = 2,
+    guardband_r13               = 3,
+    standalone_r13              = 4
+}operationModeInf_t;
+
+///SIB1_SchedulingInfo_NB_IoT_r13
+typedef enum si_Periodicity{
+    si_Periodicity_rf64=640,
+    si_Periodicity_rf128=1280,
+    si_Periodicity_rf256=2560,
+    si_Periodicity_rf512=5120,
+    si_Periodicity_rf1024=10240,
+    si_Periodicity_rf2048=20480,
+    si_Periodicity_rf4096=40960
+}si_Periodicity_NB_IoT;
+
+typedef enum si_RepetitionPattern{
+    si_RepetitionPattern_every2ndRF=0,
+    si_RepetitionPattern_every4thRF,
+    si_RepetitionPattern_every8thRF,
+    si_RepetitionPattern_every16thRF
+}si_RepetitionPattern_NB_IoT;
+
+typedef enum sib_MappingInfo{
+    sib2_v=0x1,
+    sib3_v=0x2,
+    sib4_v=0x4,
+    sib5_v=0x8,
+    sib14_v=0x10,
+    sib16_v=0x20
+}sib_MappingInfo_NB_IoT;
+
+typedef enum si_TB{
+    si_TB_56=2,
+    si_TB_120=2,
+    si_TB_208=8,
+    si_TB_256=8,
+    si_TB_328=8,
+    si_TB_440=8,
+    si_TB_552=8,
+    si_TB_680=8
+}si_TB_NB_IoT;
+
+///RACH_ConfigCommon configuration
+
+typedef enum ra_ResponseWindowSize{
+    ra_ResponseWindowSize_pp2=2,
+    ra_ResponseWindowSize_pp3=3,
+    ra_ResponseWindowSize_pp4=4,
+    ra_ResponseWindowSize_pp5=5,
+    ra_ResponseWindowSize_pp6=6,
+    ra_ResponseWindowSize_pp7=7,
+    ra_ResponseWindowSize_pp8=8,
+    ra_ResponseWindowSize_pp10=10
+}ra_ResponseWindowSize_NB_IoT;
+
+typedef enum mac_ContentionResolutionTimer{
+    mac_ContentionResolutionTimer_pp1=1,
+    mac_ContentionResolutionTimer_pp2=2,
+    mac_ContentionResolutionTimer_pp3=3,
+    mac_ContentionResolutionTimer_pp4=4,
+    mac_ContentionResolutionTimer_pp8=8,
+    mac_ContentionResolutionTimer_pp16=16,
+    mac_ContentionResolutionTimer_pp32=32,
+    mac_ContentionResolutionTimer_pp64=64
+}mac_ContentionResolutionTimer_NB_IoT;
+
+///NPRACH_ConfigSIB configuration
+
+typedef enum nprach_Periodicity{
+    nprach_Periodicity_ms40=40,
+    nprach_Periodicity_ms80=80,
+    nprach_Periodicity_ms160=160,
+    nprach_Periodicity_ms240=240,
+	nprach_Periodicity_ms320=320,
+    nprach_Periodicity_ms640=640,
+    nprach_Periodicity_ms1280=1280,
+    nprach_Periodicity_ms2560=2560
+}nprach_Periodicity_NB_IoT;
+
+typedef enum nprach_StartTime{
+    nprach_StartTime_ms8=8,
+    nprach_StartTime_ms16=16,
+    nprach_StartTime_ms32=32,
+    nprach_StartTime_ms64=64,
+    nprach_StartTime_ms128=128,
+    nprach_StartTime_ms256=256,
+    nprach_StartTime_ms512=512,
+    nprach_StartTime_ms1024=1024
+}nprach_StartTime_NB_IoT;
+
+typedef enum nprach_SubcarrierOffset{
+    nprach_SubcarrierOffset_n0=0,
+    nprach_SubcarrierOffset_n12=12,
+    nprach_SubcarrierOffset_n24=24,
+    nprach_SubcarrierOffset_n36=36,
+    nprach_SubcarrierOffset_n2=2,
+    nprach_SubcarrierOffset_n18=18,
+    nprach_SubcarrierOffset_n34=34
+}nprach_SubcarrierOffset_NB_IoT;
+
+typedef enum nprach_NumSubcarriers{
+    nprach_NumSubcarriers_n12=12,
+    nprach_NumSubcarriers_n24=24,
+    nprach_NumSubcarriers_n36=36,
+    nprach_NumSubcarriers_n48=48
+}nprach_NumSubcarriers_NB_IoT;
+
+typedef enum nprach_SubcarrierMSG3_RangeStart{
+    nprach_SubcarrierMSG3_RangeStart_zero=0,
+    nprach_SubcarrierMSG3_RangeStart_oneThird=1/3,
+    nprach_SubcarrierMSG3_RangeStart_twoThird=2/3,
+    nprach_SubcarrierMSG3_RangeStart_one=1
+}nprach_SubcarrierMSG3_RangeStart_NB_IoT;
+
+typedef enum maxNumPreambleAttemptCE{
+    maxNumPreambleAttemptCE_n3=3,
+    maxNumPreambleAttemptCE_n4=4,
+    maxNumPreambleAttemptCE_n5=5,
+    maxNumPreambleAttemptCE_n6=6,
+    maxNumPreambleAttemptCE_n7=7,
+    maxNumPreambleAttemptCE_n8=8,
+    maxNumPreambleAttemptCE_n10=10
+}maxNumPreambleAttemptCE_NB_IoT;
+
+typedef enum numRepetitionsPerPreambleAttempt{
+    numRepetitionsPerPreambleAttempt_n1=1,
+    numRepetitionsPerPreambleAttempt_n2=2,
+    numRepetitionsPerPreambleAttempt_n4=4,
+    numRepetitionsPerPreambleAttempt_n8=8,
+    numRepetitionsPerPreambleAttempt_n16=16,
+    numRepetitionsPerPreambleAttempt_n32=32,
+    numRepetitionsPerPreambleAttempt_n64=64,
+    numRepetitionsPerPreambleAttempt_n128=128
+}numRepetitionsPerPreambleAttempt_NB_IoT;
+
+typedef enum npdcch_NumRepetitions_RA{
+    npdcch_NumRepetitions_RA_r1=1,
+    npdcch_NumRepetitions_RA_r2=2,
+    npdcch_NumRepetitions_RA_r4=4,
+    npdcch_NumRepetitions_RA_r8=8,
+    npdcch_NumRepetitions_RA_r16=16,
+    npdcch_NumRepetitions_RA_r32=32,
+    npdcch_NumRepetitions_RA_r64=64,
+    npdcch_NumRepetitions_RA_r128=128,
+    npdcch_NumRepetitions_RA_r256=256,
+    npdcch_NumRepetitions_RA_r512=512,
+    npdcch_NumRepetitions_RA_r1024=1024,
+    npdcch_NumRepetitions_RA_r2048=2048
+}npdcch_NumRepetitions_RA_NB_IoT;
+
+typedef enum npdcch_StartSF_CSS_RA{
+    npdcch_StartSF_CSS_RA_v1dot5=3/2,
+    npdcch_StartSF_CSS_RA_v2=2,
+    npdcch_StartSF_CSS_RA_v4=4,
+    npdcch_StartSF_CSS_RA_v8=8,
+    npdcch_StartSF_CSS_RA_v16=16,
+    npdcch_StartSF_CSS_RA_v32=32,
+    npdcch_StartSF_CSS_RA_v48=48,
+    npdcch_StartSF_CSS_RA_v64=64
+}npdcch_StartSF_CSS_RA_NB_IoT;
+
+typedef enum npdcch_Offset_RA{
+    zero=0,
+    oneEighth=1/8,
+    oneFourth=1/4,
+    threeEighth=3/8
+}npdcch_Offset_RA_NB_IoT;
+
+typedef enum si_window_length_e{
+    ms160=160,
+    ms320=320,
+    ms480=480,
+    ms640=640,
+    ms960=960,
+    ms1280=1280,
+    ms1600=1600
+}si_window_length_t;
+
+typedef enum si_periodicity_e{
+    rf64=640,
+    rf128=1280,
+    rf256=2560,
+    rf512=5120,
+	rf1024=10240,
+    rf2048=20480,
+    rf4096=40960
+}si_periodicity_t;
+
+typedef enum si_repetition_pattern_e{
+    every2ndRF=20,
+    every4thRF=40,
+	every8thRF=80,
+    every16thRF=160
+}si_repetition_pattern_t;
+
+typedef enum si_tb_e{
+    b56=2,
+    b120=2,
+    b208=8,
+    b256=8,
+    b328=8,
+    b440=8,
+    b552=8,
+    b680=8
+}si_tb_t;
+
+
+typedef struct sibs_NB_IoT_sched_s{
+	si_periodicity_t si_periodicity;
+    si_repetition_pattern_t si_repetition_pattern;
+    sib_MappingInfo_NB_IoT sib_mapping_info;   //bit vector
+    si_tb_t si_tb;
+
+}sibs_NB_IoT_sched_t;
+
+
+///-------------------------------------------------------MAC--------------------------------------------------------------------///
+typedef struct sib1_NB_IoT_sched_s{
+    int repetitions;    //  4, 8, 16
+    int starting_rf;
+}sib1_NB_IoT_sched_t;
+
+typedef struct {
+
+    uint32_t    mac_ra_ResponseWindowSize_NB_IoT;
+    uint32_t    mac_ContentionResolutionTimer_NB_IoT;
+
+}mac_RACH_ConfigCommon_NB_IoT;
+
+typedef struct {
+
+    uint32_t    mac_nprach_Periodicity_NB_IoT;
+    uint32_t    mac_nprach_StartTime_NB_IoT;
+    uint32_t    mac_nprach_SubcarrierOffset_NB_IoT;
+    uint32_t    mac_nprach_NumSubcarriers_NB_IoT;
+    uint32_t    mac_nprach_SubcarrierMSG3_RangeStart_NB_IoT;
+    uint32_t    mac_maxNumPreambleAttemptCE_NB_IoT;
+    uint32_t    mac_numRepetitionsPerPreambleAttempt_NB_IoT;
+	//	css
+    uint32_t    mac_npdcch_NumRepetitions_RA_NB_IoT;		//	rmax
+    uint32_t    mac_npdcch_StartSF_CSS_RA_NB_IoT;			//	G
+    uint32_t    mac_npdcch_Offset_RA_NB_IoT;				//	alpha offset
+
+}mac_NPRACH_ConfigSIB_NB_IoT;
+
+typedef struct{
+    //npdcch-NumRepetitions-r13
+    uint32_t R_max;
+    //npdcch-StartSF-USS-r13
+    double G;
+    //npdcch-Offset-USS-r13
+    double a_offset;
+}npdcch_ConfigDedicated_NB_IoT;
+
+typedef struct rrc_config_NB_IoT_s{
+
+    ///MIB
+    uint16_t schedulingInfoSIB1_NB_IoT;
+
+    ///SIB1
+    uint32_t cellIdentity_NB_IoT;
+
+	sib1_NB_IoT_sched_t sib1_NB_IoT_sched_config;
+	///SIBS
+	sibs_NB_IoT_sched_t sibs_NB_IoT_sched[NUMBER_OF_SIBS_MAX_NB_IoT];
+	si_window_length_t si_window_length;
+	uint32_t si_radio_frame_offset;
+
+    ///SIB2 mac_RACH_ConfigCommon_NB_IoT
+    mac_RACH_ConfigCommon_NB_IoT mac_RACH_ConfigCommon[3];
+
+    ///SIB2 mac_NPRACH_ConfigSIB_NB_IoT
+    mac_NPRACH_ConfigSIB_NB_IoT mac_NPRACH_ConfigSIB[3];
+
+    ///NPDCCH Dedicated config
+    npdcch_ConfigDedicated_NB_IoT npdcch_ConfigDedicated[3];
+
+}rrc_config_NB_IoT_t;
+
+#endif
diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..a427de5b2cfdf37fc5f9cd7df40144f893b0c3e0
--- /dev/null
+++ b/openair2/LAYER2/MAC/defs_NB_IoT.h
@@ -0,0 +1,543 @@
+
+/*! \file defs_NB_IoT.c
+ * \brief MAC layer structures
+ * \author  NTUST BMW Lab./
+ * \date 2017
+ * \email: 
+ * \version 1.0
+ *
+ */
+#ifndef __LAYER2_MAC_DEFS_NB_IOT_H__
+#define __LAYER2_MAC_DEFS_NB_IOT_H__
+#ifdef USER_MODE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+//#include "COMMON/openair_defs.h"
+#include "COMMON/platform_constants.h"
+#include "COMMON/mac_rrc_primitives.h"
+#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
+//#include "PHY/defs.h"
+#include "PHY/defs_L1_NB_IoT.h"
+#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
+#include "config_NB_IoT.h"
+//  MAC definition
+#define MAX_FRAME 0xfffff
+#define NUM_FRAME 0x100000
+#define MAX_SUBFRAME 10485760
+
+#define MAX(a, b) (((a)>(b))?(a):(b))
+
+//  RA-RNTI: 1+SFN_id>>2
+#define RA_RNTI_LOW   0x0001  //  SFN_id = 0
+#define RA_RNTI_HIGH  0x0100  //  SFN_id = 1023
+#define C_RNTI_LOW  0x0101
+#define C_RNTI_HIGH 
+
+// ULSCH LCHAN IDs
+/*!\brief LCID of extended power headroom for ULSCH */
+#define EXTENDED_POWER_HEADROOM 25
+/*!\brief LCID of power headroom for ULSCH */
+#define POWER_HEADROOM 26
+/*!\brief LCID of CRNTI for ULSCH */
+#define CRNTI 27
+/*!\brief LCID of truncated BSR for ULSCH */
+#define TRUNCATED_BSR 28
+/*!\brief LCID of short BSR for ULSCH */
+#define SHORT_BSR 29
+/*!\brief LCID of long BSR for ULSCH */
+#define LONG_BSR 30
+/*! \brief Values of CCCH LCID for DLSCH */ 
+#define CCCH_LCHANID 0
+/*!\brief Values of BCCH logical channel */
+#define BCCH 3  // SI 
+/*!\brief Values of PCCH logical channel */
+#define PCCH 4  // Paging 
+/*!\brief Value of CCCH / SRB0 logical channel */
+#define CCCH 0  // srb0
+/*!\brief DCCH / SRB1 logical channel */
+#define DCCH 1  // srb1
+/*!\brief DCCH1 / SRB2  logical channel */
+#define DCCH1 2 // srb2
+/*!\brief DTCH DRB1  logical channel */
+#define DTCH 3 // LCID
+/*!\brief MCCH logical channel */
+#define MCCH 4 
+/*!\brief MTCH logical channel */
+#define MTCH 1 
+// DLSCH LCHAN ID
+/*!\brief LCID of UE contention resolution identity for DLSCH*/
+#define UE_CONT_RES 28
+/*!\brief LCID of timing advance for DLSCH */
+#define TIMING_ADV_CMD 29
+/*!\brief LCID of discontinous reception mode for DLSCH */
+#define DRX_CMD 30
+/*!\brief LCID of padding LCID for DLSCH */
+#define SHORT_PADDING 31
+
+
+typedef enum tone_type_e
+{
+  sixtone = 0,
+  threetone,
+  singletone1,
+  singletone2,
+  singletone3
+}tone_type_t;
+
+typedef enum channel_NB_IoT_e
+{
+  NPDCCH = 0,
+  NPUSCH,
+  NPDSCH
+}channel_NB_IoT_t;
+
+typedef enum{
+  UL = 0,
+  DL
+}message_direction_t;
+
+#define MAX_NUMBER_OF_UE_MAX_NB_IoT 20
+#define SCH_PAYLOAD_SIZE_MAX_NB_IoT 320
+#define MAX_NUMBER_OF_SIBs_NB_IoT 16
+
+/*!\brief Values of BCCH0 logical channel for MIB*/
+#define BCCH0_NB_IoT 11 // MIB-NB_IoT
+/*!\brief Values of BCCH1 logical channel for SIBs */
+#define BCCH1_NB_IoT 12 // SI-SIB-NB_IoTs
+/*!\brief Values of PCCH logical channel */
+#define PCCH_NB_IoT 13  // Paging XXX not used for the moment
+#define MCCH_NB_IoT 14
+/*!\brief Value of CCCH / SRB0 logical channel */
+#define CCCH_NB_IoT 0  // srb0 ---> XXX exactly the same as in LTE (commented for compilation purposes)
+/*!\brief DCCH0 / SRB1bis logical channel */
+#define DCCH0_NB_IoT 3  // srb1bis
+/*!\brief DCCH1 / SRB1  logical channel */
+#define DCCH1_NB_IoT 1 // srb1 //XXX we redefine it for the SRB1
+/*!\brief DTCH0 DRB0  logical channel */
+#define DTCH0_NB_IoT 4 // DRB0
+/*!\brief DTCH1 DRB1  logical channel */
+#define DTCH1_NB_IoT 5 // DRB1
+/*Index of UE contention resoulution logical channel*/
+#define UE_CONTENTION_RESOLUTION 28
+/*Index of TIMING_ADVANCE logical channel*/
+#define TIMING_ADVANCE 29
+/*Index of DRX_COMMAND logical channel*/
+#define DRX_COMMAND 30
+/*Index of PADDING logical channel*/
+#define PADDING 31
+
+
+/// NPRACH-ParametersList-NB_IoT-r13 from 36.331 RRC spec defined in PHY
+/*typedef struct NPRACH_Parameters_NB_IoT{
+
+    /// the period time for nprach
+    int nprach_Periodicity;
+    /// for the start time for the NPRACH resource from 40ms-2560ms
+    int nprach_StartTime;
+    /// for the subcarrier of set to the NPRACH preamble from n0 - n34
+    int nprach_SubcarrierOffset;
+    ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48)
+    int nprach_NumSubcarriers;
+    /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1
+    int nprach_SubcarrierMSG3_RangeStart;
+    /// The max preamble transmission attempt for the CE level from 1 - 128
+    int maxNumPreambleAttemptCE;
+    /// Number of NPRACH repetitions per attempt for each NPRACH resource
+    int numRepetitionsPerPreambleAttempt;
+    /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax)
+    int npdcch_NumRepetitions_RA;
+    /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4)
+    int npdcch_StartSF_CSS_RA;
+    /// Fractional period offset of starting subframe for NPDCCH common search space
+    int npdcch_Offset_RA;
+
+} nprach_parameters_NB_IoT_t;*/
+
+/*! \brief Downlink SCH PDU Structure */
+typedef struct {
+  uint8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT];
+  uint32_t pdu_size;
+} __attribute__ ((__packed__)) DLSCH_PDU_NB_IoT;
+
+/*! \brief eNB template for UE context information  */
+typedef struct {
+    // C-RNTI of UE
+  rnti_t rnti;
+  // UE CE level
+  int CE_level;
+  // Direction of transmission(DL:0\UL:1\NONE:-1)
+  int32_t direction;
+  // DCI Reptition
+  uint32_t R_dci;
+  // MAX repetition
+  uint32_t R_max;
+
+  // HARQ round
+  uint32_t HARQ_round;
+  /*Downlink information*/
+
+  /// DLSCH pdu
+  DLSCH_PDU_NB_IoT DLSCH_pdu;
+  // PDU size
+  uint32_t DLSCH_pdu_size;
+  // Data Reptition
+  uint32_t R_dl;
+  // MCS index
+  uint32_t I_mcs_dl;
+  // total downlink buffer DCCH0_NB_IoT
+  uint32_t dl_buffer_DCCH0_NB_IoT;
+  // NDI
+  int oldNDI_DL;
+  //HARQ ACK/NACK repetition
+  uint32_t R_harq;
+
+  /*Uplink information*/
+  int oldNDI_UL;
+  // Uplink data repeat, now just follow the rach repeat number
+  uint32_t R_ul;
+  // PHR value (0-3)
+  uint32_t PHR;
+  // The uplink data size from BSR or DVI
+  uint32_t ul_total_buffer;
+  // Determine if this UE support multi-tone transmission or not
+  int multi_tone;
+  // Next UE_template ID
+  int next;
+  // Previous UE_template ID
+  int prev;
+  // MSG4 complete
+  int RRC_connected;
+  // UE active flag
+  int active;
+
+} UE_TEMPLATE_NB_IoT;
+
+/*36331 NPDCCH-ConfigDedicated-NB_IoT*/
+typedef struct{
+  //npdcch-NumRepetitions-r13
+  uint32_t R_max;
+  //npdcch-StartSF-USS-r13
+  double G;
+  //npdcch-Offset-USS-r13
+  double a_offset;
+  //NPDCCH period
+  uint32_t T;
+  //Starting subfrane of Search Space which is mod T
+  uint32_t ss_start_uss;
+}NPDCCH_config_dedicated_NB_IoT_t;
+
+
+/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
+typedef struct {
+
+  /// DCI template and MAC connection parameters for UEs
+  UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_NUMBER_OF_UE_MAX_NB_IoT];
+
+  /// NPDCCH Period and searching space info
+  NPDCCH_config_dedicated_NB_IoT_t NPDCCH_config_dedicated;
+  //int next[MAX_NUMBER_OF_UE_MAX_NB_IoT];
+  // -1:No UE in list
+  int head;
+  // -1:No UE in list
+  int tail;
+  int num_UEs;
+  //boolean_t active[MAX_NUMBER_OF_UE_MAX_NB_IoT];
+
+} UE_list_NB_IoT_t;
+
+
+typedef struct{
+
+  // flag to indicate scheduing MIB-NB_IoT
+  uint8_t flag_MIB;
+  // flag to indicate scheduling SIB1-NB_IoT
+  uint8_t flag_SIB1;
+  // flag to indicate scheduling SIBs-NB_IoT
+  uint8_t flag_SIBs[MAX_NUMBER_OF_SIBs_NB_IoT];
+  // flag to indicate scheduling type2 NPDCCH CSS with different CE level
+  uint8_t flag_type2_css[3];
+  // flag to indicate scheduling type1 NPDCCH CSS with different CE level
+  uint8_t flag_type1_css[3];
+  // flag to indicate scheduling NPDCCH USS with UE list
+  uint8_t flag_uss[MAX_NUMBER_OF_UE_MAX_NB_IoT];
+  // flag to indicate scheduling sib1/MIB
+  uint8_t flag_fix_scheduling;
+  // number of the type2 css to schedule in this period
+  uint8_t num_type2_css_run;
+  // number of the type1 css to schedule in this period
+  uint8_t num_type1_css_run;
+  // number of the uss to schedule in this period
+  uint8_t num_uss_run;
+
+}scheduling_flag_t;
+
+typedef struct available_resource_UL_s{
+
+    ///Resource start subframe
+    uint32_t start_subframe;
+    ///Resource end subframe
+    uint32_t end_subframe;
+    // pointer to next node
+    struct available_resource_UL_s *next, *prev;
+
+}available_resource_UL_t;
+
+typedef struct available_resource_DL_s{
+  uint32_t start_subframe;
+  uint32_t end_subframe;
+
+  struct available_resource_DL_s *next, *prev;
+}available_resource_DL_t;
+
+/*Structure used for scheduling*/
+typedef struct{
+  //resource position info.
+  uint32_t sf_end,sf_start;
+  //resource position info. separate by HyperSF, Frame, Subframe
+  uint32_t start_h, end_h;
+  uint32_t start_f, end_f;
+  uint32_t start_sf, end_sf;
+  //whcih available resource node is used
+  available_resource_DL_t *node;
+}sched_temp_DL_NB_IoT_t;
+
+/*!\brief  MAC subheader short with 7bit Length field */
+typedef struct {
+  uint8_t LCID:5;  // octet 1 LSB
+  uint8_t E:1;
+  uint8_t F2:1;
+  uint8_t R:1;     // octet 1 MSB
+  uint8_t L:7;     // octet 2 LSB
+  uint8_t F:1;     // octet 2 MSB
+} __attribute__((__packed__))SCH_SUBHEADER_SHORT_NB_IoT;
+typedef struct {
+  uint8_t LCID:5;   // octet 1 LSB
+  uint8_t E:1;
+  uint8_t F2:1;
+  uint8_t R:1;      // octet 1 MSB
+  uint8_t L_MSB:7;
+  uint8_t F:1;      // octet 2 MSB
+  uint8_t L_LSB:8;
+} __attribute__((__packed__))SCH_SUBHEADER_LONG_NB_IoT;
+typedef struct {
+  uint8_t LCID:5;   // octet 1 LSB
+  uint8_t E:1;
+  uint8_t F2:1;
+  uint8_t R:1;      // octet 1 MSB
+  uint8_t L_MSB:8;      // octet 2 MSB
+  uint8_t L_LSB:8;
+} __attribute__((__packed__))SCH_SUBHEADER_LONG_EXTEND_NB_IoT;
+/*!\brief MAC subheader short without length field */
+typedef struct {
+  uint8_t LCID:5;
+  uint8_t F2:1;
+  uint8_t E:1;
+  uint8_t R:1;
+} __attribute__((__packed__))SCH_SUBHEADER_FIXED_NB_IoT;
+
+
+/*! \brief Uplink SCH PDU Structure */
+typedef struct {
+  int8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT];         /*!< \brief SACH payload */
+  uint16_t Pdu_size;
+} __attribute__ ((__packed__)) ULSCH_PDU_NB_IoT;
+
+typedef struct {
+  uint8_t PH:6;
+  uint8_t R:2;
+} __attribute__((__packed__))POWER_HEADROOM_CMD_NB_IoT;
+
+typedef struct {
+  uint8_t RAPID:6;
+  uint8_t T:1;
+  uint8_t E:1;
+} __attribute__((__packed__))RA_HEADER_RAPID_NB_IoT;
+
+/*Structure used for UL scheduling*/
+typedef struct{
+  //resource position info.
+  uint32_t sf_end, sf_start;
+  //resource position info. separate by HyperSF, Frame, Subframe
+  //uint32_t start_h, end_h;
+  //uint32_t start_f, end_f;
+  //uint32_t start_sf, end_sf;
+  // information for allocating the resource
+  int tone;
+  int scheduling_delay;
+  int subcarrier_indication;
+  int ACK_NACK_resource_field;
+  available_resource_UL_t *node;
+}sched_temp_UL_NB_IoT_t;
+
+typedef struct Available_available_resource_DL{
+
+    ///Available Resoruce for sixtone
+    available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame;
+  uint32_t sixtone_end_subframe;
+    ///Available Resoruce for threetone
+    available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame;
+  uint32_t threetone_end_subframe;
+    ///Available Resoruce for singletone1
+    available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame;
+  uint32_t singletone1_end_subframe;
+    ///Available Resoruce for singletone2
+    available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame;
+    uint32_t singletone2_end_subframe;
+  ///Available Resoruce for singletone3
+    available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame;
+  uint32_t singletone3_end_subframe;
+  
+}available_resource_tones_UL_t;
+
+typedef struct schedule_result{
+  // The subframe read by output handler
+  uint32_t output_subframe;
+  // SDU length
+  uint32_t sdu_length;
+  // MAC PDU
+  uint8_t *DLSCH_pdu;
+  // The data direction indicated by this DCI
+  uint8_t direction;
+  // pointer to DCI
+  void *DCI_pdu;
+  // when all the procedure related to this DCI, enable this flag
+  boolean_t DCI_release;
+  // Indicate the channel which to transmit
+  channel_NB_IoT_t channel;
+  // rnti
+  rnti_t rnti;
+  // 0 = TC-RNTI , 1 = RA-RNTI, 2 = P-RNTI, 3 = others
+  uint8_t rnti_type;
+  // 0 = data, 1 = ACK/NACK
+  uint8_t npusch_format;
+  //HARQ ACK/NACK repetition
+  uint32_t R_harq;
+  // pointer to next node
+  struct schedule_result *next;
+
+  uint32_t end_subframe;
+  
+  uint8_t *rar_buffer;
+
+}schedule_result_t;
+
+/*Flag structure used for trigger each scheduler*/
+typedef struct{
+  scheduling_flag_t scheduling_flag;
+  //sched_temp_DL_NB_IoT_t sched_result_DL;
+  //resource grid for Uplink
+  available_resource_tones_UL_t *UL_resource;
+  //scheduling result read by output handler
+  schedule_result_t *schedule_result_list_UL;
+  schedule_result_t *schedule_result_list_DL;
+}SCHEDULE_NB_IoT_t;
+
+typedef struct{
+  uint32_t num_dlsf_per_period;
+  uint16_t *sf_to_dlsf_table;
+  uint16_t *dlsf_to_sf_table;
+}DLSF_INFO_t;
+
+typedef enum ce_level_e{
+  ce0=0,
+  ce1,
+  ce2,
+  ce_level_total
+}ce_level_t;
+
+
+
+/*! \brief eNB template for the Random access information */
+typedef struct RA_TEMPLATE_NB_IoT_s{
+
+  boolean_t active;
+  uint32_t msg3_retransmit_count;
+  uint32_t msg4_retransmit_count;
+  uint16_t ta;
+  uint8_t preamble_index;
+  ce_level_t ce_level;
+  rnti_t ue_rnti;
+  rnti_t ra_rnti;
+  struct RA_TEMPLATE_NB_IoT_s *next, *prev;
+  boolean_t wait_msg4_ack;
+  boolean_t wait_msg3_ack;
+  uint8_t rar_buffer[7];
+
+} RA_TEMPLATE_NB_IoT;
+
+typedef struct RA_template_list_s{
+  RA_TEMPLATE_NB_IoT *head;
+  RA_TEMPLATE_NB_IoT *tail;
+}RA_template_list_t;
+
+
+/*! \brief top level eNB MAC structure */
+typedef struct eNB_MAC_INST_NB_IoT_s {
+  /// Ethernet parameters for northbound midhaul interface
+  eth_params_t         eth_params_n;
+  /// Ethernet parameters for fronthaul interface
+  eth_params_t         eth_params_s;
+
+  uint8_t Mod_id;
+  //  System
+  uint32_t hyper_system_frame;
+  uint32_t system_frame;
+  uint32_t sub_frame;
+
+  uint32_t current_subframe;
+  /// Pointer to IF module instance for PHY
+  IF_Module_t *if_inst;
+  //  RA
+  RA_template_list_t RA_msg2_list;
+  RA_template_list_t RA_msg3_list;
+  RA_template_list_t RA_msg4_list;
+
+  RA_TEMPLATE_NB_IoT RA_template[MAX_NUMBER_OF_UE_MAX_NB_IoT];
+
+  //int32_t last_tx_subframe;
+
+  //  for tool
+  int32_t sib1_flag[64];
+  int32_t sib1_count[64];
+  int32_t sib1_period;
+  uint16_t dlsf_table[64];
+  int32_t sibs_table[256];
+
+  //  channel config
+
+  //USS list
+  //Number of USS period is used
+  int num_uss_list;
+  UE_list_NB_IoT_t *UE_list_spec;
+
+  scheduling_flag_t scheduling_flag;
+
+  uint32_t schedule_subframe_DL;
+  uint32_t schedule_subframe_UL;
+
+  rrc_config_NB_IoT_t rrc_config;
+
+  nfapi_config_request_t config;
+
+   IF_Module_NB_IoT_t            *if_inst_NB_IoT;
+} eNB_MAC_INST_NB_IoT;
+
+// actually not here, but for now put it here
+typedef  struct {
+  uint32_t       bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */
+  uint32_t       pdus_in_buffer;  /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */
+  uint32_t       head_sdu_creation_time;           /*!< \brief Head SDU creation time. */
+  uint32_t       head_sdu_remaining_size_to_send;  /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */
+  boolean_t      head_sdu_is_segmented;     /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */
+} mac_rlc_status_resp_NB_IoT_t;
+
+// global variables
+
+nprach_parameters_NB_IoT_t nprach_list[3];
+
+//DLSF Table
+DLSF_INFO_t DLSF_information;
+
+#endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */
diff --git a/openair2/LAYER2/MAC/proto_NB_IoT.h b/openair2/LAYER2/MAC/proto_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..e493275987e2492f1372e97da12dedfa2def3e01
--- /dev/null
+++ b/openair2/LAYER2/MAC/proto_NB_IoT.h
@@ -0,0 +1,198 @@
+/*
+ * 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 LAYER2/MAC/proto_NB_IoT.h
+ * \brief MAC functions prototypes for eNB and UE
+ * \author Navid Nikaein and Raymond Knopp
+ * \date 2010 - 2014
+ * \email navid.nikaein@eurecom.fr
+ * \version 1.0
+ */
+
+#ifndef __LAYER2_MAC_PROTO_NB_IoT_H__
+#define __LAYER2_MAC_PROTO_NB_IoT_H__
+
+#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h"
+#include "LAYER2/MAC/defs_NB_IoT.h"
+#include "COMMON/platform_types.h"
+#include "openair2/RRC/LITE/defs_NB_IoT.h"
+/** \addtogroup _mac
+ *  @{
+ */
+
+int l2_init_eNB_NB_IoT(void);
+
+///config
+void rrc_mac_config_req_NB_IoT(
+    module_id_t                             Mod_idP,
+    int                                     CC_idP,
+    int                                     rntiP,
+    rrc_eNB_carrier_data_NB_IoT_t           *carrier,
+    SystemInformationBlockType1_NB_t        *sib1_NB_IoT,
+    RadioResourceConfigCommonSIB_NB_r13_t   *radioResourceConfigCommon,
+    PhysicalConfigDedicated_NB_r13_t        *physicalConfigDedicated,
+    LogicalChannelConfig_NB_r13_t           *logicalChannelConfig,            //FIXME: decide how to use it
+    uint8_t                                 ded_flag,
+    uint8_t                                 ue_list_ded_num);
+
+///system
+void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst);
+//void init_rrc_NB_IoT();
+void release_mac_inst(uint8_t order);
+eNB_MAC_INST_NB_IoT *get_mac_inst(uint8_t order);
+uint8_t register_mac_inst(eNB_MAC_INST_NB_IoT *inst, uint8_t order);
+
+///tool
+void init_tool(sib1_NB_IoT_sched_t *config);
+void UE_info_setting(UE_TEMPLATE_NB_IoT *UE_info);
+UE_TEMPLATE_NB_IoT *get_ue_from_rnti(eNB_MAC_INST_NB_IoT *inst, rnti_t rnti);
+	
+///scheduler
+void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe);
+void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe);
+
+//Calvin temp define self-tools
+int init_debug(eNB_MAC_INST_NB_IoT *inst);
+void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst);
+void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe);
+available_resource_DL_t *check_sibs_resource(eNB_MAC_INST_NB_IoT *mac_inst, int check_start_subframe, int check_end_subframe, int num_subframe, int *residual_subframe, int *out_last_subframe, int *out_first_subframe);
+uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe);
+void init(eNB_MAC_INST_NB_IoT *mac_inst);
+void init_dl_list(eNB_MAC_INST_NB_IoT *mac_inst);
+int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
+void fill_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, available_resource_DL_t *node, int start_subframe, int end_subframe, schedule_result_t *new_node);
+available_resource_DL_t *check_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int check_subframe, int num_subframes, int *out_last_subframe, int *out_first_subframe);
+void print_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst);
+void print_schedule_result_DL(void);
+void print_schedule_result_UL(void);
+void add_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce, uint32_t PHR, uint32_t ul_total_buffer);
+void remove_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce);
+//	SIBs
+void schedule_sibs(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t sibs_order, int start_subframe);
+
+//RA
+void msg3_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti);
+void msg4_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti);
+void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst);
+void init_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint8_t preamble_index, ce_level_t ce_level, uint32_t sfn_id, uint16_t ta);
+void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
+void receive_msg3_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti, uint32_t phr, uint32_t ul_total_buffer);
+void schedule_msg3_retransimission_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
+void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
+void fill_rar_NB_IoT(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template, uint8_t msg3_schedule_delay, uint8_t msg3_rep, sched_temp_UL_NB_IoT_t *schedule_template);
+void receive_msg4_ack_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t rnti);
+
+//USS
+void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int index_ss);
+
+//DATA
+uint8_t *parse_ulsch_header( uint8_t *mac_header,
+                             uint8_t *num_ce,
+                             uint8_t *num_sdu,
+                             uint8_t *rx_ces,
+                             uint8_t *rx_lcids,
+                             uint16_t *rx_lengths,
+                             uint16_t tb_length );
+
+/*******UL Scheduler**********/
+void print_scheduling_result_UL(void);
+void print_available_UL_resource(void);
+/*set nprach configuration at intial time*/
+void setting_nprach(void);
+/*Uplink main scheduler*/
+int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info, uint32_t subframe, uint32_t frame, uint32_t H_SFN);
+/*Check available uplink resource list, if there is available uplink resource, return 0, otherwise, return 1*/
+int Check_UL_resource(uint32_t DL_end, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int multi_tone, int fmt2_flag);
+/*Get I Repetition number in DCI*/
+int get_I_REP(int N_rep);
+/*Get N REP from preamble repeat*/
+int get_N_REP(int CE_level);
+/*Get TBS from mcs, multi-tone, Iru*/
+int get_TBS_UL_NB_IoT(uint32_t mcs,uint32_t multi_tone,int Iru);
+/*get I tbs from mcs and multi-tone*/
+int get_I_TBS_NB_IoT(int x,int y);
+/*Get DCI REP from R max and R*/
+int get_DCI_REP(uint32_t R,uint32_t R_max);
+/*Check single tone resource list*/
+int single_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int fmt2_flag);
+/*Check multi tone resource list*/
+int multi_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info);
+/*Generate scheduling result of DCI N0 and Uplink config*/
+void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subframe, uint32_t UL_subframe, uint32_t UL_end_subframe, DCIFormatN0_t *DCI_inst, rnti_t rnti, uint8_t *ul_debug_str, uint8_t *dl_debug_str);
+/*Adjust UL resource by removing the used resource*/
+void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info);
+/*Initialize resource by nprach configuration*/
+void Initialize_Resource(void);
+/*Function to extend uplink resource grid*/
+//void add_UL_Resource(eNB_MAC_INST_NB_IoT *mac_inst);
+void add_UL_Resource(void);
+/*Get ACK/NAK resource field*/
+int get_resource_field_value(int subcarrier, int k0);
+/*Get DL Repetition index*/
+uint8_t get_index_Rep_dl(uint16_t R);
+
+/*******DL Scheduler********/
+void schedule_DL_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, UE_TEMPLATE_NB_IoT *UE_info, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start);
+int check_resource_NPDCCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, sched_temp_DL_NB_IoT_t *NPDCCH_info, uint32_t cdd_num, uint32_t dci_rep);
+int check_resource_NPDSCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDSCH_info, uint32_t sf_end, uint32_t I_delay, uint32_t R_max, uint32_t R_dl, uint32_t n_sf);
+int check_resource_DL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, uint32_t dlsf_require, sched_temp_DL_NB_IoT_t *schedule_info);
+uint32_t get_I_mcs(int CE_level);
+uint32_t get_max_tbs(uint32_t I_tbs);
+uint32_t get_tbs(uint32_t data_size, uint32_t I_tbs, uint32_t *I_sf);
+uint32_t get_num_sf(uint32_t I_sf);
+uint32_t get_scheduling_delay(uint32_t I_delay, uint32_t R_max);
+uint32_t get_HARQ_delay(int subcarrier_spacing, uint32_t HARQ_delay_index);
+//void generate_scheduling_result_DL(uint32_t DCI_subframe, uint32_t NPDSCH_subframe, uint32_t HARQ_subframe, DCIFormatN1_t *DCI, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu);
+void generate_scheduling_result_DL(sched_temp_DL_NB_IoT_t* DCI_info, sched_temp_DL_NB_IoT_t* NPDSCH_info, sched_temp_UL_NB_IoT_t* HARQ_info, DCIFormatN1_t *DCI_inst, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu);
+void fill_DCI_N1(DCIFormatN1_t *DCI_N1, UE_TEMPLATE_NB_IoT *UE_info, uint32_t scheddly, uint32_t I_sf, uint32_t I_harq);
+//Transfrom source into hyperSF, Frame, Subframe format
+void convert_system_number(uint32_t source_sf,uint32_t *hyperSF, uint32_t *frame, uint32_t *subframe);
+//Trnasform hyperSF, Frame, Subframe format into subframe unit
+uint32_t convert_system_number_sf(uint32_t hyperSF, uint32_t frame, uint32_t subframe);
+/*input start position amd num_dlsf DL subframe, caculate the last subframe number*/
+uint32_t cal_num_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF, uint32_t frame, uint32_t subframe, uint32_t* hyperSF_result, uint32_t* frame_result, uint32_t* subframe_result, uint32_t num_dlsf_require);
+void init_dlsf_info(eNB_MAC_INST_NB_IoT *mac_inst, DLSF_INFO_t *DLSF_info);
+uint32_t generate_dlsch_header_NB_IoT(uint8_t *pdu, uint32_t num_sdu, logical_chan_id_t *logical_channel, uint32_t *sdu_length, uint8_t flag_drx, uint8_t flag_ta, uint32_t TBS);
+void maintain_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDCCH_info, sched_temp_DL_NB_IoT_t *NPDSCH_info);
+void init_tool_sib1(eNB_MAC_INST_NB_IoT *mac_inst);
+//int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
+/**DL test , delete**/
+available_resource_DL_t* new_dl_node(uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf);
+void initialize_dl_resource(available_resource_DL_t *DL_Resource_node, uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf);
+void insert_dl_resource(available_resource_DL_t *DL_Resource_node);
+void insert_schedule_result(schedule_result_t **list, int subframe, schedule_result_t *node);
+//interface with IF
+
+uint8_t *parse_ulsch_header_NB_IoT( uint8_t *mac_header, uint8_t *num_ce, uint8_t *num_sdu, uint8_t *rx_ces, uint8_t *rx_lcids, uint16_t *rx_lengths, uint16_t tb_length);
+
+void rx_sdu_NB_IoT(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t subframe, uint16_t rnti, uint8_t *sdu, uint16_t  length);
+
+int output_handler(eNB_MAC_INST_NB_IoT *mac_inst, module_id_t module_id, int CC_id, uint32_t hypersfn, uint32_t frame, uint32_t subframe, uint8_t MIB_flag, uint8_t SIB1_flag, uint32_t current_time);
+// main
+
+void mac_top_init_eNB_NB_IoT(void);
+
+uint32_t to_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_CarrierFreq, float m_dl);
+
+uint32_t from_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_earfcn, float m_dl);
+
+int32_t get_uldl_offset_NB_IoT(int eutra_band);
+#endif
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 05855a14bdece2129daa2db912394cb8a8e74c07..2de1b3fc743a4bd4ca41d9de64866fa0a8c79285 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -769,18 +769,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
 
 void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const  ctxt_pP) {
 
-  //unsigned char       *otg_pkt=NULL;
+
   module_id_t          dst_id; // dst for otg
-  //rb_id_t              rb_id;
-  //unsigned int         pkt_size=0;
   protocol_ctxt_t      ctxt;
   // we need to add conditions to avoid transmitting data when the UE is not RRC connected.
   if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic
-    //unsigned int ctime=0;
-    //ctime = ctxt_pP->frame * 100;
 
-    /*if  ((mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 0 ) > 2) &&
-    (mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 1 ) > 2)) { */
+
+
+
     PROTOCOL_CTXT_SET_BY_MODULE_ID(
       &ctxt,
       ctxt_pP->module_id,
@@ -792,36 +789,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const  ctxt_pP)
 
     for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) {
       ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id];
-/*
-      if (ctxt.rnti != NOT_A_RNTI) {
-        if (mac_eNB_get_rrc_status(ctxt.module_id, ctxt.rnti ) > 2 ) {
-        unsigned int temp = 0;
-          otg_pkt=packet_gen(
-                    ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id),
-                    UE_MODULE_ID_TO_INSTANCE(dst_id),
-                    0,
-                    ctime,
-                    &temp);
-        pkt_size = temp;
-
-        if (otg_pkt != NULL) {
-          rb_id = dst_id * maxDRB + DTCH;
-          pdcp_data_req(&ctxt,
-                        SRB_FLAG_NO,
-                        rb_id,
-                        RLC_MUI_UNDEFINED,
-                        RLC_SDU_CONFIRM_NO,
-                        pkt_size,
-                        otg_pkt,
-                        PDCP_TRANSMISSION_MODE_DATA);
-            LOG_I(OTG,
-                  "send packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n",
-                  ctxt_pP->module_id, rb_id, ctxt_pP->module_id, dst_id, pkt_size);
-            free(otg_pkt);
-          }
-        }
-      }
-*/
+
     }
   }
 }
diff --git a/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..479bd47d947d0c2fd79c96b84c72badf21557712
--- /dev/null
+++ b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h
@@ -0,0 +1,215 @@
+
+/*This is the interface module between PHY
+*Provided the FAPI style interface structures for P7.
+*Provide the semi-FAPI style interface for P5 (configuration)
+*
+*/
+
+#ifndef __IF_MODULE_NB_IoT__H__
+#define __IF_MODULE_NB_IoT__H__
+
+#include "nfapi_interface.h"
+//#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h"
+#include "PhysicalConfigDedicated-NB-r13.h"
+//#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
+#include "openair2/COMMON/platform_types.h"
+//#include "openair1/SCHED/IF_Module_L1_primitives_NB_IoT.h"
+
+//#define SCH_PAYLOAD_SIZE_MAX 4096
+#define BCCH_PAYLOAD_SIZE_MAX_NB_IoT 128
+
+
+
+// P5 FAPI-like configuration structures-------------------------------------------------------------------------------
+
+/*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS
+ * some of them may not needed because are used only at UE side
+ * some of them are not needed because not necessary at PHY level
+ * other have to be clarified since seems to be needed at PHY layer
+ * there is no UE_Config. request message carrying NB-IoT parameters???
+ *
+ * */
+typedef struct{
+	//nprach_config
+	uint16_t nprach_config_0_subcarrier_MSG3_range_start;
+	uint16_t nprach_config_1_subcarrier_MSG3_range_start;
+	uint16_t nprach_config_2_subcarrier_MSG3_range_start;
+	uint16_t nprach_config_0_max_num_preamble_attempt_CE;
+	uint16_t nprach_config_1_max_num_preamble_attempt_CE;
+	uint16_t nprach_config_2_max_num_preamble_attempt_CE;
+	uint16_t nprach_config_0_npdcch_num_repetitions_RA; //Rmax (see TS 36.213 ch 16.6) -->only this is managed at PHY layer
+	uint16_t nprach_config_1_npdcch_num_repetitions_RA;
+	uint16_t nprach_config_2_npdcch_num_repetitions_RA;
+	uint16_t nprach_config_0_npdcch_startSF_CSS_RA; //G (see TS 36.213 ch 16.6)
+	uint16_t nprach_config_1_npdcch_startSF_CSS_RA;
+	uint16_t nprach_config_2_npdcch_startSF_CSS_RA;
+	uint16_t nprach_config_0_npdcch_offset_RA; //Alfa_offset (see TS 36.213 ch 16.6)
+	uint16_t nprach_config_1_npdcch_offset_RA;
+	uint16_t nprach_config_2_npdcch_offset_RA;
+
+	//configured through the phy_config_dedicated
+	//Higher layer parameter for NPDCCH UE-spec search space
+	uint16_t npdcch_NumRepetitions;//Rmax (see TS 36.213 ch 16.6)  -->only this is managed at PHY layer
+	uint16_t npdcch_StartSF_USS; //G (see TS 36.213 ch 16.6)
+	uint16_t npdcch_Offset_USS; //Alfa_offset (see TS 36.213 ch 16.6)
+
+
+	ACK_NACK_NumRepetitions_NB_r13_t *ack_nack_numRepetitions_MSG4; //pointer to the first cell of a list of ack_nack_num_repetitions
+
+    //ulPowerControlCommon (UE side)
+    uint16_t p0_nominal_npusch;
+	uint16_t alpha;
+	uint16_t delta_preamle_MSG3;
+
+
+	/*Dedicated configuration -->not supported by FAPI (may not needed)
+	 * In OAI at least are needed when we manage the phy_procedures_eNB_TX in which we call the phy_config_dedicated_eNB_step2
+	 * that use the physicalConfigDedicated info previously stored in the PHY_VARS_eNB_NB_IoT structure through the phy_config_dedicated procedure
+	 */
+	//PhysicalConfigDedicated_NB_r13_t *phy_config_dedicated;
+
+
+
+
+}extra_phyConfig_t;
+
+typedef struct{
+
+	/*OAI config. parameters*/
+	module_id_t mod_id;
+	int CC_id;
+	uint16_t rnti;
+	int get_MIB; //should be different from 0 only when the mib!= null (NB_rrc_mac_config_req_eNB_IoT)
+	int get_COMMON;
+	int get_DEDICATED;
+
+	//ID of the Resource Block dedicated to NB-IoT
+	//For Nb-IoT only a restricted values of PRB indexes are allowed (see Rhode&Shwartz pag9)
+	//unsigned short NB_IoT_RB_ID; (should coincide with PRB index)
+
+
+
+
+	/*FAPI useful config. parameters used in the code
+	 *
+	 * -nfapi_uplink_reference_signal_config_t uplink_reference_signal_config
+	 * -nfapi_subframe_config_t subframe_config;
+	 * -nfapi_rf_config_t rf_config;
+	 * -nfapi_sch_config_t sch_config;
+	 * -nfapi_nb_iot_config_t config_NB_IoT;
+	 * -nfapi_l23_config_t l23_config;
+	 * -nfapi_config --> EARFCN (for the transport of the dl_CarrierFreq
+	 * */
+
+	//XXX where allocate memory??
+	nfapi_config_request_t* cfg;
+
+	/*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS (may non needed)*/
+	extra_phyConfig_t extra_phy_parms;
+
+}PHY_Config_NB_IoT_t;
+
+
+
+// uplink subframe P7---------------------------------------------------------------------------------
+
+
+/*UL_IND_t:
+* A structure handles all the uplink information.
+* Corresponding to the NRACH.indicaiton, UL_Config_indication, RX_ULSCH.indication, CRC.inidcation, NB_HARQ.indication in FAPI
+*/
+typedef struct{
+
+ 	/*Start at the common part*/
+
+ 	int test;
+
+ 	//Module ID
+ 	module_id_t module_id;
+ 	//CC ID
+ 	int CC_id;
+ 	//frame 
+ 	frame_t frame;
+ 	//subframe
+ 	sub_frame_t subframe;
+ 	//Hyper frame for NB-IoT implementation
+ 	uint32_t hypersfn;
+
+ 	/*preamble part*/
+
+ 	nfapi_nrach_indication_body_t NRACH;
+
+ 	/*Uplink data part*/
+
+ 	/*indication of the harq feedback*/
+ 	nfapi_nb_harq_indication_t nb_harq_ind;
+ 	/*indication of the uplink data PDU*/
+  	nfapi_rx_indication_body_t RX_NPUSCH;
+ 	/*crc_indication*/
+ 	nfapi_crc_indication_body_t crc_ind;
+
+ }UL_IND_NB_IoT_t;
+
+ // Downlink subframe P7
+
+
+typedef struct{
+
+ 	/*Start at the common part*/
+
+ 	//Module ID
+	module_id_t module_id; 
+ 	//CC ID
+ 	int CC_id;
+ 	// hyper subframe
+ 	uint32_t hypersfn;
+ 	//frame
+ 	frame_t frame;
+ 	//subframe
+ 	sub_frame_t subframe;
+
+  	/// nFAPI DL Config Request
+  	nfapi_dl_config_request_t *DL_req;
+  	/// nFAPI UL Config Request
+  	nfapi_ul_config_request_t *UL_req;
+  	/// nFAPI HI_DCI Request
+  	nfapi_hi_dci0_request_t *HI_DCI0_req;
+  	/// nFAPI TX Request
+  	nfapi_tx_request_t        *TX_req; 
+  	/// Pointers to DL SDUs
+  	//uint8_t **sdu;
+
+}Sched_Rsp_NB_IoT_t;
+
+
+/*IF_Module_t a group for gathering the Interface
+It should be allocated at the main () in lte-softmodem.c*/
+typedef struct IF_Module_NB_IoT_s{
+	//define the function pointer
+	void (*UL_indication)(UL_IND_NB_IoT_t *UL_INFO);
+	void (*schedule_response)(Sched_Rsp_NB_IoT_t *Sched_INFO);
+	void (*PHY_config_req)(PHY_Config_NB_IoT_t* config_INFO);
+}IF_Module_NB_IoT_t;
+
+/*Initial */
+
+/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
+void schedule_response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO);
+
+/*Interface for PHY Configuration
+ * Trigger the phy_config_xxx functions using parameters from the shared PHY_Config structure
+ * */
+void PHY_config_req_NB_IoT(PHY_Config_NB_IoT_t* config_INFO);
+
+//int IF_Module_init(IF_Module_t *if_inst);
+
+/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
+//void Schedule_Response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO);
+
+/*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler)
+*/
+void UL_indication_NB_IoT(UL_IND_NB_IoT_t *UL_INFO);
+
+IF_Module_NB_IoT_t *IF_Module_init_NB_IoT(int Mod_id);
+
+#endif
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c
new file mode 100644
index 0000000000000000000000000000000000000000..866b2c1e911dc9f5b81a6cc342200a0d90f1e381
--- /dev/null
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c
@@ -0,0 +1,1417 @@
+/* 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
+*/
+
+#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 */
+#include "UTIL/LOG/log.h"
+#include <asn_application.h>
+#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */
+#include <per_encoder.h>
+#include "asn1_msg.h"
+
+
+
+//#include for NB-IoT-------------------
+#include "RRCConnectionRequest-NB.h"
+#include "BCCH-DL-SCH-Message-NB.h"
+#include "UL-CCCH-Message-NB.h"
+#include "UL-DCCH-Message-NB.h"
+#include "DL-CCCH-Message-NB.h"
+#include "DL-DCCH-Message-NB.h"
+#include "EstablishmentCause-NB-r13.h"
+#include "RRCConnectionSetup-NB.h"
+#include "SRB-ToAddModList-NB-r13.h"
+#include "DRB-ToAddModList-NB-r13.h"
+#include "RRC/LITE/defs_NB_IoT.h"
+#include "RRCConnectionSetupComplete-NB.h"
+#include "RRCConnectionReconfigurationComplete-NB.h"
+#include "RRCConnectionReconfiguration-NB.h"
+#include "MasterInformationBlock-NB.h"
+#include "SystemInformation-NB.h"
+#include "SystemInformationBlockType1.h"
+#include "SIB-Type-NB-r13.h"
+#include "RRCConnectionResume-NB.h"
+#include "RRCConnectionReestablishment-NB.h"
+#include "../defs_NB_IoT.h"
+//----------------------------------------
+
+//#include "PHY/defs.h"
+#include "enb_config.h"
+
+#if defined(ENABLE_ITTI)
+# include "intertask_interface.h"
+#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;
+  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 radio 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!!??
+   */
+
+  //XXX check if correct the bit assignment
+  uint8_t sfn_MSB = (uint8_t)((frame>>6) & 0x0f); // all the 4 bits are set to 1
+  uint8_t hsfn_LSB = (uint8_t)(hyper_frame & 0x03); //2 bits set to 1 (0x3 = 0011)
+  uint16_t spare=0; //11 bits --> use uint16
+
+  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 =11; //see TS 36.213-->tables 16.4.1.3-3 ecc...
+  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 = MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13;
+  mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 0;
+
+  printf("[MIB] Initialization 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_BCCH_BCH_Message_NB,
+                                   (void*)mib_NB_IoT,
+                                   carrier->MIB_NB_IoT,
+                                   100);
+  if(enc_rval.encoded <= 0) {
+      LOG_F(RRC, "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
+               )
+{
+  BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT);
+  SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT);
+  
+
+  asn_enc_rval_t enc_rval;
+
+  PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT;
+  MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3];
+  SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT;
+  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;
+
+  memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t));
+  bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1;
+  bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13;
+
+  //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(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=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=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred;
+
+  //Still Set to "notAllowed" like in the previous case
+  (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=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 = 0; //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(P_Max_t));
+  *((*sib1_NB_IoT)->p_Max_r13) = 23;
+
+  //FIXME
+  (*sib1_NB_IoT)->freqBandIndicator_r13 =
+#if defined(ENABLE_ITTI)
+    configuration->eutra_band;
+#else
+    5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz  FDD mode)
+#endif
+
+    //OPTIONAL new parameters, to be used?
+      /*
+       * freqBandInfo_r13
+       * multiBandInfoList_r13
+       * nrs_CRS_PowerOffset_r13
+       * sib1_NB_IoT->downlinkBitmap_r13.choice.subframePattern10_r13 =(is a BIT_STRING)
+       */
+
+
+   (*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;
+
+   *eutraControlRegionSize = 1;
+   (*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize;
+
+
+   *nrs_CRS_PowerOffset= 0;
+   (*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset;
+
+   schedulingInfo_NB_IoT = (SchedulingInfo_NB_r13_t*) malloc (3*sizeof(SchedulingInfo_NB_r13_t));
+   sib_type_NB_IoT = (SIB_Type_NB_r13_t *) malloc (3*sizeof(SIB_Type_NB_r13_t));
+
+  memset(&schedulingInfo_NB_IoT[0],0,sizeof(SchedulingInfo_NB_r13_t));
+  memset(&schedulingInfo_NB_IoT[1],0,sizeof(SchedulingInfo_NB_r13_t));
+  memset(&schedulingInfo_NB_IoT[2],0,sizeof(SchedulingInfo_NB_r13_t));    
+  memset(&sib_type_NB_IoT[0],0,sizeof(SIB_Type_NB_r13_t));
+  memset(&sib_type_NB_IoT[1],0,sizeof(SIB_Type_NB_r13_t));
+  memset(&sib_type_NB_IoT[2],0,sizeof(SIB_Type_NB_r13_t));
+
+
+  // Now, follow the scheduler SIB configuration
+  // There is only one sib2+sib3 common setting
+  schedulingInfo_NB_IoT[0].si_Periodicity_r13=SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096;
+  schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission.
+  schedulingInfo_NB_IoT[0].si_TB_r13= 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[0]=SIB_Type_NB_r13_sibType3_NB_r13;
+
+  ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]);
+  ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]);
+
+  //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 == 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
+  (*sib1_NB_IoT)->si_WindowLength_r13=SystemInformationBlockType1_NB__si_WindowLength_r13_ms160;
+  (*sib1_NB_IoT)->si_RadioFrameOffset_r13= 0;
+
+  /*In Nb-IoT change/update of specific SI message can additionally be indicated by a SI message specific value tag
+   * systemInfoValueTagSI (there is no SystemInfoValueTag in SIB1-NB but only in MIB-NB)
+   *contained in systemInfoValueTagList_r13
+   **/
+  //FIXME correct?
+  (*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);
+
+
+#ifdef XER_PRINT //generate xml files
+  xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message);
+#endif
+
+
+  enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB,
+                                   (void*)bcch_message,
+                                   carrier->SIB1_NB_IoT,
+                                   100);
+
+  if (enc_rval.encoded > 0){ 
+       LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n",
+               enc_rval.failed_type->name, enc_rval.encoded);
+  }
+
+
+#ifdef USER_MODE
+  LOG_D(RRC,"[NB-IoT] SystemInformationBlockType1-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
+#endif
+
+  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 SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part;
+  struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part;
+
+  BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB
+  SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT;
+  SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT;
+
+  asn_enc_rval_t enc_rval;
+  RACH_Info_NB_r13_t rach_Info_NB_IoT;
+  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;
+
+  ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition;
+  struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config;
+  struct DL_GapConfig_NB_r13	*dl_Gap;
+
+  long *srs_SubframeConfig;
+  srs_SubframeConfig= CALLOC(1, sizeof(long));
+
+
+  if (bcch_message) {
+    memset(bcch_message,0,sizeof(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 SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
+  sib3_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
+  memset(sib2_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
+  memset(sib3_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member));
+
+  sib2_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13;
+  sib3_NB_part->present = 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 = (NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(NPRACH_Parameters_NB_r13_t));
+
+  memset(&nprach_parameters[0],0,sizeof(NPRACH_Parameters_NB_r13_t));
+  memset(&nprach_parameters[1],0,sizeof(NPRACH_Parameters_NB_r13_t));
+  memset(&nprach_parameters[2],0,sizeof(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;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.powerRampingStep =
+	configuration->rach_powerRampingStep_NB;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.preambleInitialReceivedTargetPower =
+    configuration->rach_preambleInitialReceivedTargetPower_NB;
+
+  rach_Info_NB_IoT.ra_ResponseWindowSize_r13 = configuration->rach_raResponseWindowSize_NB;
+  rach_Info_NB_IoT.mac_ContentionResolutionTimer_r13 = configuration-> rach_macContentionResolutionTimer_NB;
+  //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;
+
+  // PCCH-Config-NB-IoT-----------------------------------------------------------------
+  sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.defaultPagingCycle_r13
+    = configuration->pcch_defaultPagingCycle_NB;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.nB_r13 = configuration->pcch_nB_NB;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.npdcch_NumRepetitionPaging_r13 = configuration-> pcch_npdcch_NumRepetitionPaging_NB;
+
+  //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;
+  /*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
+
+  nprach_parameters[0].nprach_Periodicity_r13               = configuration->nprach_Periodicity[0];
+  nprach_parameters[0].nprach_StartTime_r13                 = configuration->nprach_StartTime[0];
+  nprach_parameters[0].nprach_SubcarrierOffset_r13          = configuration->nprach_SubcarrierOffset[0];
+  nprach_parameters[0].nprach_NumSubcarriers_r13            = configuration->nprach_NumSubcarriers[0];
+  nprach_parameters[0].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[0];
+  nprach_parameters[0].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart;
+  nprach_parameters[0].maxNumPreambleAttemptCE_r13          = configuration->maxNumPreambleAttemptCE_NB;
+  nprach_parameters[0].npdcch_NumRepetitions_RA_r13         = configuration->npdcch_NumRepetitions_RA[0];
+  nprach_parameters[0].npdcch_StartSF_CSS_RA_r13            = configuration->npdcch_StartSF_CSS_RA[0];
+  nprach_parameters[0].npdcch_Offset_RA_r13                 = configuration->npdcch_Offset_RA[0];
+
+  nprach_parameters[1].nprach_Periodicity_r13               = configuration->nprach_Periodicity[1];
+  nprach_parameters[1].nprach_StartTime_r13                 = configuration->nprach_StartTime[1];
+  nprach_parameters[1].nprach_SubcarrierOffset_r13          = configuration->nprach_SubcarrierOffset[1];
+  nprach_parameters[1].nprach_NumSubcarriers_r13            = configuration->nprach_NumSubcarriers[1];
+  nprach_parameters[1].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[1];
+  nprach_parameters[1].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart;
+  nprach_parameters[1].maxNumPreambleAttemptCE_r13          = configuration->maxNumPreambleAttemptCE_NB;
+  nprach_parameters[1].npdcch_NumRepetitions_RA_r13         = configuration->npdcch_NumRepetitions_RA[1];
+  nprach_parameters[1].npdcch_StartSF_CSS_RA_r13            = configuration->npdcch_StartSF_CSS_RA[1];
+  nprach_parameters[1].npdcch_Offset_RA_r13                 = configuration->npdcch_Offset_RA[1];
+
+  nprach_parameters[2].nprach_Periodicity_r13               = configuration->nprach_Periodicity[2];
+  nprach_parameters[2].nprach_StartTime_r13                 = configuration->nprach_StartTime[2];
+  nprach_parameters[2].nprach_SubcarrierOffset_r13          = configuration->nprach_SubcarrierOffset[2];
+  nprach_parameters[2].nprach_NumSubcarriers_r13            = configuration->nprach_NumSubcarriers[2];
+  nprach_parameters[2].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[2];
+  nprach_parameters[2].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart;
+  nprach_parameters[2].maxNumPreambleAttemptCE_r13          = configuration->maxNumPreambleAttemptCE_NB;
+  nprach_parameters[2].npdcch_NumRepetitions_RA_r13         = configuration->npdcch_NumRepetitions_RA[2];
+  nprach_parameters[2].npdcch_StartSF_CSS_RA_r13            = configuration->npdcch_StartSF_CSS_RA[2];
+  nprach_parameters[2].npdcch_Offset_RA_r13                 = configuration->npdcch_Offset_RA[2];
+
+
+  //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;
+
+
+  //NPUSCH-Config NB-IoT----------------------------------------------------------------
+  //list of size 3 (see maxNPRACH_Resources_NB_r13)
+  ack_nack_repetition = configuration-> npusch_ack_nack_numRepetitions_NB; //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;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.srs_SubframeConfig_r13= srs_SubframeConfig; /*OPTIONAL*/
+
+
+  /*OPTIONAL*/
+  dmrs_config = CALLOC(1,sizeof(struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13));
+  dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13;
+  dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13;
+
+  /*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;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13 =configuration->npusch_groupAssignmentNPUSCH_r13;
+
+
+  //dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/
+  dl_Gap = CALLOC(1,sizeof(struct DL_GapConfig_NB_r13));
+  dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB;
+  dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB;
+  dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB;
+  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;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.deltaPreambleMsg3_r13 = configuration->deltaPreambleMsg3;
+  sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.alpha_r13 = configuration->npusch_alpha;
+  //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=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120;
+
+  /*OPTIONAL*/
+  sib2_NB_IoT->multiBandInfoList_r13 = NULL;
+
+/// SIB3-NB-------------------------------------------------------
+
+  sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=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)= 10; //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 = BCCH_DL_SCH_MessageType_NB_PR_c1;
+  bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13;
+
+  bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = 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_BCCH_DL_SCH_Message_NB,
+                                   (void*)bcch_message,
+                                   carrier->SIB23_NB_IoT,
+                                   900);
+//  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)*/
+uint8_t do_RRCConnectionSetup_NB_IoT(
+  const protocol_ctxt_t*     const ctxt_pP,
+  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,
+  const NB_IoT_DL_FRAME_PARMS* const frame_parms, // maybe not used
+  SRB_ToAddModList_NB_r13_t**             SRB_configList_NB_IoT, //for both SRB1bis and SRB1
+  struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT
+)
+
+{
+
+ asn_enc_rval_t enc_rval;
+
+
+ //MP:logical channel group not defined for Nb-IoT
+
+ //MP: logical channel priority pag 605 (is 1 for SRB1 and for SRB1bis should be the same)
+ //long* prioritySRB1 = NULL;
+ long* prioritySRB1bis = NULL;
+ BOOLEAN_t* logicalChannelSR_Prohibit =NULL; //pag 605
+ BOOLEAN_t* npusch_AllSymbols= NULL;
+
+// struct SRB_ToAddMod_NB_r13* SRB1_config_NB = NULL;
+// struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB = NULL;
+// struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB = NULL;
+
+ struct SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL;
+ struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL;
+ struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL;
+
+ //No UL_specific parameters for NB-IoT in LogicalChanelConfig-NB
+
+ PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL;
+ DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT;
+ RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL;
+
+ memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t));
+ dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1;
+ dl_ccch_msg_NB_IoT.message.choice.c1.present = 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(SRB_ToAddModList_NB_r13_t));
+
+/// SRB1--------------------
+ {
+// SRB1_config_NB = CALLOC(1,sizeof(*SRB1_config_NB));
+//
+// //no srb_Identity in SRB_ToAddMod_NB
+//
+// SRB1_rlc_config_NB = CALLOC(1,sizeof(*SRB1_rlc_config_NB));
+// SRB1_config_NB->rlc_Config_r13   = SRB1_rlc_config_NB;
+//
+// SRB1_rlc_config_NB->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue;
+// SRB1_rlc_config_NB->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//the only possible in NB_IoT
+//
+//// SRB1_rlc_config_NB->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->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->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL;
+//
+//
+// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000;
+// SRB1_rlc_config_NB->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->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 = NULL;
+//
+// SRB1_lchan_config_NB = CALLOC(1,sizeof(*SRB1_lchan_config_NB));
+// SRB1_config_NB->logicalChannelConfig_r13  = SRB1_lchan_config_NB;
+//
+// SRB1_lchan_config_NB->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue;
+//
+//
+// prioritySRB1 = CALLOC(1, sizeof(long));
+// *prioritySRB1 = 1;
+// SRB1_lchan_config_NB->choice.explicitValue.priority_r13 = prioritySRB1;
+//
+// logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t));
+// *logicalChannelSR_Prohibit = 1;
+// //schould be set to TRUE (specs pag 641)
+// SRB1_lchan_config_NB->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit;
+//
+// //ADD SRB1
+// ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1_config_NB);
+ }
+
+///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));
+
+		 //no srb_Identity in SRB_ToAddMod_NB
+		 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 = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue;
+		 SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT
+
+		 SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000;
+		 SRB1bis_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 )
+		 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 = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue;
+
+		 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; //schould be set to TRUE (specs pag 641)
+		 SRB1bis_lchan_config_NB_IoT->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit;
+
+		 //ADD SRB1bis
+		 //MP: Actually there is no way to distinguish SRB1 and SRB1bis once put in the list
+		 //MP: SRB_ToAddModList_NB_r13_t size = 1
+		 ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1bis_config_NB_IoT);
+
+
+ // PhysicalConfigDedicated (NPDCCH, NPUSCH, CarrierConfig, UplinkPowerControl)
+
+ physicalConfigDedicated2_NB_IoT = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT));
+ *physicalConfigDedicated_NB_IoT = physicalConfigDedicated2_NB_IoT;
+
+ 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 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13));
+
+ //no tpc, no cqi and no pucch, no pdsch, no soundingRS, no AntennaInfo, no scheduling request config
+
+ /*
+  * NB-IoT supports the operation with either one or two antenna ports, AP0 and AP1.
+  * For the latter case, Space Frequency Block Coding (SFBC) is applied.
+  * Once selected, the same transmission scheme applies to NPBCH, NPDCCH, and NPDSCH.
+  * */
+
+ //FIXME: MP: CarrierConfigDedicated check the set values ----------------------------------------------
+
+  //DL
+
+ 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;
+
+  //UL
+ physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->ul_CarrierConfig_r13.ul_CarrierFreq_r13= NULL;
+
+ // NPDCCH
+ physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_NumRepetitions_r13 =0;
+ physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_Offset_USS_r13 =0;
+ physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_StartSF_USS_r13=0;
+
+ // NPUSCH //(specs TS 36.331 v14.2.1 pag 643) /* OPTIONAL */
+ physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->ack_NACK_NumRepetitions_r13= NULL;
+ npusch_AllSymbols= CALLOC(1, sizeof(BOOLEAN_t));
+ *npusch_AllSymbols= 1; //TRUE
+ physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->npusch_AllSymbols_r13= npusch_AllSymbols; /* OPTIONAL */
+ physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->groupHoppingDisabled_r13=NULL; /* OPTIONAL */
+
+ // UplinkPowerControlDedicated
+ physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13->p0_UE_NPUSCH_r13 = 0; // 0 dB (specs TS36.331 v14.2.1 pag 643)
+
+
+ //Fill the rrcConnectionSetup-NB message
+ rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value
+ rrcConnectionSetup_NB_IoT->criticalExtensions.present = RRCConnectionSetup_NB__criticalExtensions_PR_c1;
+ rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ;
+ //MP: carry only SRB1bis at the moment and phyConfigDedicated
+ 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_DL_CCCH_Message_NB,
+                                  (void*)&dl_ccch_msg_NB_IoT,
+                                  buffer,
+                                  100);
+
+ if (enc_rval.encoded <= 0) {
+     LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n",
+              enc_rval.failed_type->name, enc_rval.encoded);
+ }
+
+#ifdef USER_MODE
+ LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes), ecause %d\n",
+       enc_rval.encoded,(enc_rval.encoded+7)/8,ecause);
+#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)
+{
+  DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
+  asn_enc_rval_t enc_rval;
+
+  memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t));
+
+  dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1;
+  dl_dcch_msg_NB_IoT.message.choice.c1.present = 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 = SecurityModeCommand__criticalExtensions_PR_c1;
+
+  dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present =
+		  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
+    = (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_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_DL_DCCH_Message_NB,
+                                   (void*)&dl_dcch_msg_NB_IoT,
+                                   buffer,
+                                   100);
+  if (enc_rval.encoded <= 0) {
+      LOG_F(RRC, "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,"[NB-IoT %d] securityModeCommand-NB for UE %x Encoded %zd bits (%zd 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,"[NB-IoT %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
+)
+
+{
+
+  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(DL_DCCH_Message_NB_t));
+
+  dl_dcch_msg_NB_IoT.message.present           = DL_DCCH_MessageType_NB_PR_c1;
+  dl_dcch_msg_NB_IoT.message.choice.c1.present = 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 = UECapabilityEnquiry_NB__criticalExtensions_PR_c1;
+  dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present =
+		  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_DL_DCCH_Message_NB,
+                                   (void*)&dl_dcch_msg_NB_IoT,
+                                   buffer,
+                                   100);
+  if (enc_rval.encoded <= 0) {
+     LOG_F(RRC, "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,"[NB-IoT %d] UECapabilityEnquiry-NB for UE %x Encoded %zd bits (%zd 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,"[NB-IoT %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,
+    SRB_ToAddModList_NB_r13_t          *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1
+    DRB_ToAddModList_NB_r13_t          *DRB_list_NB_IoT, //DRB_ConfigList (default)
+    DRB_ToReleaseList_NB_r13_t         *DRB_list2_NB_IoT, //is NULL when passed
+    struct PhysicalConfigDedicated_NB_r13     *physicalConfigDedicated_NB_IoT,
+	MAC_MainConfig_NB_r13_t                   *mac_MainConfig_NB_IoT,
+  struct 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;
+  DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
+  RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB;
+
+
+  memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t));
+
+  dl_dcch_msg_NB_IoT.message.present           = DL_DCCH_MessageType_NB_PR_c1;
+  dl_dcch_msg_NB_IoT.message.choice.c1.present = 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 = RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1;
+  rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =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
+      =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_DL_DCCH_Message_NB,
+                                   (void*)&dl_dcch_msg_NB_IoT,
+                                   buffer,
+                                   RRC_BUF_SIZE);
+  if (enc_rval.encoded <= 0) {
+     LOG_F(RRC, "ASN1 message encoding failed %s, %li\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 %zd bits (%zd 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;
+
+  DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT;
+  RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject;
+
+  memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t));
+  dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1;
+  dl_ccch_msg_NB_IoT.message.choice.c1.present = 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 = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8;
+
+  //Only change in "asn_DEF_DL_CCCH_Message_NB"
+#ifdef XER_PRINT
+  xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT);
+#endif
+  enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB,
+                                   (void*)&dl_ccch_msg_NB_IoT,
+                                   buffer,
+                                   100);
+  if (enc_rval.encoded <= 0) {
+     LOG_F(RRC,"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_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) {
+      MessageDef *msg_p;
+
+      msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, 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 %zd bits (%zd 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;
+
+  DL_CCCH_Message_NB_t          dl_ccch_msg_NB_IoT;
+  RRCConnectionReject_NB_t      *rrcConnectionReject_NB_IoT;
+
+  memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t));
+  dl_ccch_msg_NB_IoT.message.present           = DL_CCCH_MessageType_NB_PR_c1;
+  dl_ccch_msg_NB_IoT.message.choice.c1.present = 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 = RRCConnectionReject_NB__criticalExtensions_PR_c1;
+  rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = 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)=
+		  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_DL_CCCH_Message_NB,
+                                   (void*)&dl_ccch_msg_NB_IoT,
+                                   buffer,
+                                   100);
+  if (enc_rval.encoded <= 0) {
+     LOG_F(RRC, "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_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) {
+      MessageDef *msg_p;
+
+      msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, 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 %zd bits (%zd 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;
+
+  DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
+
+  memset(&dl_dcch_msg_NB_IoT, 0, sizeof(DL_DCCH_Message_NB_t));
+
+  dl_dcch_msg_NB_IoT.message.present           = DL_DCCH_MessageType_NB_PR_c1;
+  dl_dcch_msg_NB_IoT.message.choice.c1.present = 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 = DLInformationTransfer_NB__criticalExtensions_PR_c1;
+  dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = 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_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_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) {
+      MessageDef *msg_p;
+
+      msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, 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
+		SRB_ToAddModList_NB_r13_t*      SRB_list_NB_IoT) //should contain SRB1 already configured?
+{
+
+	asn_enc_rval_t enc_rval;
+	DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT;
+	RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT;
+
+	memset(&dl_ccch_msg_NB_IoT, 0, sizeof(DL_CCCH_Message_NB_t));
+
+	dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1;
+	dl_ccch_msg_NB_IoT.message.choice.c1.present = 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 = RRCConnectionReestablishment_NB__criticalExtensions_PR_c1;
+	rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = 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_DL_CCCH_Message_NB,
+	                                   (void*)&dl_ccch_msg_NB_IoT,
+	                                   buffer,
+	                                   RRC_BUF_SIZE);
+
+	if (enc_rval.encoded <= 0) {
+           LOG_F(RRC, "ASN1 message encoding failed (%s, %li)!\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_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) {
+      MessageDef *msg_p;
+
+      msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, 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 %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
+  return 0;
+}
+
+/*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;
+
+  DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT;
+  RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT;
+
+
+  memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t));
+
+  dl_dcch_msg_NB_IoT.message.present           = DL_DCCH_MessageType_NB_PR_c1;
+  dl_dcch_msg_NB_IoT.message.choice.c1.present = 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 = RRCConnectionRelease_NB__criticalExtensions_PR_c1;
+  rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ;
+
+  rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = 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_DL_DCCH_Message_NB,
+                                   (void*)&dl_dcch_msg_NB_IoT,
+                                   buffer,
+                                   RRC_BUF_SIZE);//check
+
+  return((enc_rval.encoded+7)/8);
+}
+
+
+
+
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..67e0919307dc474c7ecf61de09140f7436100101
--- /dev/null
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h
@@ -0,0 +1,293 @@
+/*
+ * 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.h
+* \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
+
+#include <asn_application.h>
+#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */
+
+
+#include "RRC/LITE/defs_NB_IoT.h"
+
+/*
+ * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC)
+ * output into the chosen string buffer.
+ * RETURN VALUES:
+ *       0: The structure is printed.
+ *      -1: Problem printing the structure.
+ * WARNING: No sensible error value is returned.
+ */
+
+
+/**
+\brief Generate configuration for SIB1 (eNB).
+@param carrier pointer to Carrier information
+@param N_RB_DL Number of downlink PRBs
+@param frame radio frame number
+@return size of encoded bit stream in bytes*/
+uint8_t do_MIB_NB_IoT(
+		rrc_eNB_carrier_data_NB_IoT_t *carrier,
+		uint32_t N_RB_DL,
+		uint32_t frame,
+    uint32_t hyper_frame);
+
+
+/**
+\brief Generate a default configuration for SIB1-NB (eNB).
+@param Mod_id Instance of eNB
+@param CC_id Component carrier to configure
+@param carrier pointer to Carrier information
+@param configuration Pointer Configuration Request structure
+@return size of encoded bit stream in bytes*/
+
+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
+                      );
+
+/**
+\brief Generate a default configuration for SIB2/SIB3-NB in one System Information PDU (eNB).
+@param Mod_id Index of eNB (used to derive some parameters)
+@param buffer Pointer to PER-encoded ASN.1 description of SI-NB PDU
+@param systemInformation_NB_IoT Pointer to asn1c C representation of SI-NB PDU
+@param sib2_NB Pointer (returned) to sib2_NB component withing SI-NB PDU
+@param sib3_NB Pointer (returned) to sib3_NB component withing SI-NB PDU
+@return size of encoded bit stream in bytes*/
+
+uint8_t do_SIB23_NB_IoT(uint8_t Mod_id,
+                        int CC_id,
+                        rrc_eNB_carrier_data_NB_IoT_t *carrier,
+                        NbIoTRrcConfigurationReq *configuration
+                        );
+
+/**(UE-SIDE)
+\brief Generate an RRCConnectionRequest-NB UL-CCCH-Message (UE) based on random string or S-TMSI.  This
+routine only generates an mo-data establishment cause.
+@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU
+@param rv 5 byte random string or S-TMSI
+@param Mod_id
+@returns Size of encoded bit stream in bytes*/
+
+uint8_t do_RRCConnectionRequest_NB_IoT(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv);
+
+
+/**(UE -SIDE)
+\brief Generate an RRCConnectionSetupComplete-NB UL-DCCH-Message (UE)
+@param Mod_id
+@param Transaction_id
+@param dedicatedInfoNASLength
+@param dedicatedInfoNAS
+@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU
+@returns Size of encoded bit stream in bytes*/
+
+uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength,
+                                             const char* dedicatedInfoNAS);
+
+/** (UE-SIDE)
+\brief Generate an RRCConnectionReconfigurationComplete-NB UL-DCCH-Message (UE)
+@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU
+@param ctxt_pP
+@param Transaction_id
+@returns Size of encoded bit stream in bytes*/
+
+uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  uint8_t* buffer,
+  const uint8_t Transaction_id
+);
+
+/**
+\brief Generate an RRCConnectionSetup-NB DL-CCCH-Message (eNB).  This routine configures SRB_ToAddMod (SRB1/SRB1bis-NB) and
+PhysicalConfigDedicated-NB IEs.
+@param ctxt_pP Running context
+@param ue_context_pP UE context
+@param CC_id         Component Carrier ID
+@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU
+@param transmission_mode Transmission mode for UE (1-9)
+@param UE_id UE index for this message
+@param Transaction_id Transaction_ID for this message
+@param SRB_configList Pointer (returned) to SRB1_config/SRB1bis_config(later) IEs for this UE
+@param physicalConfigDedicated_NB Pointer (returned) to PhysicalConfigDedicated-NB IE for this UE
+@returns Size of encoded bit stream in bytes*/
+
+uint8_t do_RRCConnectionSetup_NB_IoT(
+  const protocol_ctxt_t*     const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*      const ue_context_pP,
+  int                              CC_id,
+  uint8_t*                   const buffer, //carrier[CC_id].Srb0.Tx_buffer.Payload
+  const uint8_t                    Transaction_id,
+  const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed but not deleted
+  SRB_ToAddModList_NB_r13_t**             SRB_configList_NB_IoT, //in order to be configured--> stanno puntando alla SRB_configlist dell ue_context
+  struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT //in order to be configured--> stanno puntando alla physicalConfigDedicated dell ue_context
+);
+
+
+/**
+ * For which SRB is used in NB-IoT??
+\brief Generate an RRCConnectionReconfiguration-NB DL-DCCH-Message (eNB).  This routine configures SRBToAddMod-NB (SRB1) and one DRBToAddMod-NB
+(DRB3).  PhysicalConfigDedicated-NB is not updated.
+@param ctxt_pP Running context
+@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU
+@param Transaction_id Transaction_ID for this message
+@param SRB_list_NB Pointer to SRB List to be added/modified (NULL if no additions/modifications)
+@param DRB_list_NB Pointer to DRB List to be added/modified (NULL if no additions/modifications)
+@param DRB_list2_NB Pointer to DRB List to be released      (NULL if none to be released)
+//sps not supported by NB-IoT
+@param physicalConfigDedicated_NB Pointer to PhysicalConfigDedicated-NB to be modified (NULL if no modifications)
+//measurement not supported by NB-IoT
+@param mac_MainConfig Pointer to Mac_MainConfig(NULL if no modifications)
+//no CBA functionalities
+@returns Size of encoded bit stream in bytes*/
+
+uint16_t
+do_RRCConnectionReconfiguration_NB_IoT(
+  const protocol_ctxt_t*        const ctxt_pP,
+    uint8_t                            *buffer,
+    uint8_t                             Transaction_id,
+    SRB_ToAddModList_NB_r13_t          *SRB_list_NB_IoT,
+    DRB_ToAddModList_NB_r13_t          *DRB_list_NB_IoT,
+    DRB_ToReleaseList_NB_r13_t         *DRB_list2_NB_IoT,
+    struct PhysicalConfigDedicated_NB_r13     *physicalConfigDedicated,
+    MAC_MainConfig_t                   *mac_MainConfig,
+  struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT);
+
+/**
+ * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established
+ \brief Generate a SecurityModeCommand
+ @param ctxt_pP Running context
+ @param buffer Pointer to PER-encoded ASN.1 description
+ @param Transaction_id Transaction_ID for this message
+ @param cipheringAlgorithm
+ @param integrityProtAlgorithm
+ */
+
+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);
+
+/**
+ * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established
+ \brief Generate a SecurityModeCommand
+ @param ctxt_pP Running context
+ @param buffer Pointer to PER-encoded ASN.1 description
+ @param Transaction_id Transaction_ID for this message
+ */
+
+uint8_t do_UECapabilityEnquiry_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  uint8_t*               const buffer,
+  const uint8_t                Transaction_id
+);
+
+
+/**
+ * There is nothing new in this type of message for NB-IoT (only change in some nomenclature)
+\brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB).
+@param Mod_id Module ID of eNB
+@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU
+@returns Size of encoded bit stream in bytes*/
+
+uint8_t
+do_RRCConnectionReestablishmentReject_NB_IoT(
+    uint8_t                    Mod_id,
+    uint8_t*                   const buffer);
+
+
+/**
+\brief Generate an RRCConnectionReject-NB DL-CCCH-Message (eNB).
+@param Mod_id Module ID of eNB
+@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU
+@returns Size of encoded bit stream in bytes*/
+uint8_t
+do_RRCConnectionReject_NB_IoT(
+    uint8_t                    Mod_id,
+    uint8_t*                   const buffer);
+
+
+/**
+\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message
+@param Mod_id Module ID of eNB
+@param buffer Pointer to PER-encoded ASN.1 description
+@param transaction_id Transaction index
+@returns Size of encoded bit stream in bytes*/
+
+uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id);
+
+
+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);
+
+//for now not implemented since UE side
+//uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer);
+
+//for now not implemented since UE side???
+//OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname)
+
+/**
+\brief Generate an RRCConnectionReestablishment-NB DL-CCCH Message
+ *@param
+ *
+ */
+
+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
+		SRB_ToAddModList_NB_r13_t**             SRB_configList_NB_IoT
+		 );
+
+/**
+\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message (eNB)
+@param Mod_id Module ID of eNB
+@param buffer Pointer to PER-encoded ASN.1 description of DL-DCCH-Message PDU
+@param transaction_id Transaction index
+@returns Size of encoded bit stream in bytes*/
+
+//uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id);
diff --git a/openair2/RRC/LITE/defs_NB_IoT.h b/openair2/RRC/LITE/defs_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..98b9148cd2c8dee3d1edf1633ecab6e90e794a01
--- /dev/null
+++ b/openair2/RRC/LITE/defs_NB_IoT.h
@@ -0,0 +1,570 @@
+/* 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 RRC/LITE/defs_NB_IoT.h
+* \brief NB-IoT RRC struct definitions and function prototypes
+* \author Navid Nikaein, Raymond Knopp and Michele Paffetti
+* \date 2010 - 2014, 2017
+* \version 1.0
+* \company Eurecom
+* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it
+*/
+
+#ifndef __OPENAIR_RRC_DEFS_NB_IOT_H__
+#define __OPENAIR_RRC_DEFS_NB_IOT_H__
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "collection/tree.h"
+#include "rrc_types_NB_IoT.h"
+#include "COMMON/platform_constants.h"
+#include "COMMON/platform_types.h"
+#include "targets/COMMON/openairinterface5g_limits.h"
+
+#include "COMMON/mac_rrc_primitives.h"
+
+//-----NB-IoT #include files-------
+
+//#include "SystemInformationBlockType1-NB.h"
+//#include "SystemInformation-NB.h"
+#include "RRCConnectionReconfiguration-NB.h"
+#include "RRCConnectionReconfigurationComplete-NB.h"
+#include "RRCConnectionSetup-NB.h"
+#include "RRCConnectionSetupComplete-NB.h"
+#include "RRCConnectionRequest-NB.h"
+#include "RRCConnectionReestablishmentRequest-NB.h"
+#include "BCCH-DL-SCH-Message-NB.h"
+#include "BCCH-BCH-Message-NB.h"
+#include "AS-Config-NB.h"
+#include "AS-Context-NB.h"
+#include "UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h
+//-------------------
+
+#if defined(ENABLE_ITTI)
+# include "intertask_interface.h"
+#endif
+
+/* TODO: be sure this include is correct.
+ * It solves a problem of compilation of the RRH GW,
+ * issue #186.
+ */
+#if !defined(ENABLE_ITTI)
+# include "as_message.h"
+#endif
+
+#if defined(ENABLE_USE_MME)
+# include "commonDef.h"
+#endif
+
+#if ENABLE_RAL
+# include "collection/hashtable/obj_hashtable.h"
+#endif
+
+
+
+/*I will change the name of the structure for compile purposes--> hope not to undo this process*/
+
+typedef unsigned int uid_NB_IoT_t;
+#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT (((NUMBER_OF_UE_MAX_NB_IoT/8)/sizeof(unsigned int)) + 1)
+
+typedef struct uid_linear_allocator_NB_IoT_s {
+  unsigned int   bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT];
+} uid_allocator_NB_IoT_t;
+
+
+#define PROTOCOL_RRC_CTXT_UE_FMT           PROTOCOL_CTXT_FMT
+#define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp)
+
+#define PROTOCOL_RRC_CTXT_FMT           PROTOCOL_CTXT_FMT
+#define PROTOCOL_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp)
+
+
+//left as they are --> used in LAYER2/epenair2_proc.c and UE side
+typedef enum UE_STATE_NB_IoT_e {
+ RRC_INACTIVE_NB_IoT=0,
+ RRC_IDLE_NB_IoT,
+ RRC_SI_RECEIVED_NB_IoT,
+ RRC_CONNECTED_NB_IoT,
+ RRC_RECONFIGURED_NB_IoT,
+ RRC_HO_EXECUTION_NB_IoT //maybe not needed?
+} UE_STATE_NB_IoT_t;
+
+
+/** @defgroup _rrc RRC
+ * @ingroup _oai2
+ * @{
+ */
+typedef struct UE_RRC_INFO_NB_IoT_s {
+  UE_STATE_NB_IoT_t State;
+  uint8_t SIB1systemInfoValueTag;
+  uint32_t SIStatus;
+  uint32_t SIcnt;
+#if defined(Rel10) || defined(Rel14)
+  uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA
+#endif
+  uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40
+  uint8_t handoverTarget;
+  //HO_STATE_t ho_state;
+  uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120
+  unsigned short UE_index;
+  uint32_t T300_active;
+  uint32_t T300_cnt;
+  uint32_t T304_active;
+  uint32_t T304_cnt;
+  uint32_t T310_active;
+  uint32_t T310_cnt;
+  uint32_t N310_cnt;
+  uint32_t N311_cnt;
+  rnti_t   rnti;
+} __attribute__ ((__packed__)) UE_RRC_INFO_NB_IoT;
+
+//#define NUM_PRECONFIGURED_LCHAN (NB_CH_CX*2)  //BCCH, CCCH
+
+#define UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!!
+#define UE_INDEX_INVALID  ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1
+
+
+
+// HO_STATE is not supported by NB-IoT
+
+//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG
+#define RRM_FREE(p)       if ( (p) != NULL) { free(p) ; p=NULL ; }
+#define RRM_MALLOC(t,n)   (t *) malloc16( sizeof(t) * n )
+#define RRM_CALLOC(t,n)   (t *) malloc16( sizeof(t) * n)
+#define RRM_CALLOC2(t,s)  (t *) malloc16( s )
+
+//Measurement Report not supported in NB-IoT
+
+#define PAYLOAD_SIZE_MAX 1024
+#define RRC_BUF_SIZE 255
+#define UNDEF_SECURITY_MODE 0xff
+#define NO_SECURITY_MODE 0x20
+
+/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */
+#define RRC_TRANSACTION_IDENTIFIER_NUMBER  3
+
+typedef struct UE_S_TMSI_NB_IoT_s {
+  boolean_t  presence;
+  mme_code_t mme_code;
+  m_tmsi_t   m_tmsi;
+} __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT;
+
+
+typedef enum e_rab_satus_NB_IoT_e {
+  E_RAB_STATUS_NEW_NB_IoT,
+  E_RAB_STATUS_DONE_NB_IoT, // from the eNB perspective
+  E_RAB_STATUS_ESTABLISHED_NB_IoT, // get the reconfigurationcomplete form UE
+  E_RAB_STATUS_FAILED_NB_IoT,
+} e_rab_status_NB_IoT_t;
+
+typedef struct e_rab_param_NB_IoT_s {
+  e_rab_t param;
+  uint8_t status;
+  uint8_t xid; // transaction_id
+} __attribute__ ((__packed__)) e_rab_param_NB_IoT_t;
+
+
+//HANDOVER_INFO not implemented in NB-IoT delete
+
+
+#define RRC_HEADER_SIZE_MAX 64
+#define RRC_BUFFER_SIZE_MAX 1024
+
+typedef struct {
+  char Payload[RRC_BUFFER_SIZE_MAX];
+  char Header[RRC_HEADER_SIZE_MAX];
+  char payload_size;
+} RRC_BUFFER_NB_IoT;
+
+#define RRC_BUFFER_SIZE_NB_IoT sizeof(RRC_BUFFER_NB_IoT)
+
+
+typedef struct RB_INFO_NB_IoT_s {
+  uint16_t Rb_id;  //=Lchan_id
+  //LCHAN_DESC Lchan_desc[2]; no more used
+  //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT
+} RB_INFO_NB_IoT;
+
+typedef struct SRB_INFO_NB_IoT_s {
+  uint16_t Srb_id;  //=Lchan_id---> useful for distinguish between SRB1 and SRB1bis?
+  RRC_BUFFER_NB_IoT Rx_buffer;
+  RRC_BUFFER_NB_IoT Tx_buffer;
+  //LCHAN_DESC Lchan_desc[2]; no more used
+  unsigned int Trans_id;
+  uint8_t Active;
+} SRB_INFO_NB_IoT;
+
+
+typedef struct RB_INFO_TABLE_ENTRY_NB_IoT_s {
+  RB_INFO_NB_IoT Rb_info;
+  uint8_t Active;
+  uint32_t Next_check_frame;
+  uint8_t Status;
+} RB_INFO_TABLE_ENTRY_NB_IoT;
+
+typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s {
+  SRB_INFO_NB_IoT Srb_info;
+  uint8_t Active;
+  uint8_t Status;
+  uint32_t Next_check_frame;
+} SRB_INFO_TABLE_ENTRY_NB_IoT;
+
+//MEAS_REPORT_LIST_s not implemented in NB-IoT but is used at UE side
+//HANDOVER_INFO_UE not implemented in NB-IoT
+typedef struct HANDOVER_INFO_UE_NB_IoT_s {
+  PhysCellId_t targetCellId;
+  uint8_t measFlag;
+} HANDOVER_INFO_UE_NB_IoT;
+
+//NB-IoT eNB_RRC_UE_NB_IoT_s--(used as a context in eNB --> ue_context in rrc_eNB_ue_context)------
+typedef struct eNB_RRC_UE_NB_IoT_s {
+
+  EstablishmentCause_t               establishment_cause;
+  uint8_t                            primaryCC_id;
+  //in NB-IoT only SRB0, SRB1 and SRB1bis (until AS security activation) exist
+
+  /*MP: Concept behind List and List2
+   *
+   * SRB_configList --> is used for the actual list of SRBs that is managed/that should be send over the RRC message
+   * SRB_configList2--> refers to all the SRBs configured for that specific transaction identifier
+   * 					this because in a single transaction one or more SRBs could be established
+   * 					and you want to keep memory on what happen for every transaction
+   * Transaction ID (xid): is used to associate the proper RRC....Complete message received by the UE to the corresponding
+   * 					   message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete)
+   * 					   this because it could happen that more messages are transmitted at the same time
+   */
+  SRB_ToAddModList_NB_r13_t*                SRB_configList;//for SRB1 and SRB1bis
+  SRB_ToAddModList_NB_r13_t*                SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
+  DRB_ToAddModList_NB_r13_t*                DRB_configList; //for all the DRBs
+  DRB_ToAddModList_NB_r13_t*                DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid
+  uint8_t                            		DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT
+
+  struct PhysicalConfigDedicated_NB_r13*    physicalConfigDedicated_NB_IoT;
+  MAC_MainConfig_NB_r13_t*           mac_MainConfig_NB_IoT;
+
+  //No SPS(semi-persistent scheduling) in NB-IoT
+  //No Measurement report in NB-IoT
+
+  SRB_INFO_NB_IoT                           SI;
+  SRB_INFO_NB_IoT                           Srb0;
+  SRB_INFO_TABLE_ENTRY_NB_IoT               Srb1;
+  SRB_INFO_TABLE_ENTRY_NB_IoT               Srb1bis;
+
+#if defined(ENABLE_SECURITY)
+  /* KeNB as derived from KASME received from EPC */
+  uint8_t kenb[32];
+#endif
+
+  /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */
+  e_CipheringAlgorithm_r12     ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version
+  e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
+
+  uint8_t                            Status;
+  rnti_t                             rnti;
+  uint64_t                           random_ue_identity;
+
+
+
+  /* Information from UE RRC ConnectionRequest-NB-r13_IE--> NB-IoT */
+  UE_S_TMSI_NB_IoT                          Initialue_identity_s_TMSI;
+  EstablishmentCause_NB_r13_t               establishment_cause_NB_IoT; //different set for NB-IoT
+
+  /* Information from UE RRC ConnectionReestablishmentRequest-NB--> NB-IoT */
+  ReestablishmentCause_NB_r13_t             reestablishment_cause_NB_IoT; //different set for NB_IoT
+
+  /* UE id for initial connection to S1AP */
+  uint16_t                           ue_initial_id;
+
+  /* Information from S1AP initial_context_setup_req */
+  uint32_t                           eNB_ue_s1ap_id :24;
+
+  security_capabilities_t            security_capabilities;
+
+  /* Total number of e_rab already setup in the list */ //NAS list?
+  uint8_t                           setup_e_rabs;
+  /* Number of e_rab to be setup in the list */ //NAS list?
+  uint8_t                            nb_of_e_rabs;
+  /* list of e_rab to be setup by RRC layers */
+  e_rab_param_NB_IoT_t                      e_rab[NB_RB_MAX_NB_IOT];//[S1AP_MAX_E_RAB];
+
+  // LG: For GTPV1 TUNNELS
+  uint32_t                           enb_gtp_teid[S1AP_MAX_E_RAB];
+  transport_layer_addr_t             enb_gtp_addrs[S1AP_MAX_E_RAB];
+  rb_id_t                            enb_gtp_ebi[S1AP_MAX_E_RAB];
+
+ //Which timers are referring to?
+  uint32_t                           ul_failure_timer;
+  uint32_t                           ue_release_timer;
+  //threshold of the release timer--> set in RRCConnectionRelease
+  uint32_t                           ue_release_timer_thres;
+} eNB_RRC_UE_NB_IoT_t;
+//--------------------------------------------------------------------------------
+
+typedef uid_NB_IoT_t ue_uid_t;
+
+
+//generally variable called: ue_context_pP
+typedef struct rrc_eNB_ue_context_NB_IoT_s {
+
+  /* Tree related data */
+  RB_ENTRY(rrc_eNB_ue_context_NB_IoT_s) entries;
+
+  /* Uniquely identifies the UE between MME and eNB within the eNB.
+   * This id is encoded on 24bits.
+   */
+  rnti_t         ue_id_rnti;
+
+  // another key for protocol layers but should not be used as a key for RB tree
+  ue_uid_t       local_uid;
+
+  /* UE id for initial connection to S1AP */
+  struct eNB_RRC_UE_NB_IoT_s   ue_context; //context of ue in the e-nB
+
+} rrc_eNB_ue_context_NB_IoT_t;
+
+
+
+//---NB-IoT (completely changed)-------------------------------
+//called "carrier"--> data from PHY layer
+typedef struct {
+
+  // buffer that contains the encoded messages
+  uint8_t							*MIB_NB_IoT;
+  uint8_t							sizeof_MIB_NB_IoT;
+
+  uint8_t                           *SIB1_NB_IoT;
+  uint8_t                           sizeof_SIB1_NB_IoT;
+  uint8_t                         	*SIB23_NB_IoT;
+  uint8_t                        	sizeof_SIB23_NB_IoT;
+
+
+  //not actually implemented in OAI
+  uint8_t                           *SIB4_NB_IoT;
+  uint8_t                           sizeof_SIB4_NB_IoT;
+  uint8_t                           *SIB5_NB_IoT;
+  uint8_t                           sizeof_SIB5_NB_IoT;
+  uint8_t                           *SIB14_NB_IoT;
+  uint8_t                           sizeof_SIB14_NB_IoT;
+  uint8_t                           *SIB16_NB_IoT;
+  uint8_t                           sizeof_SIB16_NB_IoT;
+
+  //TS 36.331 V14.2.1
+//  uint8_t                           *SIB15_NB;
+//  uint8_t                           sizeof_SIB15_NB;
+//  uint8_t                           *SIB20_NB;
+//  uint8_t                           sizeof_SIB20_NB;
+//  uint8_t                           *SIB22_NB;
+//  uint8_t                           sizeof_SIB22_NB;
+
+  //implicit parameters needed
+  int                               Ncp; //cyclic prefix for DL
+  int								Ncp_UL; //cyclic prefix for UL
+  int                               p_eNB; //number of tx antenna port
+  int								p_rx_eNB; //number of receiving antenna ports
+  uint32_t                          dl_CarrierFreq; //detected by the UE
+  uint32_t                          ul_CarrierFreq; //detected by the UE
+  uint16_t                          physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS
+
+  //are the only static one (memory has been already allocated)
+  BCCH_BCH_Message_NB_t                mib_NB_IoT;
+  BCCH_DL_SCH_Message_NB_t             siblock1_NB_IoT; //SIB1-NB
+  BCCH_DL_SCH_Message_NB_t             systemInformation_NB_IoT; //SI
+
+  SystemInformationBlockType1_NB_t     		*sib1_NB_IoT;
+  SystemInformationBlockType2_NB_r13_t   	*sib2_NB_IoT;
+  SystemInformationBlockType3_NB_r13_t   	*sib3_NB_IoT;
+  //not implemented yet
+  SystemInformationBlockType4_NB_r13_t    	*sib4_NB_IoT;
+  SystemInformationBlockType5_NB_r13_t     	*sib5_NB_IoT;
+  SystemInformationBlockType14_NB_r13_t     *sib14_NB_IoT;
+  SystemInformationBlockType16_NB_r13_t     *sib16_NB_IoT;
+
+
+  SRB_INFO_NB_IoT                          SI;
+  SRB_INFO_NB_IoT                          Srb0;
+
+  uint8_t                           **MCCH_MESSAGE; //  probably not needed , but added to remove errors
+  uint8_t                           sizeof_MCCH_MESSAGE[8];// but added to remove errors
+  SRB_INFO_NB_IoT                          MCCH_MESS[8];// MAX_MBSFN_AREA
+  /*future implementation TS 36.331 V14.2.1
+  SystemInformationBlockType15_NB_r14_t     *sib15;
+  SystemInformationBlockType20_NB_r14_t     *sib20;
+  SystemInformationBlockType22_NB_r14_t     *sib22;
+
+  uint8_t							SCPTM_flag;
+  uint8_t							sizeof_SC_MCHH_MESS[];
+  SC_MCCH_Message_NB_t				scptm;*/
+
+
+} rrc_eNB_carrier_data_NB_IoT_t;
+//---------------------------------------------------
+
+
+
+//---NB-IoT---(completely change)---------------------
+typedef struct eNB_RRC_INST_NB_IoT_s {
+
+  rrc_eNB_carrier_data_NB_IoT_t          carrier[MAX_NUM_CCs];
+
+  uid_allocator_NB_IoT_t                    uid_allocator; // for rrc_ue_head
+  RB_HEAD(rrc_ue_tree_NB_IoT_s, rrc_eNB_ue_context_NB_IoT_s)     rrc_ue_head; // ue_context tree key search by rnti
+
+  uint8_t                           Nb_ue;
+
+  hash_table_t                      *initial_id2_s1ap_ids; // key is    content is rrc_ue_s1ap_ids_t
+  hash_table_t                      *s1ap_id2_s1ap_ids   ; // key is    content is rrc_ue_s1ap_ids_t
+
+  //RRC configuration
+  RrcConfigurationReq configuration; //rrc_messages_types.h
+
+  // other PLMN parameters
+  /// Mobile country code
+  int mcc;
+  /// Mobile network code
+  int mnc;
+  /// number of mnc digits
+  int mnc_digit_length;
+
+  // other RAN parameters //FIXME: to be checked--> depends on APP layer
+  int srb1_timer_poll_retransmit;
+  int srb1_max_retx_threshold;
+  int srb1_timer_reordering;
+  int srb1_timer_status_prohibit;
+  int srs_enable[MAX_NUM_CCs];
+
+
+} eNB_RRC_INST_NB_IoT;
+
+#define RRC_HEADER_SIZE_MAX_NB_IoT 64
+#define MAX_UE_CAPABILITY_SIZE_NB_IoT 255
+
+//not needed for the moment
+typedef struct OAI_UECapability_NB_IoT_s {
+ uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT];
+ uint8_t sdu_size;
+////NB-IoT------
+  UE_Capability_NB_r13_t  UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE
+} OAI_UECapability_NB_IoT_t;
+
+#define RRC_BUFFER_SIZE_MAX_NB_IoT 1024
+
+
+
+typedef struct UE_RRC_INST_NB_IoT_s {
+  Rrc_State_NB_IoT_t     RrcState;
+  Rrc_Sub_State_NB_IoT_t RrcSubState;
+# if defined(ENABLE_USE_MME)
+  plmn_t          plmnID;
+  Byte_t          rat;
+  as_nas_info_t   initialNasMsg;
+# endif
+  OAI_UECapability_NB_IoT_t *UECap;
+  uint8_t *UECapability;
+  uint8_t UECapability_size;
+
+  UE_RRC_INFO_NB_IoT Info[NB_SIG_CNX_UE];
+  
+  SRB_INFO_NB_IoT                 Srb0[NB_SIG_CNX_UE];
+  SRB_INFO_TABLE_ENTRY_NB_IoT     Srb1[NB_CNX_UE];
+  SRB_INFO_TABLE_ENTRY_NB_IoT     Srb2[NB_CNX_UE];
+  HANDOVER_INFO_UE_NB_IoT         HandoverInfoUe;
+  /*
+  uint8_t *SIB1[NB_CNX_UE];
+  uint8_t sizeof_SIB1[NB_CNX_UE];
+  uint8_t *SI[NB_CNX_UE];
+  uint8_t sizeof_SI[NB_CNX_UE];
+  uint8_t SIB1Status[NB_CNX_UE];
+  uint8_t SIStatus[NB_CNX_UE];
+  SystemInformationBlockType1_t *sib1[NB_CNX_UE];
+  SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI().
+  */
+  SystemInformationBlockType2_t *sib2[NB_CNX_UE];
+  /*
+  SystemInformationBlockType3_t *sib3[NB_CNX_UE];
+  SystemInformationBlockType4_t *sib4[NB_CNX_UE];
+  SystemInformationBlockType5_t *sib5[NB_CNX_UE];
+  SystemInformationBlockType6_t *sib6[NB_CNX_UE];
+  SystemInformationBlockType7_t *sib7[NB_CNX_UE];
+  SystemInformationBlockType8_t *sib8[NB_CNX_UE];
+  SystemInformationBlockType9_t *sib9[NB_CNX_UE];
+  SystemInformationBlockType10_t *sib10[NB_CNX_UE];
+  SystemInformationBlockType11_t *sib11[NB_CNX_UE];
+
+#if defined(Rel10) || defined(Rel14)
+  uint8_t                           MBMS_flag;
+  uint8_t *MCCH_MESSAGE[NB_CNX_UE];
+  uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE];
+  uint8_t MCCH_MESSAGEStatus[NB_CNX_UE];
+  MBSFNAreaConfiguration_r9_t       *mcch_message[NB_CNX_UE];
+  SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE];
+  SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE];
+#endif
+#ifdef CBA
+  uint8_t                         num_active_cba_groups;
+  uint16_t                        cba_rnti[NUM_MAX_CBA_GROUP];
+#endif
+  uint8_t                         num_srb;
+  struct SRB_ToAddMod             *SRB1_config[NB_CNX_UE];
+  struct SRB_ToAddMod             *SRB2_config[NB_CNX_UE];
+  struct DRB_ToAddMod             *DRB_config[NB_CNX_UE][8];
+  rb_id_t                         *defaultDRB; // remember the ID of the default DRB
+  MeasObjectToAddMod_t            *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ];
+  struct ReportConfigToAddMod     *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG];
+  */
+  struct QuantityConfig           *QuantityConfig[NB_CNX_UE];
+  /*
+  struct MeasIdToAddMod           *MeasId[NB_CNX_UE][MAX_MEAS_ID];
+  MEAS_REPORT_LIST      *measReportList[NB_CNX_UE][MAX_MEAS_ID];
+  uint32_t           measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells
+  RSRP_Range_t                    s_measure;
+  struct MeasConfig__speedStatePars *speedStatePars;
+  struct PhysicalConfigDedicated  *physicalConfigDedicated[NB_CNX_UE];
+  struct SPS_Config               *sps_Config[NB_CNX_UE];
+  MAC_MainConfig_t                *mac_MainConfig[NB_CNX_UE];
+  MeasGapConfig_t                 *measGapConfig[NB_CNX_UE];
+  double                          filter_coeff_rsrp; // [7] ???
+  double                          filter_coeff_rsrq; // [7] ???
+  float                           rsrp_db[7];
+  float                           rsrq_db[7];
+  float                           rsrp_db_filtered[7];
+  float                           rsrq_db_filtered[7];
+#if ENABLE_RAL
+  obj_hash_table_t               *ral_meas_thresholds;
+  ral_transaction_id_t            scan_transaction_id;
+#endif
+#if defined(ENABLE_SECURITY)
+  // KeNB as computed from parameters within USIM card //
+  uint8_t kenb[32];
+#endif
+
+  // Used integrity/ciphering algorithms //
+  CipheringAlgorithm_r12_t                          ciphering_algorithm;
+  e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
+  */
+} UE_RRC_INST_NB_IoT;
+
+
+#include "proto_NB_IoT.h" //should be put here otherwise compilation error
+
+#endif
+/** @} */
diff --git a/openair2/RRC/LITE/extern_NB_IoT.h b/openair2/RRC/LITE/extern_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..23e7329aecf09ec9284c3b6f47b4f3ced8361aec
--- /dev/null
+++ b/openair2/RRC/LITE/extern_NB_IoT.h
@@ -0,0 +1,63 @@
+/*
+ * 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 vars.h
+* \brief rrc external vars
+* \author Navid Nikaein and Raymond Knopp, Michele Paffetti
+* \date 2011-2017
+* \version 1.0
+* \company Eurecom
+* \email: navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it
+*/
+
+#ifndef __OPENAIR_RRC_EXTERN_NB_IOT_H__
+#define __OPENAIR_RRC_EXTERN_NB_IOT_H__
+#include "RRC/LITE/defs_NB_IoT.h"
+#include "PHY_INTERFACE/IF_Module_NB_IoT.h"
+#include "LAYER2/RLC/rlc.h"
+#include "LogicalChannelConfig-NB-r13.h"
+#include "LAYER2/MAC/defs_NB_IoT.h"
+
+#include "common/ran_context.h"
+
+
+//MP: NOTE:XXX some of the parameters defined in vars_nb_iot are called by the extern.h file so not replicated here
+
+extern UE_RRC_INST_NB_IoT 					*UE_rrc_inst_NB_IoT;
+
+extern eNB_RRC_INST_NB_IoT 					*eNB_rrc_inst_NB_IoT;
+extern PHY_Config_NB_IoT_t 						*config_INFO;
+
+extern rlc_info_t 							Rlc_info_am_NB_IoT,Rlc_info_am_config_NB_IoT;
+extern uint8_t 								DRB2LCHAN_NB_IoT[2];
+extern LogicalChannelConfig_NB_r13_t 		SRB1bis_logicalChannelConfig_defaultValue_NB_IoT;
+extern LogicalChannelConfig_NB_r13_t 		SRB1_logicalChannelConfig_defaultValue_NB_IoT;
+
+extern uint16_t 							T300_NB_IoT[8];
+extern uint16_t 							T301_NB_IoT[8];
+extern uint16_t 							T310_NB_IoT[8];
+extern uint16_t 							T311_NB_IoT[8];
+extern uint16_t 							N310_NB_IoT[8];
+extern uint16_t 							N311_NB_IoT[8];
+extern uint8_t *get_NB_IoT_MIB(struct eNB_RRC_INST_NB_IoT_s *nb_iot_rrc);
+#endif
+
+
diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h
index 49cf9f2ebac23f3081fb0b02b2efb893b406a7e2..b92058741940a5aa8ee91b18b664f2cbd5bb0d46 100644
--- a/openair2/RRC/LITE/proto.h
+++ b/openair2/RRC/LITE/proto.h
@@ -410,6 +410,7 @@ rrc_data_req(
 );
 
 uint8_t
+
 rrc_data_req_ue(
   const protocol_ctxt_t*   const ctxt_pP,
   const rb_id_t                  rb_idP,
@@ -420,6 +421,7 @@ rrc_data_req_ue(
   const pdcp_transmission_mode_t modeP
 );
 
+
 void
 rrc_data_ind(
   const protocol_ctxt_t* const ctxt_pP,
diff --git a/openair2/RRC/LITE/proto_NB_IoT.h b/openair2/RRC/LITE/proto_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2f8e5b5c927d80d376123abb0b3ee607f6cbab1
--- /dev/null
+++ b/openair2/RRC/LITE/proto_NB_IoT.h
@@ -0,0 +1,260 @@
+/* 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 proto_NB_IoT.h
+ * \brief RRC functions prototypes for eNB and UE for NB-IoT
+ * \author Navid Nikaein, Raymond Knopp and Michele Paffetti
+ * \date 2010 - 2014
+ * \email navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it
+ * \version 1.0
+
+ */
+/** \addtogroup _rrc
+ *  @{
+ */
+
+#include "RRC/LITE/defs_NB_IoT.h"
+#include "pdcp.h"
+#include "rlc.h"
+#include "extern_NB_IoT.h"
+#include "LAYER2/MAC/defs_NB_IoT.h"
+/*NOTE: no static function should be declared in this header file (e.g. init_SI_NB)*/
+
+/*------------------------common_nb_iot.c----------------------------------------*/
+
+/** \brief configure  BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs
+ */
+void openair_rrc_on_NB_IoT(const protocol_ctxt_t* const ctxt_pP);
+
+void rrc_config_buffer_NB_IoT(SRB_INFO_NB_IoT *srb_info, uint8_t Lchan_type, uint8_t Role);
+
+int L3_xface_init_NB_IoT(void);
+
+void openair_rrc_top_init_eNB_NB_IoT(void);
+
+//void rrc_top_cleanup(void); -->seems not to be used
+
+//rrc_t310_expiration-->seems not to be used
+
+/** \brief Function to update timers every subframe.  For UE it updates T300,T304 and T310.
+@param ctxt_pP  running context
+@param enb_index
+@param CC_id
+*/
+RRC_status_t rrc_rx_tx_NB_IoT(protocol_ctxt_t* const ctxt_pP, const uint8_t  enb_index, const int CC_id);
+
+//long binary_search_int(int elements[], long numElem, int value);--> seems not to be used
+//long binary_search_float(float elements[], long numElem, float value);--> used only at UE side
+
+
+
+//---------------------------------------
+
+
+//defined in L2_interface
+//called by rx_sdu only in case of CCCH message (e.g RRCConnectionRequest-NB)
+int8_t mac_rrc_data_ind_eNB_NB_IoT(
+  const module_id_t     module_idP,
+  const int             CC_id,
+  const frame_t         frameP,
+  const sub_frame_t     sub_frameP,
+  const rnti_t          rntiP,
+  const rb_id_t         srb_idP,//could be skipped since always go through the CCCH channel
+  const uint8_t*        sduP,
+  const sdu_size_t      sdu_lenP
+);
+//-------------------------------------------
+
+//defined in L2_interface
+void dump_ue_list_NB_IoT(UE_list_NB_IoT_t *listP, int ul_flag);
+//-------------------------------------------
+
+
+//defined in L2_interface
+void mac_eNB_rrc_ul_failure_NB_IoT(
+		const module_id_t mod_idP,
+	    const int CC_idP,
+	    const frame_t frameP,
+	    const sub_frame_t subframeP,
+	    const rnti_t rntiP);
+//------------------------------------------
+
+//defined in eNB_scheduler_primitives.c
+int rrc_mac_remove_ue_NB_IoT(
+		module_id_t mod_idP,
+		rnti_t rntiP);
+//------------------------------------------
+//defined in L2_interface
+void mac_eNB_rrc_ul_in_sync_NB_IoT(
+				const module_id_t mod_idP,
+			    const int CC_idP,
+			    const frame_t frameP,
+			    const sub_frame_t subframeP,
+			    const rnti_t rntiP);
+//------------------------------------------
+//defined in L2_interface
+int mac_eNB_get_rrc_status_NB_IoT(
+  const module_id_t Mod_idP,
+  const rnti_t      rntiP
+);
+//---------------------------
+
+
+/*-----------eNB procedures (rrc_eNB_nb_iot.c)---------------*/
+
+//---Initialization--------------
+void openair_eNB_rrc_on_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP
+);
+
+void rrc_config_buffer_NB_IoT(
+  SRB_INFO_NB_IoT* Srb_info,
+  uint8_t Lchan_type,
+  uint8_t Role
+);
+
+char openair_rrc_eNB_configuration_NB_IoT(
+  const module_id_t enb_mod_idP,
+  NbIoTRrcConfigurationReq* configuration
+);
+
+//-----------------------------
+/**\brief RRC eNB task. (starting of the RRC state machine)
+   \param void *args_p Pointer on arguments to start the task. */
+void *rrc_enb_task_NB_IoT(void *args_p);
+
+/**\brief Entry routine to decode a UL-CCCH-Message-NB.  Invokes PER decoder and parses message.
+   \param ctxt_pP Running context
+   \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/
+int rrc_eNB_decode_ccch_NB_IoT(
+  protocol_ctxt_t* const ctxt_pP,
+  const SRB_INFO_NB_IoT*        const Srb_info,
+  const int              CC_id
+);
+
+/**\brief Entry routine to decode a UL-DCCH-Message-NB.  Invokes PER decoder and parses message.
+   \param ctxt_pP Context
+   \param Rx_sdu Pointer Received Message
+   \param sdu_size Size of incoming SDU*/
+int rrc_eNB_decode_dcch_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  const rb_id_t                Srb_id,
+  const uint8_t*    const      Rx_sdu,
+  const sdu_size_t             sdu_sizeP
+);
+
+/**\brief Generate RRCConnectionReestablishmentReject-NB
+   \param ctxt_pP       Running context
+   \param ue_context_pP UE context
+   \param CC_id         Component Carrier ID*/
+void rrc_eNB_generate_RRCConnectionReestablishmentReject_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*          const ue_context_pP,
+  const int                    CC_id
+);
+
+void rrc_eNB_generate_RRCConnectionReject_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*          const ue_context_pP,
+  const int                    CC_id
+);
+
+void rrc_eNB_generate_RRCConnectionSetup_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*          const ue_context_pP,
+  const int                    CC_id
+);
+
+void rrc_eNB_process_RRCConnectionReconfigurationComplete_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*        ue_context_pP,
+  const uint8_t xid //transaction identifier
+);
+
+
+void //was under ITTI
+rrc_eNB_reconfigure_DRBs_NB_IoT(const protocol_ctxt_t* const ctxt_pP,
+			       rrc_eNB_ue_context_NB_IoT_t*  ue_context_pP);
+
+void //was under ITTI
+rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT(
+		const protocol_ctxt_t* const ctxt_pP,
+	    rrc_eNB_ue_context_NB_IoT_t*          const ue_context_pP
+//            const uint8_t      ho_state
+	     );
+
+void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*         ue_context_pP,
+  RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB
+);
+
+void rrc_eNB_generate_SecurityModeCommand_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*          const ue_context_pP
+);
+
+void rrc_eNB_generate_UECapabilityEnquiry_NB_IoT(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_NB_IoT_t*          const ue_context_pP
+);
+
+void rrc_eNB_generate_defaultRRCConnectionReconfiguration_NB_IoT(const protocol_ctxt_t* const ctxt_pP,
+						                                                     rrc_eNB_ue_context_NB_IoT_t*          const ue_context_pP
+						                                                     //no HO flag
+						                                                    );
+
+
+/// Utilities------------------------------------------------
+
+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
+		);
+
+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
+);
+
+
+
+/**\brief Function to get the next transaction identifier.
+   \param module_idP Instance ID for CH/eNB
+   \return a transaction identifier*/
+uint8_t rrc_eNB_get_next_transaction_identifier_NB_IoT(module_id_t module_idP);
+
+
+int rrc_init_global_param_NB_IoT(void);
+
+//L2_interface.c
+int8_t mac_rrc_data_req_eNB_NB_IoT(
+  const module_id_t Mod_idP,
+  const int         CC_id,
+  const frame_t     frameP,
+  const frame_t   h_frameP,
+  const sub_frame_t   subframeP, //need for the case in which both SIB1-NB_IoT and SIB23-NB_IoT will be scheduled in the same frame
+  const rb_id_t     Srb_id,
+  uint8_t* const buffer_pP,
+  uint8_t   flag
+);
+
+
+
diff --git a/openair2/RRC/LITE/rrc_types_NB_IoT.h b/openair2/RRC/LITE/rrc_types_NB_IoT.h
new file mode 100644
index 0000000000000000000000000000000000000000..55e98ea5f1bc5248387aa1baf2303cc7fd00e775
--- /dev/null
+++ b/openair2/RRC/LITE/rrc_types_NB_IoT.h
@@ -0,0 +1,64 @@
+/*
+ * 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 rrc_types.h
+* \brief rrc types and subtypes
+* \author Navid Nikaein and Raymond Knopp
+* \date 2011 - 2014
+* \version 1.0
+* \company Eurecom
+* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr
+*/
+
+#ifndef RRC_TYPES_NB_IOT_H_
+#define RRC_TYPES_NB_IOT_H_
+
+typedef enum Rrc_State_NB_IoT_e {
+  RRC_STATE_INACTIVE_NB_IoT=0,
+  RRC_STATE_IDLE_NB_IoT,
+  RRC_STATE_CONNECTED_NB_IoT,
+
+  RRC_STATE_FIRST_NB_IoT = RRC_STATE_INACTIVE_NB_IoT,
+  RRC_STATE_LAST_NB_IoT = RRC_STATE_CONNECTED_NB_IoT,
+} Rrc_State_NB_IoT_t;
+
+typedef enum Rrc_Sub_State_NB_IoT_e {
+  RRC_SUB_STATE_INACTIVE_NB_IoT=0,
+
+  RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT,
+  RRC_SUB_STATE_IDLE_RECEIVING_SIB_NB_IoT,
+  RRC_SUB_STATE_IDLE_SIB_COMPLETE_NB_IoT,
+  RRC_SUB_STATE_IDLE_CONNECTING_NB_IoT,
+  RRC_SUB_STATE_IDLE_NB_IoT,
+
+  RRC_SUB_STATE_CONNECTED_NB_IoT,
+
+  RRC_SUB_STATE_INACTIVE_FIRST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT,
+  RRC_SUB_STATE_INACTIVE_LAST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT,
+
+  RRC_SUB_STATE_IDLE_FIRST_NB_IoT = RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT,
+  RRC_SUB_STATE_IDLE_LAST_NB_IoT = RRC_SUB_STATE_IDLE_NB_IoT,
+
+  RRC_SUB_STATE_CONNECTED_FIRST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT,
+  RRC_SUB_STATE_CONNECTED_LAST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT,
+} Rrc_Sub_State_NB_IoT_t;
+
+#endif /* RRC_TYPES_H_ */
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index a2517e07b84b162dd4fbfe55a02669f1fb7505f4..7f63e8c1ce6fdd179aa6a565bd61ef0dfbdc4ee1 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -53,6 +53,7 @@
 
 #undef GTP_DUMP_SOCKET
 
+/*
 extern boolean_t pdcp_data_req(
   const protocol_ctxt_t* const  ctxt_pP,
   const srb_flag_t     srb_flagP,
@@ -62,7 +63,7 @@ extern boolean_t pdcp_data_req(
   const sdu_size_t     sdu_buffer_sizeP,
   unsigned char *const sdu_buffer_pP,
   const pdcp_transmission_mode_t modeP);
-
+*/
 extern unsigned char NB_eNB_INST;
 extern RAN_CONTEXT_t RC;
 
diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h
index 63f5b96c330357d670606d49d13e9e2ed587fc1d..98de4a024f5225e7d061dc3d1ba09c2ec8802bad 100644
--- a/targets/COMMON/openairinterface5g_limits.h
+++ b/targets/COMMON/openairinterface5g_limits.h
@@ -11,7 +11,6 @@
 #        define NUMBER_OF_RU_MAX 32
 #        define NUMBER_OF_UE_MAX 20
 #        define NUMBER_OF_CONNECTED_eNB_MAX 3
-
 #        if defined(STANDALONE) && STANDALONE==1
 #                undef  NUMBER_OF_eNB_MAX
 #                undef  NUMBER_OF_UE_MAX
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 71ee86ecf185fd3a712bb192480578bfe312cb5c..6b52bab64cbb14505aba552f88d66d8863c12e9a 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -100,7 +100,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "stats.h"
 #endif
 #include "lte-softmodem.h"
-
+#include "NB_IoT_interface.h"
 #ifdef XFORMS
 // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
 // at eNB 0, an UL scope for every UE
@@ -560,6 +560,14 @@ static void get_options(void) {
       NB_eNB_INST = RC.nb_inst;
       NB_RU	  = RC.nb_RU;
       printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU);
+      if (nonbiotflag <= 0) {
+         load_NB_IoT();
+         printf("               nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n",
+                RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst);
+      } else {
+         printf("All Nb-IoT instances disabled\n");
+         RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0;
+      }
    }
 }