diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index 0c44982961393bbd07e66db0c39a739a0687f6c6..e5799a075ad8925d4a4418f7001ecb1582378930 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
@@ -594,7 +594,7 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
   
 #ifdef USER_MODE // need to be adapted for the emulation in the kernel space 
   if (uniformrandom() < bler) {
-    LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
+    LOG_N(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
     return(0);
   }
   else {
@@ -671,7 +671,11 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     LOG_T(PHY,"\n current harq pid is %d ue id %d \n", harq_pid, ue_id);
 #endif
 
-    if (dlsch_abstraction_MIESM(phy_vars_ue->sinr_dB, phy_vars_ue->transmission_mode[eNB_id], dlsch_eNB->rb_alloc, dlsch_eNB->harq_processes[harq_pid]->mcs,PHY_vars_eNB_g[eNB_id]->mu_mimo_mode[ue_id].dl_pow_off) == 1) {
+    if (dlsch_abstraction_MIESM(phy_vars_ue->sinr_dB, 
+				phy_vars_ue->transmission_mode[eNB_id], 
+				dlsch_eNB->rb_alloc, 
+				dlsch_eNB->harq_processes[harq_pid]->mcs,
+				PHY_vars_eNB_g[eNB_id]->mu_mimo_mode[ue_id].dl_pow_off) == 1) {
       // reset HARQ 
       dlsch_ue->harq_processes[harq_pid]->status = SCH_IDLE;
       dlsch_ue->harq_processes[harq_pid]->round  = 0;
diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h
index c23fe3d8037674721f2ffa434b7a5199950d5ea3..784ebf21505e326d5c35137b7066f08f623ef512 100755
--- a/openair2/COMMON/platform_types.h
+++ b/openair2/COMMON/platform_types.h
@@ -96,6 +96,7 @@ typedef signed int         rlc_op_status_t;
 //-----------------------------------------------------------------------------
 typedef uint16_t           pdcp_sn_t;
 typedef uint32_t           pdcp_hfn_t;
+typedef int16_t            pdcp_hfn_offset_t;
 
 typedef enum pdcp_transmission_mode_e {
    PDCP_TRANSMISSION_MODE_UNKNOWN     = 0,
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 12e69f24e1009f23b2d5d319919e6bd9e91f1024..2b74d5fe9cbf2f9ea44bc66b8c1c7ada36e23198 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -4472,30 +4472,6 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
   //if (subframeP%5 == 0)
 #ifdef EXMIMO
   pdcp_run(frameP, 1, 0, module_idP);
-  /*
-  ret = pthread_mutex_trylock (&pdcp_mutex);
-  if (ret != 0) {
-    if (ret==EBUSY)
-      LOG_E(PDCP,"Mutex busy\n");
-    else
-      LOG_E(PDCP,"Cannot lock mutex\n");
-    //return(-1);
-  }
-  else {
-    pdcp_instance_cnt++;
-    pthread_mutex_unlock(&pdcp_mutex);
-
-    if (pdcp_instance_cnt == 0) {
-      if (pthread_cond_signal(&pdcp_cond) != 0) {
-	LOG_E(PDCP,"pthread_cond_signal unsuccessfull\n");
-	//return(-1);
-      }
-    }
-    else {
-      LOG_W(PDCP,"PDCP thread busy!!! inst_cnt=%d\n",pdcp_instance_cnt);
-    }
-  }
-   */
 #endif
 #ifdef CELLULAR
   rrc_rx_tx(module_idP, frameP, 0, 0);
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 9d12e0999213eaaf334b15811fe3a6c4938989a7..4aa42d298baceacf7a9be460ac8d79887a7627fb 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -283,11 +283,12 @@ boolean_t pdcp_data_req(
                 start_meas(&UE_pdcp_stats[ue_mod_idP].apply_security);
 
               pdcp_apply_security(pdcp_p,
-                  rb_idP % maxDRB,
-                  pdcp_header_len,
-                  current_sn,
-                  pdcp_pdu_p->data,
-                  sdu_buffer_sizeP);
+				  srb_flagP,
+				  rb_idP % maxDRB,
+				  pdcp_header_len,
+				  current_sn,
+				  pdcp_pdu_p->data,
+				  sdu_buffer_sizeP);
 
               if (enb_flagP == ENB_FLAG_NO)
                 stop_meas(&eNB_pdcp_stats[enb_mod_idP].apply_security);
@@ -510,14 +511,22 @@ boolean_t pdcp_data_ind(
        * Parse the PDU placed at the beginning of SDU to check
        * if incoming SN is in line with RX window
        */
-
-      if (pdcp_header_len == PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE) { // DRB
-          sequence_number =     pdcp_get_sequence_number_of_pdu_with_long_sn((unsigned char*)sdu_buffer_pP->data);
-          //       uint8_t dc = pdcp_get_dc_filed((unsigned char*)sdu_buffer->data);
-      } else { //SRB1/2
-          sequence_number =   pdcp_get_sequence_number_of_pdu_with_SRB_sn((unsigned char*)sdu_buffer_pP->data);
+      if (MBMS_flagP == 0 ) {
+	if (srb_flagP) { //SRB1/2
+	  sequence_number =   pdcp_get_sequence_number_of_pdu_with_SRB_sn((unsigned char*)sdu_buffer_pP->data);
+	} else { // DRB
+	   if (pdcp_p->seq_num_size == PDCP_SN_7BIT){
+	    sequence_number =     pdcp_get_sequence_number_of_pdu_with_short_sn((unsigned char*)sdu_buffer_pP->data);
+	   }else if (pdcp_p->seq_num_size == PDCP_SN_12BIT){
+	    sequence_number =     pdcp_get_sequence_number_of_pdu_with_long_sn((unsigned char*)sdu_buffer_pP->data);
+	  } else {
+	    //sequence_number = 4095;
+	    LOG_E(PDCP,"wrong sequence number  (%d) for this pdcp entity \n", pdcp_p->seq_num_size);
+	  }
+	  //uint8_t dc = pdcp_get_dc_filed((unsigned char*)sdu_buffer_pP->data);
+	}
       }
-      if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p) == TRUE) {
+      if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == TRUE) {
           LOG_D(PDCP, "Incoming PDU has a sequence number (%d) in accordance with RX window\n", sequence_number);
           /* if (dc == PDCP_DATA_PDU )
 	   LOG_D(PDCP, "Passing piggybacked SDU to NAS driver...\n");
@@ -546,19 +555,19 @@ boolean_t pdcp_data_ind(
               else
                 start_meas(&UE_pdcp_stats[ue_mod_idP].validate_security);
 
-              pdcp_validate_security(pdcp_p,
-                  rb_idP,
-                  pdcp_header_len,
-                  sequence_number,
-                  sdu_buffer_pP->data,
-                  sdu_buffer_sizeP - pdcp_tailer_len);
-
-              if (enb_flagP == ENB_FLAG_NO)
-                stop_meas(&eNB_pdcp_stats[enb_mod_idP].validate_security);
-              else
-                stop_meas(&UE_pdcp_stats[ue_mod_idP].validate_security);
-
-	}
+	  pdcp_validate_security(pdcp_p, 
+				 srb_flagP,
+				 rb_idP, 
+				 pdcp_header_len,
+				 sequence_number, 
+				 sdu_buffer_pP->data,
+				 sdu_buffer_sizeP - pdcp_tailer_len);
+	  if (enb_flagP == ENB_FLAG_NO)
+	    stop_meas(&eNB_pdcp_stats[enb_mod_idP].validate_security);
+	  else
+	    stop_meas(&UE_pdcp_stats[ue_mod_idP].validate_security);
+
+	  }
 #endif
 //rrc_lite_data_ind(module_id, //Modified MW - L2 Interface
           pdcp_rrc_data_ind(enb_mod_idP,
@@ -591,7 +600,11 @@ boolean_t pdcp_data_ind(
   if (oai_emulation.info.otg_enabled == 1) {
       module_id_t src_id, dst_id;
       int    ctime;
-
+   
+      if (pdcp_p->rlc_mode == RLC_MODE_AM ) {
+	pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; 
+      }
+   
       rlc_util_print_hex_octets(PDCP,
                                 (unsigned char*)&sdu_buffer_pP->data[payload_offset],
                                 sdu_buffer_sizeP - payload_offset);
@@ -626,6 +639,9 @@ boolean_t pdcp_data_ind(
   new_sdu_p = get_free_mem_block(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t));
 
   if (new_sdu_p) {
+    if (pdcp_p->rlc_mode == RLC_MODE_AM ) {
+      pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; 
+    }
       /*
        * Prepend PDCP indication header which is going to be removed at pdcp_fifo_flush_sdus()
        */
@@ -854,7 +870,7 @@ boolean_t rrc_pdcp_config_asn1_req (
   rlc_mode_t      rlc_type       = RLC_MODE_NONE;
   DRB_Identity_t  drb_id         = 0;
   DRB_Identity_t *pdrb_id_p      = NULL;
-  uint8_t         drb_sn         = 0;
+  uint8_t         drb_sn         = 12;
   uint8_t         srb_sn         = 5; // fixed sn for SRBs
   uint8_t         drb_report     = 0;
   long int        cnt            = 0;
@@ -968,7 +984,8 @@ boolean_t rrc_pdcp_config_asn1_req (
               }
               if (drb_toaddmod_p->pdcp_Config->rlc_AM) {
                   drb_report = drb_toaddmod_p->pdcp_Config->rlc_AM->statusReportRequired;
-                  rlc_type =RLC_MODE_AM;
+		  drb_sn = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; // default SN size 
+                  rlc_type = RLC_MODE_AM;
               }
               if (drb_toaddmod_p->pdcp_Config->rlc_UM){
                   drb_sn = drb_toaddmod_p->pdcp_Config->rlc_UM->pdcp_SN_Size;
@@ -1149,32 +1166,35 @@ boolean_t pdcp_config_req_asn1 (pdcp_t   *pdcp_pP,
     pdcp_pP->header_compression_profile = header_compression_profileP;
     pdcp_pP->status_report              = rb_reportP;
 
-    if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
-        pdcp_pP->seq_num_size = 7;
-    } else if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) {
-        pdcp_pP->seq_num_size = 12;
+    if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) {
+        pdcp_pP->seq_num_size = PDCP_SN_12BIT;
+    } else if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
+        pdcp_pP->seq_num_size = PDCP_SN_7BIT;
     } else {
-        pdcp_pP->seq_num_size = 5;
+        pdcp_pP->seq_num_size = PDCP_SN_5BIT;
     }
 
-    pdcp_pP->rlc_mode                  = rlc_modeP;
-    pdcp_pP->next_pdcp_tx_sn           = 0;
-    pdcp_pP->next_pdcp_rx_sn           = 0;
-    pdcp_pP->tx_hfn                    = 0;
-    pdcp_pP->rx_hfn                    = 0;
-    pdcp_pP->last_submitted_pdcp_rx_sn = 4095;
-    pdcp_pP->first_missing_pdu         = -1;
 
+    pdcp_pP->rlc_mode                         = rlc_modeP;
+    pdcp_pP->next_pdcp_tx_sn                  = 0;
+    pdcp_pP->next_pdcp_rx_sn                  = 0;
+    pdcp_pP->next_pdcp_rx_sn_before_integrity = 0;
+    pdcp_pP->tx_hfn                           = 0;
+    pdcp_pP->rx_hfn                           = 0;
+    pdcp_pP->last_submitted_pdcp_rx_sn        = 4095;
+    pdcp_pP->first_missing_pdu                = -1;
+    pdcp_pP->rx_hfn_offset                    = 0;
+    
     if (enb_flagP == ENB_FLAG_NO) {
         LOG_I(PDCP, "[UE %d] Config request : Action ADD for eNB %d: Frame %d LCID %d (rb id %d) "
             "configured with SN size %d bits and RLC %s\n",
             ue_mod_idP, enb_mod_idP, frameP, lc_idP, rb_idP, pdcp_pP->seq_num_size,
-            (rlc_modeP == 1) ? "AM" : (rlc_modeP == 2) ? "TM" : "UM");
+            (rlc_modeP == RLC_MODE_AM ) ? "AM" : (rlc_modeP == RLC_MODE_TM) ? "TM" : "UM");
     } else {
         LOG_I(PDCP, "[eNB %d] Config request : Action ADD for UE %d: Frame %d LCID %d (rb id %d) "
             "configured with SN size %d bits and RLC %s\n",
             enb_mod_idP, ue_mod_idP, frameP, lc_idP, rb_idP, pdcp_pP->seq_num_size,
-            (rlc_modeP == 1) ? "AM" : (rlc_modeP == 2) ? "TM" : "UM");
+            (rlc_modeP == RLC_MODE_AM) ? "AM" : (rlc_modeP == RLC_MODE_TM) ? "TM" : "UM");
     }
 
     /* Setup security */
@@ -1208,12 +1228,12 @@ boolean_t pdcp_config_req_asn1 (pdcp_t   *pdcp_pP,
         LOG_I(PDCP,"[UE %d] Config request : Action MODIFY for eNB %d: Frame %d LCID %d "
             "RB id %d configured with SN size %d and RLC %s \n",
             ue_mod_idP, enb_mod_idP, frameP, lc_idP, rb_idP, rb_snP,
-            (rlc_modeP == 1) ? "AM" : (rlc_modeP == 2) ? "TM" : "UM");
+            (rlc_modeP == RLC_MODE_AM) ? "AM" : (rlc_modeP == RLC_MODE_TM) ? "TM" : "UM");
     } else {
         LOG_I(PDCP,"[eNB %d] Config request : Action MODIFY for UE %d: Frame %d LCID %d "
             "RB id %d configured with SN size %d and RLC %s \n",
             enb_mod_idP, ue_mod_idP, frameP, lc_idP, rb_idP, rb_snP,
-            (rlc_modeP == 1) ? "AM" : (rlc_modeP == 2) ? "TM" : "UM");
+            (rlc_modeP == RLC_MODE_AM) ? "AM" : (rlc_modeP == RLC_MODE_TM) ? "TM" : "UM");
     }
     break;
   case CONFIG_ACTION_REMOVE:
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index cf948f0698113360769ab227160831400d47e46f..8d170a0c2815690a37b53f476c1c8d17f054a6dc 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -151,11 +151,14 @@ typedef struct pdcp_t {
    */
   pdcp_sn_t next_pdcp_tx_sn;
   pdcp_sn_t next_pdcp_rx_sn;
+  pdcp_sn_t next_pdcp_rx_sn_before_integrity;
   /*
    * TX and RX Hyper Frame Numbers
    */
   pdcp_hfn_t tx_hfn;
   pdcp_hfn_t rx_hfn;
+  pdcp_hfn_offset_t rx_hfn_offset; // related to sn mismatch
+  
   /*
    * SN of the last PDCP SDU delivered to upper layers
    */
@@ -172,6 +175,11 @@ typedef struct pdcp_t {
    * which is not also a valid sequence number
    */
   short int first_missing_pdu;
+  /*
+   * decipher using a different rx_hfn
+   */
+  
+  
 } pdcp_t;
 
 #if defined(Rel10)
@@ -439,6 +447,21 @@ typedef struct pdcp_missing_pdu_info_t {
 #define PDCP_MAX_SN_7BIT  127  // 2^7-1
 #define PDCP_MAX_SN_12BIT 4095 // 2^12-1
 
+/*
+ * Reordering_Window: half of the PDCP SN space
+ */ 
+#define REORDERING_WINDOW_SN_5BIT 16
+#define REORDERING_WINDOW_SN_7BIT 64
+#define REORDERING_WINDOW_SN_12BIT 2048
+
+/* 
+ * SN size 
+ */
+#define PDCP_SN_5BIT  5
+#define PDCP_SN_7BIT  7
+#define PDCP_SN_12BIT 12
+ 
+
 protected_pdcp(signed int             pdcp_2_nas_irq;)
 public_pdcp(pdcp_stats_t              UE_pdcp_stats[NUMBER_OF_UE_MAX];)
 public_pdcp(pdcp_stats_t              eNB_pdcp_stats[NUMBER_OF_eNB_MAX];)
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c
index 995d69ae0f3ba220288fd09ac31d36e57768fb81..eed6657c235e84800b9043900cf461f6d9038f62 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c
@@ -113,8 +113,8 @@ int pdcp_netlink_init(void) {
   pdcp_netlink_queue_ue       = calloc(nb_inst_ue, sizeof(struct lfds611_queue_state*));
   pdcp_netlink_nb_element_ue  = malloc(nb_inst_ue * sizeof(uint32_t));
 
-  LOG_I(PDCP, "Creating %d queues for eNB Netlink -> PDCP communication\n", nb_inst_enb);
-  LOG_I(PDCP, "Creating %d queues for UE Netlink -> PDCP communication\n", nb_inst_ue);
+  LOG_I(PDCP, "[NETLINK] Creating %d queues for eNB Netlink -> PDCP communication\n", nb_inst_enb);
+  LOG_I(PDCP, "[NETLINK] Creating %d queues for UE Netlink -> PDCP communication\n", nb_inst_ue);
 
   for (i = 0; i < nb_inst_enb; i++) {
       pdcp_netlink_nb_element_enb[i] = 0;
@@ -132,7 +132,7 @@ int pdcp_netlink_init(void) {
   }
 
   if (pthread_attr_init(&attr) != 0) {
-      LOG_E(PDCP, "Failed to initialize pthread attribute for Netlink -> PDCP communication (%d:%s)\n",
+      LOG_E(PDCP, "[NETLINK]Failed to initialize pthread attribute for Netlink -> PDCP communication (%d:%s)\n",
           errno, strerror(errno));
       exit(EXIT_FAILURE);
   }
@@ -147,7 +147,7 @@ int pdcp_netlink_init(void) {
    * should be avoided if we want a reliable link.
    */
   if (pthread_create(&pdcp_netlink_thread, &attr, pdcp_netlink_thread_fct, NULL) != 0) {
-      LOG_E(PDCP, "Failed to create new thread for Netlink/PDCP communcation (%d:%s)\n",
+      LOG_E(PDCP, "[NETLINK]Failed to create new thread for Netlink/PDCP communcation (%d:%s)\n",
           errno, strerror(errno));
       exit(EXIT_FAILURE);
   }
@@ -166,12 +166,12 @@ int pdcp_netlink_dequeue_element(
   if (eNB_flagP) {
       ret = lfds611_queue_dequeue(pdcp_netlink_queue_enb[enb_mod_idP], (void **)data_ppP);
       if (ret != 0) {
-          LOG_D(PDCP, "De-queueing packet for eNB instance %d\n", enb_mod_idP);
+          LOG_D(PDCP,"[NETLINK]De-queueing packet for eNB instance %d\n", enb_mod_idP);
       }
   } else {
       ret = lfds611_queue_dequeue(pdcp_netlink_queue_ue[ue_mod_idP], (void **)data_ppP);
       if (ret != 0) {
-          LOG_D(PDCP, "De-queueing packet for UE instance %d\n", ue_mod_idP);
+          LOG_D(PDCP, "[NETLINK]De-queueing packet for UE instance %d\n", ue_mod_idP);
       }
   }
 
@@ -187,6 +187,7 @@ void *pdcp_netlink_thread_fct(void *arg) {
 
   pdcp_thread_read_state = 0;
   memset(nl_rx_buf, 0, NL_MAX_PAYLOAD);
+  LOG_I(PDCP, "[NETLINK_THREAD] binding to fd  %d\n",nas_sock_fd);
 
   while (1) {
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h
index 71a694cb6954eec6f2ad61d93bc987d1329bce52..0040380200b81c0986dcc14db96ceac1aac5871b 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h
@@ -153,11 +153,15 @@ void pdcp_config_set_security(pdcp_t *pdcp_pP, module_id_t enb_mod_idP, module_i
                               uint16_t lc_idP, uint8_t security_modeP, uint8_t *kRRCenc_pP, uint8_t *kRRCint_pP, uint8_t *kUPenc_pP);
 
 #if defined(ENABLE_SECURITY)
-int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
+int pdcp_apply_security(pdcp_t *pdcp_entity, 
+			srb_flag_t srb_flagP,
+			rb_id_t rb_id,
                         uint8_t pdcp_header_len, uint16_t current_sn, uint8_t *pdcp_pdu_buffer,
                         uint16_t sdu_buffer_size);
 
-int pdcp_validate_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
+int pdcp_validate_security(pdcp_t *pdcp_entity, 
+			   srb_flag_t srb_flagP,
+			   rb_id_t rb_id,
                            uint8_t pdcp_header_len, uint16_t current_sn, uint8_t *pdcp_pdu_buffer,
                            uint16_t sdu_buffer_size);
 #endif /* defined(ENABLE_SECURITY) */
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
index efac38b5565d12b3c6236ff894036094f4ebcc9d..36fd421e664ff1432343d4ac6b4147546150ded4 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
@@ -27,9 +27,10 @@
 
 *******************************************************************************/
 /*! \file pdcp_security.c
- * \brief PDCP Security Methods
- * \author ROUX Sebastien
- * \date 2013
+ * \brief PDCP Security Methods 
+ * \author ROUX Sebastie and Navid Nikaein
+ * \email openair_tech@eurecom.fr, navid.nikaein@eurecom.fr
+ * \date 2014
  */
 #include <stdint.h>
 
@@ -48,47 +49,62 @@
 #if defined(ENABLE_SECURITY)
 
 static
-uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn);
+uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn);
 static
-uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn);
+uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn);
 
 static
-uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn)
+uint32_t pdcp_get_next_count_tx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn)
 {
-    uint32_t count;
-    /* For TX COUNT = TX_HFN << length of SN | pdcp SN */
-    if (pdcp_header_len == PDCP_CONTROL_PLANE_DATA_PDU_SN_SIZE) {
-        /* 5 bits length SN */
-        count = (pdcp_entity->tx_hfn << 5)  | (pdcp_sn & 0x001F);
-    } else {
-        /* 12 bits length SN */
-        count = (pdcp_entity->tx_hfn << 12) | (pdcp_sn & 0x0FFF);
+  uint32_t count;
+  /* For TX COUNT = TX_HFN << length of SN | pdcp SN */
+  if (srb_flagP) {
+    /* 5 bits length SN */
+    count = ((pdcp_entity->tx_hfn << 5)  | (pdcp_sn & 0x001F));
+  } else {
+    if (pdcp_entity->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
+      count = ((pdcp_entity->tx_hfn << 7) | (pdcp_sn & 0x07F));
+    } else { /*Default is the 12 bits length SN */
+      count = ((pdcp_entity->tx_hfn << 12) | (pdcp_sn & 0x0FFF));
     }
-//     LOG_D(PDCP, "[OSA] TX COUNT = 0x%08x\n", count);
-
-    return count;
+  }
+  LOG_D(PDCP, "[OSA] TX COUNT = 0x%08x\n", count);
+  
+  return count;
 }
 
 static
-uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, uint8_t pdcp_header_len, uint16_t pdcp_sn)
+uint32_t pdcp_get_next_count_rx(pdcp_t *pdcp_entity, srb_flag_t srb_flagP, uint16_t pdcp_sn) 
 {
-    uint32_t count;
-    /* For RX COUNT = RX_HFN << length of SN | pdcp SN of received PDU */
-    if (pdcp_header_len == PDCP_CONTROL_PLANE_DATA_PDU_SN_SIZE) {
-        /* 5 bits length SN */
-        count = (pdcp_entity->rx_hfn << 5)  | (pdcp_sn & 0x001F);
-    } else {
-        /* 12 bits length SN */
-        count = (pdcp_entity->rx_hfn << 12) | (pdcp_sn & 0x0FFF);
+  uint32_t count;
+  /* For RX COUNT = RX_HFN << length of SN | pdcp SN of received PDU */
+  if (srb_flagP) {
+    /* 5 bits length SN */
+    count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 5)  | (pdcp_sn & 0x001F));
+  } else {
+    if (pdcp_entity->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) {
+      /* 7 bits length SN */
+      count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 7) | (pdcp_sn & 0x007F));
+    } else { // default 
+      /* 12 bits length SN */
+      count = (((pdcp_entity->rx_hfn + pdcp_entity->rx_hfn_offset) << 12) | (pdcp_sn & 0x0FFF));
     }
-//     LOG_D(PDCP, "[OSA] RX COUNT = 0x%08x\n", count);
-
-    return count;
+  
+  }
+  // reset the hfn offset
+  pdcp_entity->rx_hfn_offset =0;
+  LOG_D(PDCP, "[OSA] RX COUNT = 0x%08x\n", count);
+  
+  return count;
 }
 
-int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
-                        uint8_t pdcp_header_len, uint16_t current_sn, uint8_t *pdcp_pdu_buffer,
-                        uint16_t sdu_buffer_size)
+int pdcp_apply_security(pdcp_t        *pdcp_entity, 
+			srb_flag_t     srb_flagP,
+			rb_id_t        rb_id,
+			uint8_t        pdcp_header_len, 
+			uint16_t       current_sn, 
+			uint8_t       *pdcp_pdu_buffer,
+                        uint16_t      sdu_buffer_size)
 {
     uint8_t *buffer_encrypted = NULL;
     stream_cipher_t encrypt_params;
@@ -99,12 +115,12 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
 
     vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_IN);
 
-    encrypt_params.direction  = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK;
+    encrypt_params.direction  = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK; 
     encrypt_params.bearer     = rb_id - 1;
-    encrypt_params.count      = pdcp_get_next_count_tx(pdcp_entity, pdcp_header_len, current_sn);
+    encrypt_params.count      = pdcp_get_next_count_tx(pdcp_entity, srb_flagP, current_sn);
     encrypt_params.key_length = 16;
 
-    if (rb_id < DTCH) {
+    if (srb_flagP) {
         /* SRBs */
         uint8_t *mac_i;
 
@@ -119,7 +135,8 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
 
         /* Both header and data parts are integrity protected for
          * control-plane PDUs */
-        stream_compute_integrity(pdcp_entity->integrityProtAlgorithm, &encrypt_params,
+        stream_compute_integrity(pdcp_entity->integrityProtAlgorithm, 
+				 &encrypt_params,
                                  mac_i);
 
         encrypt_params.key = pdcp_entity->kRRCenc;  // + 128  // bit key 
@@ -136,7 +153,8 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
     buffer_encrypted = &pdcp_pdu_buffer[pdcp_header_len];
 
     /* Apply ciphering if any requested */
-    stream_encrypt(pdcp_entity->cipheringAlgorithm, &encrypt_params,
+    stream_encrypt(pdcp_entity->cipheringAlgorithm, 
+		   &encrypt_params,
                    &buffer_encrypted);
 
     vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_OUT);
@@ -144,9 +162,13 @@ int pdcp_apply_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
     return 0;
 }
 
-int pdcp_validate_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
-                           uint8_t pdcp_header_len, uint16_t current_sn, uint8_t *pdcp_pdu_buffer,
-                           uint16_t sdu_buffer_size)
+int pdcp_validate_security(pdcp_t         *pdcp_entity, 
+			   srb_flag_t     srb_flagP,
+			   rb_id_t        rb_id,
+                           uint8_t        pdcp_header_len, 
+			   uint16_t       current_sn, 
+			   uint8_t       *pdcp_pdu_buffer,
+                           uint16_t       sdu_buffer_size)
 {
     uint8_t *buffer_decrypted = NULL;
     stream_cipher_t decrypt_params;
@@ -162,12 +184,12 @@ int pdcp_validate_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
 
     decrypt_params.direction  = (pdcp_entity->is_ue == 1) ? SECU_DIRECTION_DOWNLINK : SECU_DIRECTION_UPLINK ;
     decrypt_params.bearer     = rb_id - 1;
-    decrypt_params.count      = pdcp_get_next_count_rx(pdcp_entity, pdcp_header_len, current_sn);
+    decrypt_params.count      = pdcp_get_next_count_rx(pdcp_entity, srb_flagP, current_sn);
     decrypt_params.message    = &pdcp_pdu_buffer[pdcp_header_len];
     decrypt_params.blength    = (sdu_buffer_size - pdcp_header_len) << 3;
     decrypt_params.key_length = 16;
 
-    if (rb_id < DTCH) {
+    if (srb_flagP) {
         LOG_D(PDCP, "[OSA][RB %d] %s Validating control-plane security\n",
               rb_id, (pdcp_entity->is_ue != 0) ? "eNB -> UE" : "UE -> eNB");
         decrypt_params.key = pdcp_entity->kRRCenc;// + 128;
@@ -178,25 +200,28 @@ int pdcp_validate_security(pdcp_t *pdcp_entity, rb_id_t rb_id,
     }
 
     /* Uncipher the block */
-    stream_decrypt(pdcp_entity->cipheringAlgorithm, &decrypt_params, &buffer_decrypted);
-
-    if (rb_id < DTCH) {
-        /* Now check the integrity of the complete PDU */
-        decrypt_params.message    = pdcp_pdu_buffer;
-        decrypt_params.blength    = sdu_buffer_size << 3;
-        decrypt_params.key        = pdcp_entity->kRRCint + 16;// 128;
-
-        if (stream_check_integrity(pdcp_entity->integrityProtAlgorithm,
-            &decrypt_params, &pdcp_pdu_buffer[sdu_buffer_size]) != 0)
-        {
-            LOG_E(PDCP, "[OSA] failed to validate MAC-I of incoming PDU\n");
-            vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
-            return -1;
-        }
+    stream_decrypt(pdcp_entity->cipheringAlgorithm, 
+		   &decrypt_params, 
+		   &buffer_decrypted);
+
+    if (srb_flagP) {
+      /* Now check the integrity of the complete PDU */
+      decrypt_params.message    = pdcp_pdu_buffer;
+      decrypt_params.blength    = sdu_buffer_size << 3;
+      decrypt_params.key        = pdcp_entity->kRRCint + 16;// 128;
+      
+      if (stream_check_integrity(pdcp_entity->integrityProtAlgorithm,
+				 &decrypt_params, 
+				 &pdcp_pdu_buffer[sdu_buffer_size]) != 0)
+	{
+	  LOG_E(PDCP, "[OSA] failed to validate MAC-I of incoming PDU\n");
+	  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
+	  return -1;
+	}
     }
-
+    
     vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
-
+    
     return 0;
 }
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c
index f95bab27b82b84dfd729ef86ae8b728055c10e31..341ab21fe2d014bb3a0af0add9e35bd7b4b576ba 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c
@@ -29,8 +29,9 @@
 
 /*! \file pdcp_sequence_manager.c
 * \brief PDCP Sequence Numbering Methods
-* \author Baris Demiray
-* \date 2011
+* \author Baris Demiray and Navid Nikaein
+* \email navid.nikaein@eurecom.fr
+* \date 2014
 */
 
 #include "pdcp_sequence_manager.h"
@@ -146,9 +147,11 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity)
  * @return 1 if SN is okay, 0 otherwise
  * XXX Reordering window should also be handled here
  */
-boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity)
-{
-  LOG_D(PDCP, "Incoming RX Seq # is %04d\n", seq_num);
+boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_flag_t srb_flagP)  {
+  
+  uint16_t  reordering_window = 0;
+  
+  LOG_D(PDCP, "Incoming RX Sequence number is %04d\n", seq_num);
 
   if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE || pdcp_is_seq_num_valid(seq_num, pdcp_entity->seq_num_size) == FALSE)
     return FALSE;
@@ -164,27 +167,117 @@ boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity)
   }
 
   /*
-   * XXX Since we do not implement reordering window yet we expect to receive
-   * exactly the next SN from lower layer. When reordering window is implemented
-   * the operator utilized here should be >= as stated in 5.1.2.1.2
+   * RX Procedures for SRB and DRBs as described in sec 5.1.2 of 36.323
    */
+ 
+  if (srb_flagP) { // SRB
+    
+    if (seq_num < pdcp_entity->next_pdcp_rx_sn) {
+      // decipher and verify the integrity of the PDU (if applicable) using COUNT based on RX_HFN + 1 and the received PDCP SN 
+      pdcp_entity->rx_hfn++;
+      pdcp_entity->rx_hfn_offset   = 0;
+    } else{ 
+      // decipher and verify the integrity of the PDU (if applicable) using COUNT based using COUNT based on RX_HFN and the received PDCP SN
+      pdcp_entity->rx_hfn_offset   = 0;
+    }
+
+    // Assume  that integrity verification is applicable and the integrity verification is passed successfully; 
+    // or assume that  integrity verification is not applicable:
+    
+    // same the old next_pdcp_rx_sn to revert otherwise
+    pdcp_entity->next_pdcp_rx_sn_before_integrity = pdcp_entity->next_pdcp_rx_sn;
+    if (seq_num != pdcp_entity->next_pdcp_rx_sn)
+      LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num); 
+    //set Next_PDCP_RX_SN to the received PDCP SN +1 ;
+    pdcp_entity->next_pdcp_rx_sn = seq_num;
+    pdcp_advance_rx_window(pdcp_entity);  // + 1, and check if it is larger than Maximum_PDCP_SN:
+    
+  } else { // DRB
+
+    if (pdcp_entity->seq_num_size == PDCP_SN_7BIT)
+      reordering_window = REORDERING_WINDOW_SN_7BIT;
+    else 
+      reordering_window = REORDERING_WINDOW_SN_12BIT;
+
+    switch (pdcp_entity->rlc_mode) {
+    case RLC_MODE_AM: 
+      if ((seq_num - pdcp_entity->last_submitted_pdcp_rx_sn > reordering_window)  || 
+	  ((0 <= pdcp_entity->last_submitted_pdcp_rx_sn - seq_num) &&  
+	   (pdcp_entity->last_submitted_pdcp_rx_sn - seq_num < reordering_window)  )) {
+	
+	if (seq_num  > pdcp_entity->next_pdcp_rx_sn) {
+	  /* 
+	   * decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN - 1 and the received PDCP SN;
+	   */
+	  pdcp_entity->rx_hfn_offset   =  -1;
+	} else  {
+	  /*
+	   *  decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN and the received PDCP SN;
+	   */
+	  pdcp_entity->rx_hfn_offset   = 0;
+	}
+	
+	// discard this PDCP SDU;
+	LOG_W(PDCP, "Out of the reordering window (Incoming SN:%d, Expected SN:%d): discard this PDCP SDU\n", 
+	      seq_num, pdcp_entity->next_pdcp_rx_sn);
+	
+	return FALSE;
+      } else if (pdcp_entity->next_pdcp_rx_sn - seq_num > reordering_window) {
+	pdcp_entity->rx_hfn++;
+	// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
+	pdcp_entity->rx_hfn_offset   = 0;
+      	pdcp_entity->next_pdcp_rx_sn++;
+      }
+      else if (seq_num - pdcp_entity->next_pdcp_rx_sn  >= reordering_window ){
+	//  use COUNT based on RX_HFN – 1 and the received PDCP SN for deciphering the PDCP PDU;
+	pdcp_entity->rx_hfn_offset   = -1;
+      }
+      else if (seq_num  >= pdcp_entity->next_pdcp_rx_sn ) {
+	// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
+	pdcp_entity->rx_hfn_offset = 0; 
+	//set Next_PDCP_RX_SN to the received PDCP SN +1 ;
+	pdcp_entity->next_pdcp_rx_sn = seq_num;
+	pdcp_advance_rx_window(pdcp_entity);  // + 1, anc check if it is larger than Maximum_PDCP_SN:
+	LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num);
+      } else if (seq_num < pdcp_entity->next_pdcp_rx_sn){
+	// use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU;
+	pdcp_entity->rx_hfn_offset = 0;
+      }
+      break;
+    case RLC_MODE_UM :
+      if (seq_num <  pdcp_entity->next_pdcp_rx_sn)
+	pdcp_entity->rx_hfn++;
+      // decipher the PDCP Data PDU using COUNT based on RX_HFN and the received PDCP SN as specified in the subclause 5.6;
+      //set Next_PDCP_RX_SN to the received PDCP SN +1 ;
+      pdcp_entity->next_pdcp_rx_sn = seq_num;
+      pdcp_advance_rx_window(pdcp_entity);  // + 1, and check if it is larger than Maximum_PDCP_SN:
+    
+      break;
+    case RLC_MODE_TM : 
+    default:
+      LOG_W(PDCP,"RLC mode %d not supported\n",pdcp_entity->rlc_mode);
+      return FALSE;
+    }
+  }
+
+  /*   
   if (seq_num == pdcp_entity->next_pdcp_rx_sn) {
     LOG_I(PDCP, "Next expected SN (%d) arrived, advancing RX window\n", seq_num);
 
     return pdcp_advance_rx_window(pdcp_entity);
   } else {
-    LOG_E(PDCP, "D'oh! Incoming SN is not the one we expected to receive! (Incoming:%d, Expected:%d)\n", \
+    LOG_E(PDCP, "Incoming SN is not the one we expected to receive! (Incoming:%d, Expected:%d)\n", \
         seq_num, pdcp_entity->next_pdcp_rx_sn);
+  
 
-    /*
-     * Update first missing PDU (used in PDCP Control PDU for 
-     * PDCP status report, see 6.2.6)
-     */
+    // Update first missing PDU (used in PDCP Control PDU for PDCP status report, see 6.2.6)
     if (pdcp_entity->first_missing_pdu != -1)
       pdcp_entity->first_missing_pdu = pdcp_entity->next_pdcp_rx_sn;
 
     return FALSE;
   }
