diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
index e550eeaf990b73f285017d273f44c59746da0ff9..9b1bb1a4fbddfb0fb5d9c222cb06ea3609fc31f3 100755
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
@@ -571,6 +571,7 @@ rlc_am_mac_data_indication (void *rlcP, u32_t frame, u8 eNB_flag, struct mac_dat
     mem_block_t               *tb;
     int                       num_li;
     int                       num_nack;
+    s16_t                     tb_size;
 
     if (data_indP.data.nb_elements > 0) {
         LOG_D(RLC, "[RLC_AM][MOD %d][RB %d][FRAME %05d] MAC_DATA_IND %d TBs\n", l_rlc->module_id, l_rlc->rb_id, frame, data_indP.data.nb_elements);
@@ -607,8 +608,9 @@ rlc_am_mac_data_indication (void *rlcP, u32_t frame, u8 eNB_flag, struct mac_dat
                                                                        "/%d Bytes ",
                                                                        ((struct mac_tb_ind *) (tb->data))->size);
             } else {
+                tb_size = (s16_t) ((struct mac_tb_ind *) (tb->data))->size;
                 rlc_am_get_control_pdu_infos((rlc_am_pdu_sn_10_t*) ((struct mac_tb_ind *) (tb->data))->data_ptr,
-                                             (s16_t) ((struct mac_tb_ind *) (tb->data))->size,
+                                             &tb_size,
                                              &control_pdu_info);
 
                 rlc[l_rlc->module_id].m_mscgen_trace_length += sprintf(&rlc[l_rlc->module_id].m_mscgen_trace[rlc[l_rlc->module_id].m_mscgen_trace_length],
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
index b376f7e7b8adfdbfc2bc3d59a304f9ea18ff1e98..c8246933907b47c234ab64030c0186da01c5917a 100755
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
@@ -31,6 +31,7 @@ Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis
 //#include "rtos_header.h"
 #include "platform_types.h"
 //-----------------------------------------------------------------------------
+#include "assertions.h"
 #include "rlc.h"
 #include "rlc_am.h"
 #include "list.h"
@@ -204,7 +205,7 @@ rlc_am_receive_routing (rlc_am_entity_t *rlcP, u32_t frame, u8_t eNB_flag, struc
 {
     mem_block_t        *tb;
     u8_t               *first_byte;
-    u16_t               tb_size_in_bytes;
+    s16_t               tb_size_in_bytes;
 
     while ((tb = list_remove_head (&data_indP.data))) {
         first_byte = ((struct mac_tb_ind *) (tb->data))->data_ptr;
@@ -218,7 +219,25 @@ rlc_am_receive_routing (rlc_am_entity_t *rlcP, u32_t frame, u8_t eNB_flag, struc
             } else {
                 rlcP->stat_rx_control_bytes += tb_size_in_bytes;
                 rlcP->stat_rx_control_pdu += 1;
-                rlc_am_receive_process_control_pdu (rlcP, frame, tb, first_byte, tb_size_in_bytes);
+                rlc_am_receive_process_control_pdu (rlcP, frame, tb, first_byte, &tb_size_in_bytes);
+                // if data pdu concatenated with control PDU (seen with real hardware LTE dongle integration)
+                if (tb_size_in_bytes > 0) {
+#if defined(RLC_ENABLE_PDU_CONCATENATION)
+                    if ((*first_byte & 0x80) == 0x80) {
+                        rlcP->stat_rx_data_bytes += tb_size_in_bytes;
+                        rlcP->stat_rx_data_pdu   += 1;
+                        rlc_am_receive_process_data_pdu (rlcP, frame, eNB_flag, tb, first_byte, tb_size_in_bytes);
+                    } else {
+                        AssertFatal( tb_size_in_bytes == 0,
+                                            "Not a data PDU concatened to control PDU %ld bytes left",
+                                            tb_size_in_bytes);
+                    }
+#else
+                    AssertFatal( tb_size_in_bytes == 0,
+                                        "Remaining %d bytes following a control PDU",
+                                        tb_size_in_bytes);
+#endif
+                }
             }
             LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d][RX ROUTING] VR(R)=%03d VR(MR)=%03d\n", frame, rlcP->module_id, rlcP->rb_id, rlcP->vr_r, rlcP->vr_mr);
         }
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
index 038e6b717c0360dbc62f6b57ccdf8bb796c487e4..cce220b6fe19b6881063c6179811cffee7d97e06 100755
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
@@ -112,7 +112,7 @@ void rlc_am_write16_bit_field(u8_t** dataP, unsigned int* bit_posP, signed int b
     }
 }
 //-----------------------------------------------------------------------------
-signed int rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_t* headerP, s16_t total_sizeP, rlc_am_control_pdu_info_t* pdu_infoP)
+signed int rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_t* headerP, s16_t *total_size_pP, rlc_am_control_pdu_info_t* pdu_infoP)
 //-----------------------------------------------------------------------------
 {
     memset(pdu_infoP, 0, sizeof (rlc_am_control_pdu_info_t));
@@ -125,6 +125,7 @@ signed int rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_t* headerP, s16_t total
         if (pdu_infoP->cpt != 0x00) return -3;
         pdu_infoP->ack_sn = ((headerP->b2 >> 2) & 0x3F) | (((u16_t)(headerP->b1 & 0x0F)) << 6);
         pdu_infoP->e1     = (headerP->b2 >> 1) & 0x01;
+        *total_size_pP -= 1;
 
         if (pdu_infoP->e1) {
             unsigned int nack_to_read  = 1;
@@ -149,22 +150,18 @@ signed int rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_t* headerP, s16_t total
 
                 if (!pdu_infoP->nack_list[pdu_infoP->num_nack - 1].e1) {
                     nack_to_read = 0;
+                    *total_size_pP = *total_size_pP - (s16_t)((uint64_t)byte_pos + (uint64_t)((bit_pos + 7)/8) - (uint64_t)headerP);
                     return 0;
                 }
 
                 if (pdu_infoP->num_nack == RLC_AM_MAX_NACK_IN_STATUS_PDU) {
+                    *total_size_pP = *total_size_pP - (s16_t)((uint64_t)byte_pos + (uint64_t)((bit_pos + 7)/8) - (uint64_t)headerP);
                     return -2;
                 }
             }
-#ifdef RLC_TEST_AGREGATED_DATA_PDU_WITH_CONTROL_PDU
-            AssertFatal( (uint64_t)((uint64_t)byte_pos + (bit_pos +7)/8 - (uint64_t)headerP) == total_sizeP,
-                    "Remaining bytes in transport block: %l",
-                    total_sizeP - (int64_t)((uint64_t)byte_pos + (bit_pos +7)/8 - (uint64_t)headerP ));
-#endif
+            *total_size_pP = *total_size_pP - (s16_t)((uint64_t)byte_pos + (uint64_t)((bit_pos + 7)/8) - (uint64_t)headerP);
         } else {
-#ifdef RLC_TEST_AGREGATED_DATA_PDU_WITH_CONTROL_PDU
-            AssertFatal( total_sizeP == 2, "Remaining bytes in transport block: %l", total_sizeP - 2);
-#endif
+            *total_size_pP = *total_size_pP - 2;
         }
         return 0;
     } else {
@@ -195,13 +192,13 @@ void rlc_am_display_control_pdu_infos(rlc_am_control_pdu_info_t* pdu_infoP)
     }
 }
 //-----------------------------------------------------------------------------
