Commit a0325027 authored by Cedric Roux's avatar Cedric Roux

Merge remote-tracking branch 'origin/bugfix-189-rlc-am-fixes' into develop_integration_w13

parents 2437d0fb 49006696
...@@ -388,9 +388,9 @@ typedef struct { ...@@ -388,9 +388,9 @@ typedef struct {
struct PMCH_InfoList_r9 *pmch_InfoList struct PMCH_InfoList_r9 *pmch_InfoList
#endif #endif
); );
unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, char*); unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, const unsigned int,char*);
void (*mac_rlc_data_ind)(module_id_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* ); void (*mac_rlc_data_ind)(module_id_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* );
mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP, mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, sub_frame_t subframeP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP,
logical_chan_id_t channel_idP, tb_size_t tb_sizeP); logical_chan_id_t channel_idP, tb_size_t tb_sizeP);
signed int (*rrc_rlc_data_req)(module_id_t, rb_id_t, mui_t, confirm_t, sdu_size_t, char *); signed int (*rrc_rlc_data_req)(module_id_t, rb_id_t, mui_t, confirm_t, sdu_size_t, char *);
void (*rrc_rlc_register_rrc) (void (*rrc_data_indP)(module_id_t , rb_id_t , sdu_size_t , char* ), void (*rrc_rlc_register_rrc) (void (*rrc_data_indP)(module_id_t , rb_id_t , sdu_size_t , char* ),
......
...@@ -562,14 +562,16 @@ int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { ...@@ -562,14 +562,16 @@ int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) {
int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id);
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id);
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,subframe,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0);
return rlc_status.bytes_in_buffer; return rlc_status.bytes_in_buffer;
} }
int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id);
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0); uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id);
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0);
return rlc_status.head_sdu_creation_time; return rlc_status.head_sdu_creation_time;
} }
......
This diff is collapsed.
...@@ -504,7 +504,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -504,7 +504,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
module_idP,CC_id,frameP,MTCH,TBS, module_idP,CC_id,frameP,MTCH,TBS,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
rlc_status = mac_rlc_status_ind(module_idP,0,frameP,module_idP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH, rlc_status = mac_rlc_status_ind(module_idP,0,frameP,subframeP,module_idP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH,
TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch);
LOG_D(MAC,"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", LOG_D(MAC,"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n",
MTCH,frameP,subframeP, rlc_status.bytes_in_buffer); MTCH,frameP,subframeP, rlc_status.bytes_in_buffer);
...@@ -521,6 +521,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ...@@ -521,6 +521,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_YES, MBMS_FLAG_YES,
MTCH, MTCH,
0, //not used
(char*)&mch_buffer[sdu_length_total]); (char*)&mch_buffer[sdu_length_total]);
//sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]); //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]);
LOG_I(MAC,"[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n",module_idP,CC_id,sdu_lengths[num_sdus],MTCH); LOG_I(MAC,"[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n",module_idP,CC_id,sdu_lengths[num_sdus],MTCH);
......
...@@ -174,6 +174,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -174,6 +174,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
rnti, rnti,
mod_id, mod_id,
frame, frame,
subframe,
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
lcid, lcid,
...@@ -193,6 +194,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -193,6 +194,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
rnti, rnti,
mod_id, mod_id,
frame, frame,
subframe,
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
lcid, lcid,
...@@ -209,6 +211,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ...@@ -209,6 +211,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
lcid, lcid,
rlc_size, //not used
(char *)&dlsch_buffer[sdu_length_total]); (char *)&dlsch_buffer[sdu_length_total]);
LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[j]); LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[j]);
......
...@@ -160,7 +160,7 @@ void _store_dlsch_buffer (module_id_t Mod_id, ...@@ -160,7 +160,7 @@ void _store_dlsch_buffer (module_id_t Mod_id,
for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels
rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,subframeP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
...@@ -1241,6 +1241,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id, ...@@ -1241,6 +1241,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
rnti, rnti,
mod_id, mod_id,
frame, frame,
subframe,
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
j, j,
......
...@@ -109,7 +109,7 @@ void store_dlsch_buffer (module_id_t Mod_id, ...@@ -109,7 +109,7 @@ void store_dlsch_buffer (module_id_t Mod_id,
for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels
rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,subframeP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
......
...@@ -394,7 +394,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -394,7 +394,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
} else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] > 0) { } else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] > 0) {
// This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example) // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO,
DCCH, DCCH,
6); 6);
...@@ -409,6 +409,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, ...@@ -409,6 +409,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti,
eNB_indexP, frameP,ENB_FLAG_NO, MBMS_FLAG_NO, eNB_indexP, frameP,ENB_FLAG_NO, MBMS_FLAG_NO,
DCCH, DCCH,
6, //not used
(char *)&ulsch_buff[0]); (char *)&ulsch_buff[0]);
LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]); LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
......
This diff is collapsed.
This diff is collapsed.
...@@ -267,23 +267,32 @@ private_rlc_am( void rlc_am_get_pdus (const protocol_ctxt_t* const ctxtP,v ...@@ -267,23 +267,32 @@ private_rlc_am( void rlc_am_get_pdus (const protocol_ctxt_t* const ctxtP,v
*/ */
protected_rlc_am( void rlc_am_rx (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind);) protected_rlc_am( void rlc_am_rx (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind);)
/*! \fn struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP) /*! \fn struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP)
* \brief Request the maximum number of bytes that can be served by RLC instance to MAC and fix the amount of bytes requested by MAC for next RLC transmission. * \brief Request the maximum number of bytes that can be served by RLC instance to MAC and fix the amount of bytes requested by MAC for next RLC transmission.
* \param[in] ctxt_pP Running context. * \param[in] ctxt_pP Running context.
* \param[in] rlc_pP RLC AM protocol instance pointer. * \param[in] rlc_pP RLC AM protocol instance pointer.
* \param[in] tbs_sizeP Number of bytes requested by MAC for next transmission. * \param[in] tbs_sizeP Number of bytes requested by MAC for next transmission.
* \param[in] tx_statusP Transmission status given by MAC on previous MAC transmission of the PDU. * \param[in] tx_statusP Transmission status given by MAC on previous MAC transmission of the PDU.
* \param[in] enb_flagP eNB or UE flag indication.
* \return The maximum number of bytes that can be served by RLC instance to MAC. * \return The maximum number of bytes that can be served by RLC instance to MAC.
*/ */
public_rlc_am( struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP, void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP);) public_rlc_am( struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP, void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP);)
/*! \fn struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP) /*! \fn void rlc_am_set_nb_bytes_requested_by_mac (void * const rlc_pP,const tb_size_t tb_sizeP)
* \brief Set available TBS for RLC Tx just before am_mac_data_request. Used for UE only.
* \param[in] rlc_pP RLC AM protocol instance pointer.
* \param[in] tb_sizeP Available Tx Transport Block size in bytes.
*/
public_rlc_am( void rlc_am_set_nb_bytes_requested_by_mac (void * const rlc_pP,const tb_size_t tb_sizeP);)
/*! \fn struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP,const eNB_flag_t enb_flagP)
* \brief Gives PDUs to lower layer MAC. * \brief Gives PDUs to lower layer MAC.
* \param[in] ctxt_pP Running context. * \param[in] ctxt_pP Running context.
* \param[in] rlc_pP RLC AM protocol instance pointer. * \param[in] rlc_pP RLC AM protocol instance pointer.
* \param[in] enb_flagP eNB or UE flag
* \return A PDU of the previously requested number of bytes, and the updated maximum number of bytes that can be served by RLC instance to MAC for next RLC transmission. * \return A PDU of the previously requested number of bytes, and the updated maximum number of bytes that can be served by RLC instance to MAC for next RLC transmission.
*/ */
public_rlc_am( struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP);) public_rlc_am( struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP,const eNB_flag_t enb_flagP);)
/*! \fn void rlc_am_mac_data_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind data_indP) /*! \fn void rlc_am_mac_data_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind data_indP)
* \brief Receive PDUs from lower layer MAC. * \brief Receive PDUs from lower layer MAC.
...@@ -293,6 +302,13 @@ public_rlc_am( struct mac_data_req rlc_am_mac_data_request (const protocol_ct ...@@ -293,6 +302,13 @@ public_rlc_am( struct mac_data_req rlc_am_mac_data_request (const protocol_ct
*/ */
public_rlc_am( void rlc_am_mac_data_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind data_indP);) public_rlc_am( void rlc_am_mac_data_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind data_indP);)
/*! \fn uint32_t rlc_am_get_buffer_occupancy_in_bytes (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP)
* \brief Get Tx Buffer Occupancy.
* \param[in] ctxt_pP Running context.
* \param[in] rlc_pP RLC AM protocol instance pointer.
*/
public_rlc_am( uint32_t rlc_am_get_buffer_occupancy_in_bytes (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP);)
/*! \fn void rlc_am_data_req (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, mem_block_t *sduP) /*! \fn void rlc_am_data_req (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, mem_block_t *sduP)
* \brief Interface with higher layers, buffer higher layer SDUS for transmission. * \brief Interface with higher layers, buffer higher layer SDUS for transmission.
* \param[in] ctxt_pP Running context. * \param[in] ctxt_pP Running context.
......
...@@ -48,14 +48,17 @@ ...@@ -48,14 +48,17 @@
# define RLC_AM_SDU_DATA_BUFFER_SIZE 64*1024 # define RLC_AM_SDU_DATA_BUFFER_SIZE 64*1024
/** Max number of incoming SDUs from upper layer that can be buffered in a RLC AM protocol instance. */ /** Max number of incoming SDUs from upper layer that can be buffered in a RLC AM protocol instance. */
# define RLC_AM_SDU_CONTROL_BUFFER_SIZE 128 # define RLC_AM_SDU_CONTROL_BUFFER_SIZE 1024
/** Size of the retransmission buffer (number of PDUs). */ /** Size of the retransmission buffer (number of PDUs). */
# define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_SN_MODULO # define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_WINDOW_SIZE
/** PDU minimal header size in bytes. */ /** PDU minimal header size in bytes. */
# define RLC_AM_HEADER_MIN_SIZE 2 # define RLC_AM_HEADER_MIN_SIZE 2
/** PDU Segment minimal header size in bytes = PDU header + SOStart + SOEnd. */
# define RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE 4
/** If we want to send a segment of a PDU, then the min transport block size requested by MAC should be this amount. */ /** If we want to send a segment of a PDU, then the min transport block size requested by MAC should be this amount. */
# define RLC_AM_MIN_SEGMENT_SIZE_REQUEST 8 # define RLC_AM_MIN_SEGMENT_SIZE_REQUEST 8
...@@ -69,6 +72,99 @@ ...@@ -69,6 +72,99 @@
# define RLC_AM_MAX_NACK_IN_STATUS_PDU 1023 # define RLC_AM_MAX_NACK_IN_STATUS_PDU 1023
/** Max holes created by NACK_SN with segment offsets for a PDU in the retransmission buffer. */ /** Max holes created by NACK_SN with segment offsets for a PDU in the retransmission buffer. */
# define RLC_AM_MAX_HOLES_REPORT_PER_PDU 32 # define RLC_AM_MAX_HOLES_REPORT_PER_PDU 16
/** @} */ /** @} */
# endif
#define RLC_AM_POLL_PDU_INFINITE 0xFFFF
#define RLC_AM_POLL_BYTE_INFINITE 0xFFFFFFFF
/* MACRO DEFINITIONS */
#define RLC_AM_NEXT_SN(sn) (((sn)+1) & (RLC_AM_SN_MASK))
#define RLC_AM_PREV_SN(sn) (((sn)+(RLC_AM_SN_MODULO)-1) & (RLC_AM_SN_MASK))
#define RLC_DIFF_SN(sn,snref,modulus) ((sn+(modulus)-snref) & ((modulus)-1))
#define RLC_SN_IN_WINDOW(sn,snref,modulus) ((RLC_DIFF_SN(sn,snref,modulus)) < ((modulus) >> 1))
#define RLC_AM_DIFF_SN(sn,snref) (RLC_DIFF_SN(sn,snref,RLC_AM_SN_MODULO))
#define RLC_AM_SN_IN_WINDOW(sn,snref) (RLC_SN_IN_WINDOW(sn,snref,RLC_AM_SN_MODULO))
#define RLC_SET_BIT(x,offset) ((x) |= (1 << (offset)))
#define RLC_GET_BIT(x,offset) (((x) & (1 << (offset))) >> (offset))
#define RLC_CLEAR_BIT(x,offset) ((x) &= ~(1 << (offset)))
#define RLC_SET_EVENT(x,event) ((x) |= (event))
#define RLC_GET_EVENT(x,event) ((x) & (event))
#define RLC_CLEAR_EVENT(x,event) ((x) &= (~(event)))
/* Common to Data and Status PDU */
#define RLC_AM_SN_BITS 10
#define RLC_AM_PDU_D_C_BITS 1
#define RLC_AM_PDU_E_BITS 1
#define RLC_AM_PDU_FI_BITS 2
#define RLC_AM_PDU_POLL_BITS 1
#define RLC_AM_PDU_RF_BITS 1
#define RLC_AM_LI_BITS 11
#define RLC_AM_LI_MASK 0x7FF
/* AM Data PDU */
#define RLC_AM_PDU_E_OFFSET 2
#define RLC_AM_PDU_FI_OFFSET (RLC_AM_PDU_E_OFFSET + RLC_AM_PDU_E_BITS)
#define RLC_AM_PDU_POLL_OFFSET (RLC_AM_PDU_FI_OFFSET + RLC_AM_PDU_FI_BITS)
#define RLC_AM_PDU_RF_OFFSET (RLC_AM_PDU_POLL_OFFSET + RLC_AM_PDU_POLL_BITS)
#define RLC_AM_PDU_D_C_OFFSET (RLC_AM_PDU_RF_OFFSET + RLC_AM_PDU_RF_BITS)
#define RLC_AM_PDU_GET_FI_START(px) (RLC_GET_BIT((px),RLC_AM_PDU_FI_OFFSET + 1))
#define RLC_AM_PDU_GET_FI_END(px) (RLC_GET_BIT((px),RLC_AM_PDU_FI_OFFSET))
#define RLC_AM_PDU_GET_LI(x,offset) (((x) >> (offset)) & RLC_AM_LI_MASK)
#define RLC_AM_PDU_SET_LI(x,li,offset) ((x) |= (((li) & RLC_AM_LI_MASK) << (offset)))
#define RLC_AM_PDU_SET_E(px) (RLC_SET_BIT((px),RLC_AM_PDU_E_OFFSET))
#define RLC_AM_PDU_SET_D_C(px) (RLC_SET_BIT((px),RLC_AM_PDU_D_C_OFFSET))
#define RLC_AM_PDU_SET_RF(px) (RLC_SET_BIT((px),RLC_AM_PDU_RF_OFFSET))
#define RLC_AM_PDU_SET_POLL(px) (RLC_SET_BIT((px),RLC_AM_PDU_POLL_OFFSET))
#define RLC_AM_PDU_CLEAR_POLL(px) (RLC_CLEAR_BIT((px),RLC_AM_PDU_POLL_OFFSET))
#define RLC_AM_PDU_SEGMENT_SO_LENGTH 15
#define RLC_AM_PDU_SEGMENT_SO_BYTES 2
#define RLC_AM_PDU_SEGMENT_SO_OFFSET 0
#define RLC_AM_PDU_LSF_OFFSET (RLC_AM_PDU_SEGMENT_SO_OFFSET + RLC_AM_PDU_SEGMENT_SO_LENGTH)
#define RLC_AM_PDU_SET_LSF(px) (RLC_SET_BIT((px),RLC_AM_PDU_LSF_OFFSET))
#define RLC_AM_HEADER_LI_LENGTH(li) ((li) + ((li)>>1) + ((li)&1))
#define RLC_AM_PDU_SEGMENT_HEADER_SIZE(numLis) (RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + RLC_AM_HEADER_LI_LENGTH(numLis))
/* STATUS PDU */
#define RLC_AM_STATUS_PDU_CPT_STATUS 0
#define RLC_AM_STATUS_PDU_CPT_OFFSET 4
#define RLC_AM_STATUS_PDU_CPT_LENGTH 3
#define RLC_AM_STATUS_PDU_ACK_SN_OFFSET 2
#define RLC_AM_STATUS_PDU_SO_LENGTH 15
#define RLC_AM_STATUS_PDU_SO_END_ALL_BYTES 0x7FFF
/* Uplink STATUS PDU trigger events */
#define RLC_AM_STATUS_NOT_TRIGGERED 0
#define RLC_AM_STATUS_TRIGGERED_POLL 0x01 /* Status Report is triggered by a received poll */
#define RLC_AM_STATUS_TRIGGERED_T_REORDERING 0x02 /* Status Report is triggered by Timer Reordering Expiry */
#define RLC_AM_STATUS_TRIGGERED_DELAYED 0x10 /* Status is delayed until SN(receivedPoll) < VR(MS) */
#define RLC_AM_STATUS_PROHIBIT 0x20 /* TimerStatusProhibit still running */
#define RLC_AM_STATUS_NO_TX_MASK (RLC_AM_STATUS_PROHIBIT | RLC_AM_STATUS_TRIGGERED_DELAYED)
/* Status triggered (bit 5-7) will be concatenated with Poll triggered (bit 0-4) for RLCdec. RLC_AM_STATUS_TRIGGERED_DELAYED is not recorded. */
#define RLC_AM_SET_STATUS(x,event) (RLC_SET_EVENT(x,event))
#define RLC_AM_GET_STATUS(x,event) (RLC_GET_EVENT(x,event))
#define RLC_AM_CLEAR_STATUS(x,event) (RLC_CLEAR_EVENT(x,event))
#define RLC_AM_CLEAR_ALL_STATUS(x) ((x) = (RLC_AM_STATUS_NOT_TRIGGERED))
#endif
...@@ -57,7 +57,6 @@ typedef struct rlc_am_entity_s { ...@@ -57,7 +57,6 @@ typedef struct rlc_am_entity_s {
boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */
rlc_buffer_occupancy_t sdu_buffer_occupancy; /*!< \brief Number of bytes of unsegmented SDUs. */ rlc_buffer_occupancy_t sdu_buffer_occupancy; /*!< \brief Number of bytes of unsegmented SDUs. */
rlc_buffer_occupancy_t retransmission_buffer_occupancy; /*!< \brief Number of bytes of PDUs in retransmission buffer waiting for a ACK. */
rlc_buffer_occupancy_t status_buffer_occupancy; /*!< \brief Number of bytes of control PDUs waiting for transmission. */ rlc_buffer_occupancy_t status_buffer_occupancy; /*!< \brief Number of bytes of control PDUs waiting for transmission. */
rlc_am_control_pdu_info_t control_pdu_info; rlc_am_control_pdu_info_t control_pdu_info;
...@@ -69,17 +68,14 @@ typedef struct rlc_am_entity_s { ...@@ -69,17 +68,14 @@ typedef struct rlc_am_entity_s {
pthread_mutex_t lock_input_sdus; pthread_mutex_t lock_input_sdus;
rlc_am_tx_sdu_management_t *input_sdus; /*!< \brief Input SDU buffer (for SDUs coming from upper layers). */ rlc_am_tx_sdu_management_t *input_sdus; /*!< \brief Input SDU buffer (for SDUs coming from upper layers). */
signed int nb_sdu; /*!< \brief Total number of valid rlc_am_tx_sdu_management_t in input_sdus[]. */ signed int nb_sdu; /*!< \brief Total number of valid rlc_am_tx_sdu_management_t in input_sdus[]. */
signed int nb_sdu_no_segmented; /*!< \brief Total number of SDUs not segmented and partially segmented. */ signed int nb_sdu_no_segmented; /*!< \brief Total number of SDUs not segmented and partially segmented. nb_sdu_no_segmented = next_sdu_index - current_sdu_index */
signed int next_sdu_index; /*!< \brief Next SDU index in input_sdus array where for a new incoming SDU. */ signed int next_sdu_index; /*!< \brief Next SDU index in input_sdus array where for a new incoming SDU. */
signed int current_sdu_index; /*!< \brief Current SDU index in input_sdus array to be segmented. */ signed int current_sdu_index; /*!< \brief Current SDU index in input_sdus array to be segmented which is not segmented or partially segmented. */
rlc_am_tx_data_pdu_management_t *pdu_retrans_buffer; /*!< \brief Retransmission buffer. */ rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer; /*!< \brief Transmission PDU data buffer. Used also for retransmissions */
signed int retrans_num_pdus; /*!< \brief Number of PDUs in the retransmission buffer. */ signed int retrans_num_pdus; /*!< \brief Number of PDUs in the retransmission buffer. */
signed int retrans_num_bytes; /*!< \brief Number of bytes in the retransmission buffer. */ signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. Only payload is taken into account */
signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. */
unsigned int num_nack_so; /*!< \brief Number of segment offsets asked to be retransmitted by peer RLC entity. */
unsigned int num_nack_sn; /*!< \brief Number of segment asked to be retransmitted by peer RLC entity. */
boolean_t force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ boolean_t force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */
//--------------------------------------------------------------------- //---------------------------------------------------------------------
...@@ -137,7 +133,7 @@ typedef struct rlc_am_entity_s { ...@@ -137,7 +133,7 @@ typedef struct rlc_am_entity_s {
//----------------------------- //-----------------------------
uint16_t max_retx_threshold; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to limit the number of retransmissions of an AMD PDU. */ uint16_t max_retx_threshold; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to limit the number of retransmissions of an AMD PDU. */
uint16_t poll_pdu; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollPDU PDUs. */ uint16_t poll_pdu; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollPDU PDUs. */
uint16_t poll_byte; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollByte bytes. */ uint32_t poll_byte; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollByte bytes. */
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// STATISTICS // STATISTICS
...@@ -176,14 +172,14 @@ typedef struct rlc_am_entity_s { ...@@ -176,14 +172,14 @@ typedef struct rlc_am_entity_s {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// OUTPUTS // OUTPUTS
//--------------------------------------------------------------------- //---------------------------------------------------------------------
sdu_size_t nb_bytes_requested_by_mac; /*!< \brief Number of bytes requested by lower layer for next transmission. */ sdu_size_t nb_bytes_requested_by_mac; /*!< \brief Number of remaining bytes available for transmission of any RLC PDU indicated by lower layer */
list_t pdus_to_mac_layer; /*!< \brief PDUs buffered for transmission to MAC layer. */ list_t pdus_to_mac_layer; /*!< \brief PDUs buffered for transmission to MAC layer. */
list_t control_pdu_list; /*!< \brief Control PDUs buffered for transmission to MAC layer. */ list_t control_pdu_list; /*!< \brief Control PDUs buffered for transmission to MAC layer. */
rlc_sn_t first_retrans_pdu_sn; /*!< \brief Lowest sequence number of PDU to be retransmitted. */
list_t segmentation_pdu_list; /*!< \brief List of "freshly" segmented PDUs. */ list_t segmentation_pdu_list; /*!< \brief List of "freshly" segmented PDUs. */
boolean_t status_requested; /*!< \brief Status requested by peer. */ uint8_t status_requested; /*!< \brief Status bitmap requested by peer. */
frame_t last_frame_status_indication; /*!< \brief The last frame number a MAC status indication has been received by RLC. */ rlc_sn_t sn_status_triggered_delayed; /*!< \brief SN of the last received poll for which Status is delayed until SN is out of Rx Window. */
uint32_t last_absolute_subframe_status_indication; /*!< \brief The last absolute subframe number a MAC status indication has been received by RLC. */
//----------------------------- //-----------------------------
// buffer occupancy measurements sent to MAC // buffer occupancy measurements sent to MAC
//----------------------------- //-----------------------------
......
...@@ -41,21 +41,28 @@ void rlc_am_free_in_sdu( ...@@ -41,21 +41,28 @@ void rlc_am_free_in_sdu(
const unsigned int index_in_bufferP) const unsigned int index_in_bufferP)
{ {
if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) { if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) {
/* BugFix: SDU shall have been already freed during initial PDU segmentation or concatenation !! */
AssertFatal(rlcP->input_sdus[index_in_bufferP].mem_block == NULL, "RLC AM Tx SDU Conf: Data Part is not empty index=%d LcId=%d\n",
index_in_bufferP,rlcP->channel_id);
/*
if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) { if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) {
free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block, __func__); free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block, __func__);
rlcP->input_sdus[index_in_bufferP].mem_block = NULL; rlcP->input_sdus[index_in_bufferP].mem_block = NULL;
rlcP->nb_sdu_no_segmented -= 1; rlcP->nb_sdu_no_segmented -= 1;
rlcP->input_sdus[index_in_bufferP].sdu_remaining_size = 0; rlcP->input_sdus[index_in_bufferP].sdu_remaining_size = 0;
} }
*/
rlcP->nb_sdu -= 1; rlcP->nb_sdu -= 1;
memset(&rlcP->input_sdus[index_in_bufferP], 0, sizeof(rlc_am_tx_sdu_management_t)); memset(&rlcP->input_sdus[index_in_bufferP], 0, sizeof(rlc_am_tx_sdu_management_t));
rlcP->input_sdus[index_in_bufferP].flags.transmitted_successfully = 1; rlcP->input_sdus[index_in_bufferP].flags.transmitted_successfully = 1;
// case when either one SDU needs to be removed from segmentation or SDU buffer is full
if (rlcP->current_sdu_index == index_in_bufferP) { if (rlcP->current_sdu_index == index_in_bufferP) {
rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
} }
// wrapping and reset current_sdu_index to next_sdu_index when all transmitted SDUs have been acknowledged
while ((rlcP->current_sdu_index != rlcP->next_sdu_index) && while ((rlcP->current_sdu_index != rlcP->next_sdu_index) &&
(rlcP->input_sdus[rlcP->current_sdu_index].flags.transmitted_successfully == 1)) { (rlcP->input_sdus[rlcP->current_sdu_index].flags.transmitted_successfully == 1)) {
rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
...@@ -100,3 +107,41 @@ rlc_am_in_sdu_is_empty( ...@@ -100,3 +107,41 @@ rlc_am_in_sdu_is_empty(
return 0; return 0;
} }
// called when PDU is ACKED
//-----------------------------------------------------------------------------
void
rlc_am_pdu_sdu_data_cnf(
const protocol_ctxt_t* const ctxt_pP,
rlc_am_entity_t* const rlc_pP,
const rlc_sn_t snP)
{
int pdu_sdu_index;
int sdu_index;
for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].nb_sdus; pdu_sdu_index++) {
sdu_index = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].sdus_index[pdu_sdu_index];
assert(sdu_index >= 0);
assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE);
rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1;
if ((rlc_pP->input_sdus[sdu_index].nb_pdus_ack == rlc_pP->input_sdus[sdu_index].nb_pdus) &&
(rlc_pP->input_sdus[sdu_index].sdu_remaining_size == 0)) {
#if TEST_RLC_AM
rlc_am_v9_3_0_test_data_conf (
rlc_pP->module_id,
rlc_pP->rb_id,
rlc_pP->input_sdus[sdu_index].mui,
RLC_SDU_CONFIRM_YES);
#else
rlc_data_conf(
ctxt_pP,
rlc_pP->rb_id,
rlc_pP->input_sdus[sdu_index].mui,
RLC_SDU_CONFIRM_YES,
rlc_pP->is_data_plane);
#endif
rlc_am_free_in_sdu(ctxt_pP, rlc_pP, sdu_index);
}
}
}
...@@ -77,5 +77,13 @@ protected_rlc_am_in_sdu(void rlc_am_free_in_sdu_data (const protocol_ctxt_t* con ...@@ -77,5 +77,13 @@ protected_rlc_am_in_sdu(void rlc_am_free_in_sdu_data (const protocol_ctxt_t* con
* \return 1 if the buffer is empty, else 0. * \return 1 if the buffer is empty, else 0.
*/ */
protected_rlc_am_in_sdu(signed int rlc_am_in_sdu_is_empty(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP);) protected_rlc_am_in_sdu(signed int rlc_am_in_sdu_is_empty(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP);)
/*! \fn void rlc_am_pdu_sdu_data_cnf(const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* const rlc_pP,const rlc_sn_t snP)
* \brief Process SDU cnf of a ACKED PDU for all SDUs concatenated in this PDU.
* \param[in] ctxtP Running context.
* \param[in] rlcP RLC AM protocol instance pointer.
* \param[in] snP Sequence number of the PDU.
*/
protected_rlc_am_in_sdu(void rlc_am_pdu_sdu_data_cnf(const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* const rlc_pP,const rlc_sn_t snP);)
/** @} */ /** @} */
# endif # endif
...@@ -51,16 +51,16 @@ rlc_am_init( ...@@ -51,16 +51,16 @@ rlc_am_init(
pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL); pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL);
rlc_pP->input_sdus = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t)); rlc_pP->input_sdus = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t));
//#warning "cast the rlc retrans buffer to uint32" //#warning "cast the rlc retrans buffer to uint32"
// rlc_pP->pdu_retrans_buffer = calloc(1, (uint16_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(rlc_am_tx_data_pdu_management_t))); // rlc_pP->tx_data_pdu_buffer = calloc(1, (uint16_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(rlc_am_tx_data_pdu_management_t)));
rlc_pP->pdu_retrans_buffer = calloc(1, (uint32_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof( rlc_pP->tx_data_pdu_buffer = calloc(1, (uint32_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(
rlc_am_tx_data_pdu_management_t))); rlc_am_tx_data_pdu_management_t)));
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] input_sdus[] = %p element size=%zu\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] input_sdus[] = %p element size=%zu\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->input_sdus, rlc_pP->input_sdus,
sizeof(rlc_am_tx_sdu_management_t)); sizeof(rlc_am_tx_sdu_management_t));
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] pdu_retrans_buffer[] = %p element size=%zu\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] tx_data_pdu_buffer[] = %p element size=%zu\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->pdu_retrans_buffer, rlc_pP->tx_data_pdu_buffer,
sizeof(rlc_am_tx_data_pdu_management_t)); sizeof(rlc_am_tx_data_pdu_management_t));
// TX state variables // TX state variables
...@@ -74,12 +74,12 @@ rlc_am_init( ...@@ -74,12 +74,12 @@ rlc_am_init(
// RX state variables // RX state variables
//rlc_pP->vr_r = 0; //rlc_pP->vr_r = 0;
rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE;
//rlc_pP->vr_x = 0; rlc_pP->vr_x = RLC_SN_UNDEFINED;
//rlc_pP->vr_ms = 0; //rlc_pP->vr_ms = 0;
//rlc_pP->vr_h = 0; //rlc_pP->vr_h = 0;
rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1
rlc_pP->first_retrans_pdu_sn = -1;
rlc_pP->initialized = TRUE; rlc_pP->initialized = TRUE;
} }
...@@ -128,12 +128,13 @@ rlc_am_reestablish( ...@@ -128,12 +128,13 @@ rlc_am_reestablish(
// RX state variables // RX state variables
rlc_pP->vr_r = 0; rlc_pP->vr_r = 0;
rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE;
rlc_pP->vr_x = 0; rlc_pP->vr_x = RLC_SN_UNDEFINED;
rlc_pP->vr_ms = 0; rlc_pP->vr_ms = 0;
rlc_pP->vr_h = 0; rlc_pP->vr_h = 0;
rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
rlc_pP->status_requested = RLC_AM_STATUS_NOT_TRIGGERED;
rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1
rlc_pP->first_retrans_pdu_sn = -1;
rlc_pP->initialized = TRUE; rlc_pP->initialized = TRUE;
...@@ -172,16 +173,16 @@ rlc_am_cleanup( ...@@ -172,16 +173,16 @@ rlc_am_cleanup(
pthread_mutex_destroy(&rlc_pP->lock_input_sdus); pthread_mutex_destroy(&rlc_pP->lock_input_sdus);
if (rlc_pP->pdu_retrans_buffer != NULL) { if (rlc_pP->tx_data_pdu_buffer != NULL) {
for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) { for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) {
if (rlc_pP->pdu_retrans_buffer[i].mem_block != NULL) { if (rlc_pP->tx_data_pdu_buffer[i % RLC_AM_WINDOW_SIZE].mem_block != NULL) {
free_mem_block(rlc_pP->pdu_retrans_buffer[i].mem_block, __func__); free_mem_block(rlc_pP->tx_data_pdu_buffer[i % RLC_AM_WINDOW_SIZE].mem_block, __func__);
rlc_pP->pdu_retrans_buffer[i].mem_block = NULL; rlc_pP->tx_data_pdu_buffer[i % RLC_AM_WINDOW_SIZE].mem_block = NULL;
} }
} }
free(rlc_pP->pdu_retrans_buffer); free(rlc_pP->tx_data_pdu_buffer);
rlc_pP->pdu_retrans_buffer = NULL; rlc_pP->tx_data_pdu_buffer = NULL;
} }
memset(rlc_pP, 0, sizeof(rlc_am_entity_t)); memset(rlc_pP, 0, sizeof(rlc_am_entity_t));
......
...@@ -212,7 +212,8 @@ void ...@@ -212,7 +212,8 @@ void
rlc_am_reassemble_pdu( rlc_am_reassemble_pdu(
const protocol_ctxt_t* const ctxt_pP, const protocol_ctxt_t* const ctxt_pP,