+  */ 
+  return TRUE;
 }
 
 boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity)
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h
index 1ec86c6cda1cf7827fcbe745edb3590cda826a8d..0e6d4d9977cfdcdd4664c2a13a5555277da70164 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h
@@ -71,7 +71,7 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity);
  * Checks if incoming PDU has a sequence number in accordance with the RX window
  * @return TRUE if it is valid, FALSE otherwise
  */
-boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity);
+boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_flag_t srb_flagP);
 /**
 * Updates missing PDU bitmap with incoming sequence number
 * @return TRUE if successful, FALSE otherwise
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
index d7eccde91c4d1c6f80f3777443feaf7177043dff..953f64fbf77994c393622dc044b6a4dc70f6f55b 100755
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
@@ -591,8 +591,8 @@ void rlc_am_segment_10 (
 
         pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
         pdu_tb_req_p->tb_size         = data_pdu_size - pdu_remaining_size;
-
-        assert(pdu_tb_req_p->tb_size < 3000);
+#warning "why 3000: changed to RLC_SDU_MAX_SIZE "
+        assert(pdu_tb_req_p->tb_size < RLC_SDU_MAX_SIZE );
         rlc_am_pdu_polling(rlc_pP, frameP,pdu_p, pdu_mngt_p->payload_size);
 
         //list_add_tail_eurecom (pdu_mem_p, &rlc_pP->segmentation_pdu_list);
diff --git a/openair2/NAS/DRIVER/MESH/common.c b/openair2/NAS/DRIVER/MESH/common.c
index b50367874296e99c4b8a42afc04b4d24f8d2dc2e..a2121fc7cdd0b4f23ec68fa67c7e337799558e7c 100755
--- a/openair2/NAS/DRIVER/MESH/common.c
+++ b/openair2/NAS/DRIVER/MESH/common.c
@@ -432,7 +432,7 @@ void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct class
   
   if (bytes_wrote != NAS_PDCPH_SIZE)
     {
-      printk("NAS_COMMON_QOS_SEND: problem while writing PDCP's header (bytes wrote = %d to fifo %d)\n",bytes_wrote,NAS2PDCP_FIFO);
+      printk("NAS_COMMON_QOS_SEND: problem while writing PDCP's header (bytes wrote = %d )\n",bytes_wrote);
       printk("rb_id %d, Wrote %d, Header Size %lu\n", pdcph.rb_id , bytes_wrote, NAS_PDCPH_SIZE);
 #ifndef NAS_NETLINK
       rtf_reset(NAS2PDCP_FIFO);
diff --git a/openair2/NAS/DRIVER/MESH/netlink.c b/openair2/NAS/DRIVER/MESH/netlink.c
index 574f311549c472516278386901d810b6cb2174d3..e763d6fc38c99df05325c7414344ef5a4396563b 100644
--- a/openair2/NAS/DRIVER/MESH/netlink.c
+++ b/openair2/NAS/DRIVER/MESH/netlink.c
@@ -245,14 +245,17 @@ int nas_netlink_send(unsigned char *data,unsigned int len) {
 #else
   NETLINK_CB(nl_skb).pid = 0;
 #endif
-
-#ifdef NETLINK_DEBUG
-  printk("[NAS][NETLINK] In nas_netlink_send, nl_skb %p, nl_sk %x, nlh %p, nlh->nlmsg_len %d\n",nl_skb,nas_nl_sk,nlh,nlh->nlmsg_len);
+  
+ #ifdef NETLINK_DEBUG
+  printk("[NAS][NETLINK] In nas_netlink_send, nl_skb %p, nl_sk %x, nlh %p, nlh->nlmsg_len %d (NAS_NETLINK_ID %d)\n",
+	 nl_skb,nas_nl_sk,nlh,nlh->nlmsg_len,
+	 NAS_NETLINK_ID);
 #endif //DEBUG_NETLINK
 
   if (nas_nl_sk) {
 
     //  nasmesh_lock();
+    
     status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
     // mutex_unlock(&nasmesh_mutex);
 
@@ -271,4 +274,11 @@ int nas_netlink_send(unsigned char *data,unsigned int len) {
     printk("[NAS][SEND] socket is NULL\n");
     return(0);
   }
+
+  /*
+    nlmsg_failure:	// Used by NLMSG_PUT
+  if (nl_skb)
+    kfree_skb(nl_skb);
+*/
+
 }