-void rlc_am_receive_process_control_pdu(rlc_am_entity_t* rlcP, u32_t frame, mem_block_t*  tbP, u8_t* first_byteP, u16_t tb_size_in_bytesP)
+void rlc_am_receive_process_control_pdu(rlc_am_entity_t* rlcP, u32_t frame, mem_block_t*  tbP, u8_t* first_byteP, s16_t *tb_size_in_bytes_pP)
 //-----------------------------------------------------------------------------
 {
   //rlc_am_control_pdu_info_t* pdu_info  = ((rlc_am_control_pdu_info_t*)(tbP->data));
   rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10 = (rlc_am_pdu_sn_10_t*)first_byteP;
 
-  if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10, tb_size_in_bytesP, &g_rlc_am_control_pdu_info) >= 0) {
+  if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10, tb_size_in_bytes_pP, &g_rlc_am_control_pdu_info) >= 0) {
 
     rlc_am_tx_buffer_display(rlcP, frame, " TX BUFFER BEFORE PROCESS OF STATUS PDU");
     LOG_D(RLC, "[FRAME %05d][RLC_AM][MOD %02d][RB %02d] RX CONTROL PDU VT(A) %04d VT(S) %04d POLL_SN %04d ACK_SN %04d\n",
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h
index 56e72040e67732df1fe83005a81efb5e2db0c8b4..ad8d75c2511735f3a98f6c92fb1a86eabc48bcbd 100755
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.h
@@ -95,10 +95,10 @@ protected_rlc_am_status_report(void        rlc_am_write16_bit_field(u8_t** dataP
 /*! \fn signed int rlc_am_get_control_pdu_infos      (rlc_am_pdu_sn_10_t* headerP, s16_t total_sizeP, rlc_am_control_pdu_info_t* pdu_infoP)
 * \brief      Retrieve control PDU informations from a serialized control PDU.
 * \param[in]  headerP           Pointer on the header of the RLC AM PDU.
-* \param[in]  total_sizeP       PDU size in bytes.
+* \param[in]  total_size_pP     Pointer on PDU size in bytes.
 * \param[in,out]  pdu_infoP     Struct containing interpreted PDU control informations.
 */
-protected_rlc_am_status_report( signed int rlc_am_get_control_pdu_infos (rlc_am_pdu_sn_10_t* headerP, s16_t total_sizeP, rlc_am_control_pdu_info_t* pdu_infoP);)
+protected_rlc_am_status_report( signed int rlc_am_get_control_pdu_infos (rlc_am_pdu_sn_10_t* headerP, s16_t *total_size_pP, rlc_am_control_pdu_info_t* pdu_infoP);)
 
 /*! \fn void rlc_am_display_control_pdu_infos(rlc_am_control_pdu_info_t* pdu_infoP)
 * \brief      Dump on LOG output the informations contained in the pdu_infoP structure.
@@ -112,9 +112,9 @@ protected_rlc_am_status_report( void rlc_am_display_control_pdu_infos(rlc_am_con
 * \param[in]  frame             Frame index.
 * \param[in]  tbP               Control PDU embedded in a mem_block_t structure.
 * \param[in]  first_byte        Pointer on first byte of control PDU.
-* \param[in]  tb_size_in_bytes  Size of serialized control PDU in bytes.
+* \param[in]  tb_size_in_bytes  Pointer on size of serialized control PDU in bytes.
 */
-protected_rlc_am_status_report( void       rlc_am_receive_process_control_pdu(rlc_am_entity_t* rlcP, u32_t frame, mem_block_t*  tbP, u8_t* first_byte, u16_t tb_size_in_bytes);)
+protected_rlc_am_status_report( void       rlc_am_receive_process_control_pdu(rlc_am_entity_t* rlcP, u32_t frame, mem_block_t*  tbP, u8_t* first_byte, s16_t *tb_size_in_bytes);)
 
 /*! \fn int  rlc_am_write_status_pdu(u32_t frame,rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10P, rlc_am_control_pdu_info_t* pdu_infoP)
 * \brief      Remove all marked holes for PDU with sequence number "snP".