diff --git a/targets/SIMU/USER/Makefile b/targets/SIMU/USER/Makefile
index 3734265b109d8315738504e0c082c0ba0f3b2a3a..57ad85d02d33742015a1366be159014aa9851f62 100644
--- a/targets/SIMU/USER/Makefile
+++ b/targets/SIMU/USER/Makefile
@@ -364,14 +364,15 @@ oai_nw_drv:
 oai_nw_drv_clean:
 	(cd $(OPENAIR2_DIR)/NAS/DRIVER/LITE && $(MAKE) clean)
 nasmesh_fix:
-	(cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && $(MAKE))
-	(cd $(OPENAIR2_DIR) && $(MAKE) nasmesh_netlink_address_fix.ko)
-	(cp $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko . )
-nasmesh_fix_install:
-	(cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && $(MAKE))
-	(cd $(OPENAIR2_DIR) && $(MAKE) nasmesh_netlink_address_fix.ko)
+	(cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && $(MAKE) clean && $(MAKE))
+	(cd $(OPENAIR2_DIR) && $(MAKE) clean && $(MAKE) nasmesh_netlink_address_fix.ko)
+nasmesh_fix_uninstall:	
+	(sudo rmmod nasmesh.ko)
+nasmesh_fix_install:	
+	(sudo insmod $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko)	
+nasmesh_fix_reinstall:
+	(sudo rmmod nasmesh.ko)	
 	(sudo insmod $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko)
-	(cp $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko . )
 nasmesh_nl:
 	(cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && $(MAKE))
 	(cd $(OPENAIR2_DIR) && $(MAKE) nasmesh_netlink.ko)
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index b6e5f585494fabe8639dbc6ce5713d53cb468517..623c9b2f4879824bb26182110cb4ddfda6f3c4ba 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -1097,9 +1097,9 @@ void update_otg_eNB(module_id_t enb_module_idP, unsigned int ctime) {
                       (otg_pkt->otg_pkt).is_ue = 0;
                       (otg_pkt->otg_pkt).mode = PDCP_TRANSMISSION_MODE_DATA;
                       //Adding the packet to the OTG-PDCP buffer
-#warning "Strange code"
+#warning "Strange code: To be verifed"
                       pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[enb_module_idP]));
-                      LOG_I(EMU, "[eNB %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d for app id %d \n",
+                      LOG_I(EMU,"[eNB %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d for app id %d \n",
                           (otg_pkt->otg_pkt).module_id, otg_pkt->otg_pkt.sdu_buffer_size, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id, app_id);
                   } else {
                       free(otg_pkt);