Skip to content
Snippets Groups Projects
Commit c1f14990 authored by Lionel Gauthier's avatar Lionel Gauthier
Browse files

Old rev code

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7372 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 0bd3c9ec
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 5532 deletions
This diff is collapsed.
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_constant.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_CONSTANT_H__
# define __RLC_AM_CONSTANT_H__
# define RLC_AM_LOCATION_UTRAN 0xBA
# define RLC_AM_LOCATION_UE 0x01
//----------------------------------------------------------
// AMD DATA, CONTROL PDU parameters
//----------------------------------------------------------
# define NB_MAX_SUFI 30
# define SUFI_MAX_SIZE 40
// SUFI field (4 bits)
# define RLC_AM_SUFI_NO_MORE 0x0
# define RLC_AM_SUFI_WINDOW 0x1
# define RLC_AM_SUFI_ACK 0x2
# define RLC_AM_SUFI_LIST 0x3
# define RLC_AM_SUFI_BITMAP 0x4
# define RLC_AM_SUFI_RLIST 0x5
# define RLC_AM_SUFI_MRW 0x6
# define RLC_AM_SUFI_MRW_ACK 0x7
# define RLC_AM_SUFI_NO_MORE_SIZE 4
//in bits
# define RLC_AM_SUFI_ACK_SIZE 16
//in bits
# define RLC_AM_SUFI_LIST_SIZE_MIN 24
//in bits
# define RLC_AM_SUFI_BITMAP_SIZE_MIN 28
//in bits
//----------------------------------------------------------
// values for ack field of struct rlc_am_tx_pdu_management
// this struct is mapped on the misc field of each pdu
# define RLC_AM_PDU_ACK_NO_EVENT 0
# define RLC_AM_PDU_ACK_EVENT 1
# define RLC_AM_PDU_NACK_EVENT -1
//----------------------------------------------------------
# define RLC_AM_SEND_MRW_OFF 0x0F
# define RLC_AM_SEND_MRW_ON 0xF0
//----------------------------------------------------------
// SN Field
# define RLC_AM_SN_1ST_PART_MASK 0x7F
# define RLC_AM_SN_2ND_PART_MASK 0xF8
//----------------------------------------------------------
// Polling bit (values shifted 2 bits left)
# define RLC_AM_P_STATUS_REPORT_NOT_REQUESTED 0
# define RLC_AM_P_STATUS_REPORT_REQUESTED 4
# define RLC_AM_P_STATUS_REPORT_MASK 4
//----------------------------------------------------------
// li field (values shifted 1 bit left)
# define RLC_AM_SEGMENT_NB_MAX_LI_PER_PDU 32
//----------------------------------------------------------
// shifted 3 bits left
# define RLC_AM_RESET_SEQUENCE_NUMBER_MASK 0x08
# define RLC_AM_TIMER_POLL_TIME_OUT_EVENT 0x001
# define RLC_AM_TIMER_POLL_PROHIBIT_TIME_OUT_EVENT 0x002
# define RLC_AM_TIMER_EPC_TIME_OUT_EVENT 0x004
# define RLC_AM_TIMER_DISCARD_TIME_OUT_EVENT 0x008
# define RLC_AM_TIMER_POLL_PERIODIC_TIME_OUT_EVENT 0x010
# define RLC_AM_TIMER_STATUS_PROHIBIT_TIME_OUT_EVENT 0x020
# define RLC_AM_TIMER_STATUS_PERIODIC_TIME_OUT_EVENT 0x040
# define RLC_AM_TIMER_RST_TIME_OUT_EVENT 0x080
# define RLC_AM_TIMER_MRW_TIME_OUT_EVENT 0x100
//----------------------------------------------------------
# define RLC_AM_SDU_SEGMENTS_SUBMITTED_TO_LOWER_LAYER 0xFF
// for sdu_header_copy
# define RLC_AM_SN_INVALID 0xFFFF
// PDU transmission
# define RLC_AM_PDU_COPY_LOCATION_RETRANSMISSION_BUFFER_TO_SEND 0x10
# define RLC_AM_PDU_COPY_LOCATION_PDUS_TO_MAC_LAYER 0x20
# define RLC_AM_PDU_COPY_LOCATION_MASK 0xF0
//----------------------------------------------------------
// Events defined for state model of the acknowledged mode entity
# define RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT 0x00
# define RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT 0x01
# define RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT 0x10
# define RLC_AM_TRANSMIT_CRLC_SUSPEND_CNF_EVENT 0x11
# define RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT 0x12
# define RLC_AM_RECEIVE_RESET_EVENT 0x20
# define RLC_AM_TRANSMIT_RESET_EVENT 0x21
# define RLC_AM_RECEIVE_RESET_ACK_EVENT 0x22
# define RLC_AM_TRANSMIT_RESET_ACK_EVENT 0x23
//----------------------------------------------------------
# define RLC_AM_TRAFFIC_NOT_ALLOWED 0x00
# define RLC_AM_TRAFFIC_ALLOWED_FOR_STATUS 0xC0
// mutual exclusion of set bits with next value
# define RLC_AM_TRAFFIC_ALLOWED_FOR_DATA 0x0D
// mutual exclusion of set bits with previous value
# define RLC_AM_DCCH_ID 0xC0
// mutual exclusion of set bits with next value
# define RLC_AM_DTCH_ID 0x0D
// mutual exclusion of set bits with previous value
//----------------------------------------------------------
// for status report of transmission by MAC layer
# define RLC_AM_STATUS_PDU_TYPE 0x0001
# define RLC_AM_FIRST_STATUS_PDU_TYPE 0x0011
# define RLC_AM_LAST_STATUS_PDU_TYPE 0x0021
# define RLC_AM_MRW_STATUS_PDU_TYPE 0x0040
# define RLC_AM_RESET_PDU_TYPE 0x0080
# define RLC_AM_RESET_ACK_PDU_TYPE 0x0100
# define RLC_AM_DATA_POLL_PDU_TYPE 0x1800
# define RLC_AM_DATA_PDU_TYPE 0x1000
//----------------------------------------------------------
// TIMER EPC
# define TIMER_EPC_STATE_IDLE 0x00
# define TIMER_EPC_STATE_TIMER_ARMED 0x01
# define TIMER_EPC_STATE_TIMED_OUT 0x02
# define TIMER_EPC_STATE_VR_EP_COUNTING_DOWN 0x04
# define TIMER_EPC_STATE_VR_EP_EQUAL_ZERO 0x08
# define TIMER_EPC_PDU_STATUS_SUBMITTED_LOWER_LAYER_EVENT 0x01
# define TIMER_EPC_PDU_STATUS_TRANSMITED_EVENT 0x02
# define TIMER_EPC_TIMER_TIMED_OUT_EVENT 0x04
# define TIMER_EPC_VR_EP_EQUAL_ZERO_EVENT 0x08
# endif
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_control_primitives_proto_extern.h -
-------------------
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_CONTROL_PRIMITIVES_H__
# define __RLC_AM_CONTROL_PRIMITIVES_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "mem_block.h"
# include "rrm_config_structs.h"
//-----------------------------------------------------------------------------
extern void config_req_rlc_am (struct rlc_am_entity *rlcP, module_id_t module_idP, rlc_am_info_t * config_amP, uint8_t rb_idP, rb_type_t rb_typeP);
extern void send_rlc_am_control_primitive (struct rlc_am_entity *rlcP, module_id_t module_idP, mem_block_t * cprimitiveP);
extern void init_rlc_am (struct rlc_am_entity *rlcP);
extern void rlc_am_reset_state_variables (struct rlc_am_entity *rlcP);
extern void rlc_am_alloc_buffers_after_establishment (struct rlc_am_entity *rlcP);
extern void rlc_am_discard_all_pdus (struct rlc_am_entity *rlcP);
extern void rlc_am_stop_all_timers (struct rlc_am_entity *rlcP);
extern void rlc_am_free_all_resources (struct rlc_am_entity *rlcP);
extern void rlc_am_set_configured_parameters (struct rlc_am_entity *rlcP, mem_block_t * cprimitiveP);
//extern void rlc_am_probing_get_buffer_occupancy_measurements (struct rlc_am_entity *rlcP, probing_report_traffic_rb_parameters *reportP, int measurement_indexP);
# endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_demux.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
//#include "mac_log_interface_struct.h"
#include "LAYER2/RLC/rlc.h"
#include "mac_primitives.h"
#include "list.h"
#include "rlc_am_entity.h"
#include "rlc_am_structs.h"
#include "rlc_am_constants.h"
#include "rlc_am_receiver_proto_extern.h"
#include "rlc_am_reset_proto_extern.h"
#include "rlc_am_status_proto_extern.h"
#include "rlc_am_timers_proto_extern.h"
#include "LAYER2/MAC/extern.h"
#define DEBUG_DEMUX_RESET
#define DEBUG_DEMUX
//-----------------------------------------------------------------------------
void
rlc_am_demux_routing (struct rlc_am_entity *rlcP, unsigned int traffic_typeP, struct mac_data_ind data_indP)
{
//-----------------------------------------------------------------------------
struct rlc_am_pdu_header *data;
struct rlc_am_reset_header *control;
mem_block_t *tb;
uint8_t *first_byte;
uint16_t tb_size_in_bytes;
uint8_t first_bit;
uint8_t bits_to_shift;
uint8_t bits_to_shift_last_loop;
uint8_t data_received;
int index;
//-------------------------------------------------------
// D A T A P D U
//-------------------------------------------------------
data_received = 0;
while ((tb = list_remove_head (&data_indP.data))) {
if (!(((struct mac_tb_ind *) (tb->data))->error_indication)) {
first_byte = ((struct mac_tb_ind *) (tb->data))->data_ptr;
tb_size_in_bytes = data_indP.tb_size >> 3;
first_bit = ((struct mac_tb_ind *) (tb->data))->first_bit;
if (first_bit > 0) {
// shift data of transport_block TO CHECK
bits_to_shift_last_loop = 0;
while ((tb_size_in_bytes)) {
bits_to_shift = first_byte[tb_size_in_bytes] >> (8 - first_bit);
first_byte[tb_size_in_bytes] = (first_byte[tb_size_in_bytes] << first_bit) | (bits_to_shift_last_loop);
tb_size_in_bytes -= 1;
bits_to_shift_last_loop = bits_to_shift;
}
first_byte[0] = (first_byte[0] << first_bit) | (bits_to_shift_last_loop);
}
((struct rlc_am_rx_pdu_management *) (tb->data))->first_byte = first_byte;
data = (struct rlc_am_pdu_header *) (first_byte);
if ((data->byte1 & RLC_DC_MASK) == RLC_DC_DATA_PDU) {
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] RX AMD PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
for (index=0; index < rlcP->pdu_size ; index++) {
msg("%02X.",first_byte[index]);
}
msg("\n");
#endif
rlcP->stat_rx_data_pdu += 1;
if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) {
((struct rlc_am_rx_pdu_management *) (tb->data))->piggybacked_processed = 0;
receiver_retransmission_management (rlcP, tb, data);
// pdu is data;
data_received = 1;
} else {
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] DROP DATA TB NOT ALLOWED IN PROTOCOL STATE 0x%02X\n", rlcP->rb_id, rlcP->protocol_state);
#endif
free_mem_block (tb);
}
} else {
rlcP->stat_rx_control_pdu += 1;
control = (struct rlc_am_reset_header *) first_byte;
if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_STATUS) {
if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) {
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] RX STATUS PDU ON DTCH Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlc_am_process_status_info (rlcP, &(control->byte1));
}
} else if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_RESET) {
#ifdef DEBUG_DEMUX_RESET
msg ("[RLC_AM][RB %d][DEMUX] RX RESET PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
process_reset (tb, control, rlcP);
} else if ((control->byte1 & RLC_PDU_TYPE_MASK) == RLC_PDU_TYPE_RESET_ACK) {
#ifdef DEBUG_DEMUX_RESET
msg ("[RLC_AM][RB %d][DEMUX] RX RESET ACK PDU Frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
process_reset_ack (tb, control, rlcP);
#ifndef USER_MODE
rlc_info_t Rlc_info_am_config1;
Rlc_info_am_config1.rlc_mode=RLC_AM;
Rlc_info_am_config1.rlc.rlc_am_info.sdu_discard_mode = SDU_DISCARD_MODE_RESET;//SDU_DISCARD_MODE_MAX_DAT_RETRANSMISSION;//
Rlc_info_am_config1.rlc.rlc_am_info.timer_poll = 0;
Rlc_info_am_config1.rlc.rlc_am_info.timer_poll_prohibit = 0;
Rlc_info_am_config1.rlc.rlc_am_info.timer_discard = 500;
Rlc_info_am_config1.rlc.rlc_am_info.timer_poll_periodic = 0;
Rlc_info_am_config1.rlc.rlc_am_info.timer_status_prohibit = 250;
Rlc_info_am_config1.rlc.rlc_am_info.timer_status_periodic = 500;
Rlc_info_am_config1.rlc.rlc_am_info.timer_rst = 250;//250
Rlc_info_am_config1.rlc.rlc_am_info.max_rst = 500;//500
Rlc_info_am_config1.rlc.rlc_am_info.timer_mrw = 0;
Rlc_info_am_config1.rlc.rlc_am_info.pdu_size = 32; //416; // in bits
//Rlc_info_am.rlc.rlc_am_info.in_sequence_delivery = 1;//boolean
Rlc_info_am_config1.rlc.rlc_am_info.max_dat = 32;//127;
Rlc_info_am_config1.rlc.rlc_am_info.poll_pdu = 0;
Rlc_info_am_config1.rlc.rlc_am_info.poll_sdu = 0;//256;/
Rlc_info_am_config1.rlc.rlc_am_info.poll_window = 80;//128
Rlc_info_am_config1.rlc.rlc_am_info.tx_window_size = 512;
Rlc_info_am_config1.rlc.rlc_am_info.rx_window_size = 512;
Rlc_info_am_config1.rlc.rlc_am_info.max_mrw = 8;
Rlc_info_am_config1.rlc.rlc_am_info.last_transmission_pdu_poll_trigger = 1;//boolean
Rlc_info_am_config1.rlc.rlc_am_info.last_retransmission_pdu_poll_trigger = 1;//boolean
Rlc_info_am_config1.rlc.rlc_am_info.send_mrw = 1;//boolean*
Mac_rlc_xface->rrc_rlc_config_req(0,CONFIG_ACTION_REMOVE,rlcP->rb_id,RADIO_ACCESS_BEARER,Rlc_info_am_config1);
Mac_rlc_xface->rrc_rlc_config_req(0,CONFIG_ACTION_ADD,rlcP->rb_id,RADIO_ACCESS_BEARER,Rlc_info_am_config1);
#endif
}
free_mem_block (tb);
}
} else {
#ifdef BENCH_QOS_L2
fprintf (bench_l2, "[PDU RX ERROR] FRAME %d RLC-AM %p\n", Mac_rlc_xface->frame, rlcP);
#endif
#ifdef DEBUG_DEMUX
msg ("[RLC_AM][RB %d][DEMUX] RX PDU WITH ERROR INDICATION\n", rlcP->rb_id);
#endif
rlcP->stat_rx_error_pdu += 1;
free_mem_block (tb);
}
}
if ((data_received)) { //avoid call
if (traffic_typeP & RLC_AM_TRAFFIC_ALLOWED_FOR_DATA) {
if (rlcP->pdu_size <= 126) {
#ifdef DEBUG_DEMUX
msg("[RLC_AM][RB %d] Calling process_receiver_buffer_7\n",rlcP->rb_id);
#endif
process_receiver_buffer_7 (rlcP);
} else {
#ifdef DEBUG_DEMUX
msg("[RLC_AM][RB %d] Calling process_receiver_buffer_15\n",rlcP->rb_id);
#endif
process_receiver_buffer_15 (rlcP);
}
}
}
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_demux_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_DEMUX_PROTO_EXTERN_H__
# define __RLC_AM_DEMUX_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "mac_primitives.h"
//-----------------------------------------------------------------------------
extern void rlc_am_demux_routing (struct rlc_am_entity *rlcP, unsigned int traffic_typeP, struct mac_data_ind data_indP);
# endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_notif.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#define RLC_AM_C
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "rlc.h"
#include "rlc_primitives.h"
#include "rlc_am_status_proto_extern.h"
#include "umts_timer_struct.h"
#include "umts_timer_proto_extern.h"
#include "rlc_am_discard_tx_proto_extern.h"
#include "rlc_am_reset_proto_extern.h"
#include "LAYER2/MAC/extern.h"
//-----------------------------------------------------------------------------
void rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity* rlcP, mem_block_t* discard_procedureP);
void rlc_am_discard_notify_sdu_time_out (struct rlc_am_entity* rlcP, mem_block_t* sduP);
void rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity* rlcP, mem_block_t* mbP);
//-----------------------------------------------------------------------------
// handler for timer
//-----------------------------------------------------------------------------
void
rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity* rlcP, mem_block_t* discard_procedureP)
{
//-----------------------------------------------------------------------------
/* from 3GPP TS 25.322 V5.5.0
If Timer_MRW expires before the discard procedure is terminated, the Sender shall:
- if VT(MRW)<MaxMRW-1:
- set the MRW SUFI as previously transmitted (even if additional SDUs were discarded in the mean-time);
- include the MRW SUFI in a new status report (if other SUFIs are included, their contents shall be updated);
- transmit the status report by either including it in a STATUS PDU or piggybacked in an AMD PDU;
- increment VT(MRW) by one;
- restart Timer_MRW for this discard procedure.
If the number of retransmission of an MRW SUFI (i.e. VT(MRW)) equals MaxMRW, the Sender shall:
- terminate the SDU discard with explicit signalling procedure;
- stop the timer Timer_MRW;
- deliver an error indication to upper layers;
- initiate the RLC RESET procedure */
rlcP->timer_mrw = NULL;
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d][DISCARD] NOTIF MRW_ACK TIME OUT VT(MRW) %d PROCEDURE %p\n", rlcP->rb_id, rlcP->vt_mrw, discard_procedureP);
#endif
if ((rlcP->protocol_state & (RLC_RESET_PENDING_STATE | RLC_RESET_AND_SUSPEND_STATE)) == 0) {
// check the number of retransmission of the status pdu
if (rlcP->vt_mrw < (rlcP->max_mrw - 1)) {
rlc_am_schedule_procedure (rlcP);
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM %p][DISCARD] NOTIF MRW_ACK TIME OUT REARM TIMER\n", rlcP);
#endif
rlcP->vt_mrw += 1;
} else {
// TO DO : "deliver an error indication to upper layers"
#ifdef DEBUG_RESET
msg ("\n[RLC_AM][RB %d][DISCARD] NOTIF MRW_ACK TIME OUT MAX_MRW REACHED -> RESET\n", rlcP->rb_id);
#endif
send_reset_pdu (rlcP);
}
}
}
// handler for timer
//-----------------------------------------------------------------------------
void
rlc_am_discard_check_sdu_time_out (struct rlc_am_entity* rlcP)
{
//-----------------------------------------------------------------------------
mem_block_t* sdu;
mem_block_t* pdu;
int discard_go_on;
int last_removed_pdu_sn;
int sn;
// TIMER BASED DISCARD
if ((rlcP->sdu_discard_mode & RLC_SDU_DISCARD_TIMER_BASED_EXPLICIT)
&& ((rlcP->protocol_state & (RLC_RESET_PENDING_STATE | RLC_RESET_AND_SUSPEND_STATE)) == 0)) {
/* from 3GPP TS 25.322 V5.0.0 p68
- if "Timer based SDU discard with explicit signalling" is configured:
- discard all SDUs up to and including the SDU for which the timer Timer_Discard expired.
- discard all AMD PDUs including segments of the discarded SDUs, unless they also carry a segment of a SDU
whose timer has not expired;
- if more than 15 discarded SDUs are to be informed to the Receiver:
- if "Send MRW" is not configured:
- assemble an MRW SUFI with the discard information of the SDUs.
- otherwise ("Send MRW" is configured):
- assemble an MRW SUFI with the discard information of the first 15 SDUs; and
- include the discard information of the rest SDUs in another MRW SUFI which shall be sent by the next
SDU discard with explicit signalling procedure (after the current SDU discard with explicit signalling
procedure is terminated).
- otherwise (less than or equal to 15 discarded SDUs are to be informed to the Receiver):
- assemble an MRW SUFI with the discard information of the SDUs.
- schedule and submit to lower layer a STATUS PDU/piggybacked STATUS PDU containing the MRW SUFI;
- if SN_MRWLENGTH in the MRW SUFI >VT(S):
- update VT(S) to SN_MRWLENGTH.
- start a timer Timer_MRW
If a new SDU discard with explicit signalling procedure is triggered when the timer Timer_MRW is active, no new
MRW SUFIs shall be sent before the current SDU discard with explicit signalling procedure is terminated by one of the
termination criteria.
*/
discard_go_on = 1;
last_removed_pdu_sn = -1;
while ((sdu = rlcP->input_sdus[rlcP->current_sdu_index]) && discard_go_on) {
if ((*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_creation_time) >= rlcP->timer_discard_init) {
// buffer occupancy is not updated at each generation of pdu, it is only updated for a sdu when the
// segmentation of this one is finished.
rlcP->buffer_occupancy -= ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_remaining_size;
rlcP->nb_sdu -= 1;
if ((rlcP->send_mrw & RLC_AM_SEND_MRW_ON) ||
// the condition says if the sdu has generated one or more pdus
(((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_size != ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_remaining_size)) {
((struct rlc_am_tx_sdu_management*) (sdu->data))->last_pdu_sn = rlcP->vt_s;
((struct rlc_am_tx_sdu_management*) (sdu->data))->no_new_sdu_segmented_in_last_pdu = 1;
rlcP->vt_s = (rlcP->vt_s + 1) & SN_12BITS_MASK;
list2_add_tail (sdu, &rlcP->sdu_discarded);
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] SDU DISCARDED SIGNALLING YES, TIMED OUT %ld ms frame %d ", rlcP->rb_id,
(*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_creation_time), Mac_rlc_xface->frame);
msg ("BO %d, NB SDU %d\n", rlcP->buffer_occupancy, rlcP->nb_sdu);
display_protocol_vars_rlc_am (rlcP);
#endif
if (((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_size != ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_remaining_size) {
// some pdu have to be removed if a sdu discarded generated almost one pdu
if (last_removed_pdu_sn == -1) {
sn = rlcP->vt_a;
} else {
sn = last_removed_pdu_sn;
}
while (sn != rlcP->vt_s) {
pdu = rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size];
if ((pdu)) {
// now check if a copy of the pdu is not present in the retransmission_buffer_to_send
if ((((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy)) {
list2_remove_element (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy, &rlcP->retransmission_buffer_to_send);
free_mem_block (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->copy);
}
// if this pdu has been retransmitted, remove its size from buffer occupancy
if (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->vt_dat > 0) {
rlcP->buffer_occupancy_retransmission_buffer -= 1;
}
free_mem_block (rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size]);
rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size] = NULL;
}
sn = (sn + 1) & SN_12BITS_MASK;
}
last_removed_pdu_sn = sn;
}
} else {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] SDU DISCARDED SIGNALLING NO, TIMED OUT %ld ms ", rlcP->rb_id,
(*rlcP->frame_tick_milliseconds - ((struct rlc_am_tx_sdu_management*) (sdu->data))->sdu_creation_time));
msg ("BO %d, NB SDU %d\n", rlcP->buffer_occupancy, rlcP->nb_sdu);
#endif
free_mem_block (sdu);
}
if (!(rlcP->data_plane)) {
#ifdef DEBUG_RLC_AM_SEND_CONFIRM
msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d LOST IN DISCARD\n", rlcP->rb_id,
((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->mui);
#endif
rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[rlcP->current_sdu_index]->data))->mui, RLC_TX_CONFIRM_FAILURE,
rlcP->data_plane);
}
rlcP->input_sdus[rlcP->current_sdu_index] = NULL;
rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % rlcP->size_input_sdus_buffer;
// reset variables for segmentation
rlcP->li_exactly_filled_to_add_in_next_pdu = 0;
rlcP->li_one_byte_short_to_add_in_next_pdu = 0;
} else {
discard_go_on = 0;
}
}
}
}
//-----------------------------------------------------------------------------
void
rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity* rlcP, mem_block_t* pduP)
{
//-----------------------------------------------------------------------------
struct rlc_am_tx_data_pdu_management* pdu_mngt;
struct rlc_am_tx_sdu_management* sdu_mngt;
mem_block_t* pdu;
mem_block_t* pdu2;
mem_block_t* sdu;
int sdu_index;
int sdu_index2;
int pdu_index;
int last_sdu_index;
int sn;
pdu_mngt = (struct rlc_am_tx_data_pdu_management*) pduP->data;
// should never occur
//if (pdu_mngt->nb_sdu == 0) return;
// discard previous SDUS
#ifdef DEBUG_RLC_AM_DISCARD_MAX_DAT
msg ("[RLC_AM][RB %d] DISCARD MAX DAT PDU FRAME %d SN 0x%03X CONTAINS SDU INDEX ", rlcP->rb_id, Mac_rlc_xface->frame, pdu_mngt->sn);
sdu_index = 0;
while (sdu_index < pdu_mngt->nb_sdu) {
msg ("%d ", pdu_mngt->sdu[sdu_index]);
sdu_index += 1;
}
msg ("\n");
#endif
// From 3GPP TS25.322 V5.0.0 (2002-03) page 68
// - if "SDU discard after MaxDAT number of retransmissions" is configured:
// - discard all SDUs that have segments in AMD PDUs with SN inside the interval
// VT(A) <= SN <= X, where X is the value of the SN of the AMD PDU with VT(DAT) >= MaxDAT;
// - if requested
// - inform the upper layers of the discarded SDUs.
//---------------------------------------------------------------
// here delete all SDUs before the last sdu that have segments in the pdu discarded
sdu_index = rlcP->next_sdu_index;
last_sdu_index = pdu_mngt->sdu[pdu_mngt->nb_sdu - 1];
while (sdu_index != last_sdu_index) {
if ((sdu = rlcP->input_sdus[sdu_index])) {
list2_add_tail (sdu, &rlcP->sdu_discarded);
if (!(rlcP->data_plane)) {
#ifdef DEBUG_RLC_AM_SEND_CONFIRM
msg ("[RLC_AM][RB %d][CONFIRM] SDU MUI %d LOST IN DISCARD\n", rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->mui);
#endif
rlc_data_conf (0, rlcP->rb_id, ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->mui, RLC_TX_CONFIRM_FAILURE, rlcP->data_plane);
}
rlcP->input_sdus[sdu_index] = NULL;
rlcP->nb_sdu -= 1;
#ifdef DEBUG_RLC_AM_FREE_SDU
msg ("[RLC_AM][RB %d] DISCARD MAX DAT FREE_SDU INDEX %d\n", rlcP->rb_id, sdu_index);
#endif
}
sdu_index = (sdu_index + 1) % rlcP->size_input_sdus_buffer;
}
//---------------------------------------------------------------
// here delete all PDUs up to and except the last of the last sdu discarded
sdu = rlcP->input_sdus[sdu_index];
sdu_mngt = (struct rlc_am_tx_sdu_management*) (sdu->data);
sn = rlcP->vt_a;
while (sn != sdu_mngt->last_pdu_sn) {
if ((pdu2 = rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size])) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD FREE PDU SN 0x%03X\n", rlcP->rb_id, sn);
#endif
// check if a copy of the pdu is not present in the retransmission_buffer_to_send
if ((((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->copy)) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] FREE PDU COPY ALSO\n", rlcP->rb_id);
#endif
list2_remove_element (((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->copy, &rlcP->retransmission_buffer_to_send);
free_mem_block (((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->copy);
}
// if this pdu has been retransmitted, remove its size from buffer occupancy
if (((struct rlc_am_tx_data_pdu_management*) (pdu2->data))->vt_dat > 0) {
rlcP->buffer_occupancy_retransmission_buffer -= 1;
}
free_mem_block (pdu2);
rlcP->retransmission_buffer[sn % rlcP->recomputed_configured_tx_window_size] = NULL;
}
sn = (sn + 1) & SN_12BITS_MASK;
}
//----------------------------------------------
// Now for the last pdu of the last sdu discarded, check if it contains other segments of
// sdu newer than the discarded
// if the pdu cannot be found : it is OK, nothing to do
pdu = rlcP->retransmission_buffer[sdu_mngt->last_pdu_sn % rlcP->recomputed_configured_tx_window_size];
if ((pdu)) {
// search the index of the sdu passed in parameter
pdu_mngt = (struct rlc_am_tx_data_pdu_management*) pdu->data;
if (pdu_mngt->sdu[pdu_mngt->nb_sdu - 1] == sdu_index) {
//----------------------------------------------
// now check if a copy of the pdu is not present in the retransmission_buffer_to_send
if ((pdu_mngt->copy)) {
list2_remove_element (pdu_mngt->copy, &rlcP->retransmission_buffer_to_send);
free_mem_block (pdu_mngt->copy);
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X\n", rlcP->rb_id, sn);
rlc_am_display_data_pdu7 (pdu);
#endif
//----------------
// discard the pdu
// if this pdu has been retransmitted, remove its size from buffer occupancy
if (((struct rlc_am_tx_data_pdu_management*) (pdu->data))->vt_dat > 0) {
rlcP->buffer_occupancy_retransmission_buffer -= 1;
}
pdu_index = pdu_mngt->sn % rlcP->recomputed_configured_tx_window_size;
free_mem_block (rlcP->retransmission_buffer[pdu_index]);
rlcP->retransmission_buffer[pdu_index] = NULL;
} else {
// if this pdu is not discarded, mark the sdu discarded by writing "-1" for their index : used in retransmission
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, CONTAINS OTHER SDUS (LAST SDU INDEX=%d): NOT CLEARED\n", rlcP->rb_id, sdu_mngt->last_pdu_sn,
pdu_mngt->sdu[pdu_mngt->nb_sdu - 1]);
#endif
sdu_index2 = 0;
while (pdu_mngt->sdu[sdu_index2] != sdu_index) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, MARK SDU index % AS DISCARDED\n", rlcP->rb_id, pdu_mngt->sn, pdu_mngt->sdu[sdu_index2]);
#endif
pdu_mngt->sdu[sdu_index2] = -1;
sdu_index2 += 1;
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, MARK SDU index %d AS DISCARDED\n", rlcP->rb_id, pdu_mngt->sn, pdu_mngt->sdu[sdu_index2]);
#endif
pdu_mngt->sdu[sdu_index2] = -1;
}
}
#ifdef DEBUG_RLC_AM_DISCARD
else {
msg ("[RLC_AM][RB %d] DISCARD LAST PDU SN 0x%03X, ALREADY CLEARED\n", rlcP->rb_id, sdu_mngt->last_pdu_sn);
}
#endif
//----------------
// discard the sdu
if ((rlcP->input_sdus[sdu_index])) { // may be removed by "free_retransmission_buffer_no_confirmation"
if (sdu_index == rlcP->current_sdu_index) {
// sdu under segmentation
rlcP->buffer_occupancy -= ((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->sdu_remaining_size;
((struct rlc_am_tx_sdu_management*) (rlcP->input_sdus[sdu_index]->data))->no_new_sdu_segmented_in_last_pdu = 1;
rlcP->li_exactly_filled_to_add_in_next_pdu = 0;
rlcP->li_one_byte_short_to_add_in_next_pdu = 0;
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD THE SDU DISCARDED WAS UNDER SEGMENTATION (index %d)\n", rlcP->rb_id, sdu_index);
#endif
}
list2_add_tail (rlcP->input_sdus[sdu_index], &rlcP->sdu_discarded);
#ifdef DEBUG_RLC_AM_FREE_SDU
msg ("[RLC_AM][RB %d] DISCARD MAX DAT FREE_SDU INDEX %d\n", rlcP - rb_id, sdu_index);
#endif
rlcP->input_sdus[sdu_index] = NULL;
rlcP->nb_sdu -= 1;
}
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_notif_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_DISCARD_NOTIF_PROTO_EXTERN_H__
# define __RLC_AM_DISCARD_NOTIF_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "rlc_am_structs.h"
# include "rlc_am_constants.h"
# include "mem_block.h"
//-----------------------------------------------------------------------------
extern void rlc_am_discard_notify_mrw_ack_time_out (struct rlc_am_entity *rlcP, mem_block_t * discard_procedureP);
extern void rlc_am_discard_check_sdu_time_out (struct rlc_am_entity *rlcP);
extern void rlc_am_discard_notify_max_dat_pdu (struct rlc_am_entity *rlcP, mem_block_t * pduP);
# endif
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_rx_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_DISCARD_RX_PROTO_EXTERN_H__
# define __RLC_AM_DISCARD_RX_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "mem_block.h"
//-----------------------------------------------------------------------------
extern void rlc_am_received_sufi_ack_check_discard_procedures (struct rlc_am_entity *rlcP);
extern void rlc_am_free_discard_procedure (mem_block_t * mb_current_procedureP);
extern inline void rlc_am_discard_free_receiver_buffer (struct rlc_am_entity *rlcP, uint16_t sn_mrw_iP, uint8_t nlengthP);
extern uint8_t *retransmission_buffer_management_mrw (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP);
extern uint8_t *retransmission_buffer_management_mrw_ack (struct rlc_am_entity *rlcP, uint8_t * byte1P, uint8_t * byte_alignedP);
# endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_tx.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "rlc_am_discard_notif_proto_extern.h"
#include "rlc_am_discard_rx_proto_extern.h"
#include "rlc_primitives.h"
#include "rlc_am_status_proto_extern.h"
#include "rlc_am_util_proto_extern.h"
#include "rlc_am_constants.h"
#include "rlc_am_structs.h"
#include "umts_timer_proto_extern.h"
//-----------------------------------------------------------------------------
void rlc_am_schedule_procedure (struct rlc_am_entity* rlcP);
void rlc_am_process_sdu_discarded (struct rlc_am_entity* rlcP);
void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (struct rlc_am_entity* rlcP);
void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (struct rlc_am_entity* rlcP);
//-----------------------------------------------------------------------------
void
rlc_am_schedule_procedure (struct rlc_am_entity* rlcP)
{
//-----------------------------------------------------------------------------
mem_block_t* pdu_status;
struct rlc_am_discard_procedure* procedure;
// if a procedure is running do nothing
if (!(rlcP->timer_mrw) && (rlcP->discard_procedures.head)) {
// launch remaining procedures (only 1 procedure running)
procedure = (struct rlc_am_discard_procedure*) ((rlcP->discard_procedures.head)->data);
/* sn_mrw_length = procedure->last_pdu_sn;
if (rlc_am_comp_sn(rlcP, rlcP->vt_s, sn_mrw_length, rlcP->vt_s) > 0) {
#ifdef DEBUG_RLC_AM_DISCARD
msg("[RLC_AM %p][DISCARD] SCHEDULE PROCEDURE %p UPDATE VT(S) %04X -> %04X\n", rlcP, rlcP->discard_procedures.head, rlcP->vt_s, sn_mrw_length);
#endif
rlcP->vt_s = sn_mrw_length;
}
*/
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD SCHEDULE PROCEDURE %p vt_s 0x%04X vt_a 0x%04X\n", rlcP->rb_id, rlcP->discard_procedures.head, rlcP->vt_s, rlcP->vt_a);
#endif
procedure->running = 0xFF;
pdu_status = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE);
memcpy (pdu_status->data, procedure->control_pdu->data, rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation));
list_add_tail_eurecom (pdu_status, &rlcP->control);
}
}
//-----------------------------------------------------------------------------
void
rlc_am_process_sdu_discarded (struct rlc_am_entity* rlcP)
{
//-----------------------------------------------------------------------------
// We assume that the list sdu_discarded contains sdu(s)
/* From 3GPP TS 25.322 V4.3.0 (2001-12)
The Sender shall initiate the SDU discard with explicit signalling procedure if one of the
following triggers is detected:
- "Timer based SDU discard with explicit signalling" is configured, Timer_Discard expires
for an SDU, and one or more segments of the SDU have been submitted to a lower layer;
- "Timer based SDU discard with explicit signalling" is configured, Timer_Discard expires
for an SDU, and Send MRW is configured;
- "SDU discard after MaxDAT number of transmissions" is configured, and MaxDAT number of
transmissions is reached (i.e. VT(DAT) � MaxDAT) for an AMD PDU.
*/
// discard procedure
if ((rlcP->send_mrw & RLC_AM_SEND_MRW_ON)) {
rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (rlcP);
} else { // RLC_AM_SEND_MRW_OFF
rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (rlcP);
}
rlc_am_schedule_procedure (rlcP);
}
//-----------------------------------------------------------------------------
void
rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (struct rlc_am_entity* rlcP)
{
//-----------------------------------------------------------------------------
/* From 3GPP TS 25.322 V5.0.0 (2002-03)
The Sender shall:
- if "Send MRW" is configured:
- if the last discarded SDU ended in an AMD PDU, and its "Length Indicator" is present in the same AMD
PDU, and no new SDU is present inside this AMD PDU:
- set the last SN_MRWi field in the MRW SUFI to 1 + "Sequence Number" of the AMD PDU which
contains the "Length Indicator" of the last discarded SDU;
- set the NLENGTH field in the MRW SUFI to "0000".
- otherwise:
- set the last SN_MRWi field in the MRW SUFI to the "Sequence Number" of the AMD PDU which
contains the "Length Indicator" of the last discarded SDU;
- set the NLENGTH field in the MRW SUFI so that the last data octet to be discarded in the Receiver shall be
the octet indicated by the NLENGTH:th "Length Indicator" field of the AMD PDU which contains the
"Length Indicator" of the last discarded SDU;
- set each of the other SN_MRWi fields in the MRW SUFI to the "Sequence Number" of the AMD PDU which
contains the "Length Indicator" of the i:th discarded SDU.
- if the MRW SUFI contains only one SN_MRWi field and the value of SN_MRWi field
VT(A)+Configured_Tx_Window_Size:
- set the LENGTH field in the MRW SUFI to "0000".
- otherwise:
- set the LENGTH field in the MRW SUFI to the number of SN_MRWi fields in the same MRW SUFI. In this
case, SN_MRW1 shall be in the interval VT(A) SN_MRW1 < VT(A)+Configured_Tx_Window_Size.
*/
mem_block_t* mb_discard_procedure = NULL;
mem_block_t* sdu_discarded;
struct rlc_am_tx_sdu_management* last_sdu_discarded_mngt;
mem_block_t* le;
struct rlc_am_status_header* pdu;
uint8_t* p8;
int last_sn_mrw_length;
uint8_t count_sdu_discarded;
uint8_t byte_aligned;
#ifdef DEBUG_RLC_AM_DISCARD
uint16_t sn_mrw_length;
#endif
while (rlcP->sdu_discarded.head) {
// alloc a discard procedure
mb_discard_procedure = get_free_mem_block (sizeof (struct rlc_am_discard_procedure));
memset (mb_discard_procedure->data, 0, sizeof (struct rlc_am_discard_procedure));
list_init (&((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list, NULL);
count_sdu_discarded = 0;
// assign sdu discarded to discard procedure
// sdu headers are registered in discard procedure
last_sn_mrw_length = -1;
while ((rlcP->sdu_discarded.head) && (count_sdu_discarded < 15)) { // max 15 sdu discarded per procedure
sdu_discarded = list2_remove_head (&rlcP->sdu_discarded);
// this test is done to avoid signalling n times the same SN_MRW_length if a pdu contains n sdu
// so it can save some discard procedures.
if (last_sn_mrw_length != ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD IN PROCEDURE %p ADD SDU SN_MRWlength 0x%03X\n", rlcP->rb_id, mb_discard_procedure,
((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn);
#endif
list_add_tail_eurecom (sdu_discarded, &((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list);
last_sn_mrw_length = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn;
count_sdu_discarded += 1;
} else {
free_mem_block (sdu_discarded);
}
}
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->length = count_sdu_discarded;
//((struct rlc_am_discard_procedure*)(mb_discard_procedure->data))->nlength = ((struct rlc_am_sdu_discard_management*)((mem_block_t*)(sdu_header_copy_copy->data))->data)->li_index_for_discard;
last_sdu_discarded_mngt = (struct rlc_am_tx_sdu_management*) (sdu_discarded->data);
if ((last_sdu_discarded_mngt->no_new_sdu_segmented_in_last_pdu)) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD NO NEW SDU SEGMENTED IN LAST PDU DISCARDED\n", rlcP->rb_id);
#endif
last_sdu_discarded_mngt->last_pdu_sn = (last_sdu_discarded_mngt->last_pdu_sn + 1) & SN_12BITS_MASK;
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = 0;
} else {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD OTHER SDU(s) SEGMENTED IN LAST PDU DISCARDED\n", rlcP->rb_id);
#endif
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = last_sdu_discarded_mngt->li_index_for_discard +
1; // +1 since numerotation begins at 1
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD SET SN_MRW_LENGTH 0x%04X NLENGTH = %d \n", rlcP->rb_id, last_sdu_discarded_mngt->last_pdu_sn,
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength);
sn_mrw_length = last_sdu_discarded_mngt->last_pdu_sn;
#endif
// make status pdu
le = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE);
if (le == NULL) {
// be carefull : lost resources in mb_discard : TO DO
msg ("[RLC_AM][RB %d] FATAL ERROR : OUT OF MEMORY\n", rlcP->rb_id);
return;
} else {
((struct rlc_am_tx_control_pdu_management*) (le->data))->rlc_tb_type = RLC_AM_MRW_STATUS_PDU_TYPE;
pdu = (struct rlc_am_status_header*) (&le->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]);
pdu->byte1 = RLC_PDU_TYPE_STATUS;
p8 = &(pdu->byte1);
*p8 = *p8 | RLC_AM_SUFI_MRW;
p8 = p8 + 1;
// fill field LENGTH
*p8 = (count_sdu_discarded << 4);
byte_aligned = 0;
// fill fields SN_MRWi
sdu_discarded = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list.head); // reuse of var sdu_discarded
while ((count_sdu_discarded)) {
count_sdu_discarded -= 1;
if (byte_aligned) {
*p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn >> 4;
p8 = p8 + 1;
*p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn << 4;
byte_aligned = 0;
} else {
//*p8 = 0 << 4 | (temp_sn >> 8);
*p8 |= (((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn >> 8);
p8 = p8 + 1;
*p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn;
p8 = p8 + 1;
byte_aligned = 1;
}
sdu_discarded = sdu_discarded->next;
}
// fill field Nlength
if (byte_aligned) {
*p8 = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength << 4) | RLC_AM_SUFI_NO_MORE;
} else {
*p8 |= (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength);
p8 = p8 + 1;
*p8 = (RLC_AM_SUFI_NO_MORE << 4);
}
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->control_pdu = le;
list2_add_tail (mb_discard_procedure, &rlcP->discard_procedures);
}
}
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD QUEUED NEW PROCEDURE SEND_MRW IS CONFIGURED SN_MRW_length = 0x%04X length %d nlength %d\n",
rlcP->rb_id, sn_mrw_length, ((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->length,
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength);
#endif
}
//-----------------------------------------------------------------------------
void
rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (struct rlc_am_entity* rlcP)
{
//-----------------------------------------------------------------------------
/* From 3GPP TS 25.322 V5.0.0 (2002-03)
The Sender shall:
- if "Send MRW" is NOT configured:
- if the last SDU to be discarded in the Receiver ended in an AMD PDU, and its "Length Indicator" is present
in the same AMD PDU, and no new SDU is present inside this AMD PDU:
- set the last SN_MRWi field in the MRW SUFI to 1 + "Sequence Number" of the AMD PDU which
contains the "Length Indicator" of the last SDU to be discarded in the Receiver;
- set the NLENGTH field in the MRW SUFI to "0000".
- otherwise:
- set the last SN_MRWi field in the MRW SUFI to the "Sequence Number" of the AMD PDU which
contains the "Length Indicator" of the last SDU to be discarded in the Receiver;
- set the NLENGTH field in the MRW SUFI so that the last data octet to be discarded in the Receiver shall be
the octet indicated by the NLENGTH:th "Length Indicator" field of the AMD PDU which contains the
"Length Indicator" of the last SDU to be discarded in the Receiver;
- optionally set each of the other SN_MRWi fields in the MRW SUFI to the "Sequence Number" of the AMD
PDU which contains the "Length Indicator" of the i:th SDU to be discarded in the Receiver;
- if the MRW SUFI contains only one SN_MRWi field and the value of SN_MRWi field
VT(A)+Configured_Tx_Window_Size:
- set the LENGTH field in the MRW SUFI to "0000".
- otherwise:
- set the LENGTH field in the MRW SUFI to the number of SN_MRWi fields in the same MRW SUFI. In this
case, SN_MRW1 shall be in the interval VT(A) SN_MRW1 < VT(A)+Configured_Tx_Window_Size.
*/
mem_block_t* mb_discard_procedure = NULL;
mem_block_t* sdu_discarded;
struct rlc_am_tx_sdu_management* last_sdu_discarded_mngt;
mem_block_t* le;
struct rlc_am_status_header* pdu;
int last_sn_mrw_length;
uint8_t* p8;
uint8_t count_sdu_discarded;
uint8_t byte_aligned;
#ifdef DEBUG_RLC_AM_DISCARD
uint16_t sn_mrw_length;
#endif
while (rlcP->sdu_discarded.head) {
// alloc a discard procedure
mb_discard_procedure = get_free_mem_block (sizeof (struct rlc_am_discard_procedure));
memset (mb_discard_procedure->data, 0, sizeof (struct rlc_am_discard_procedure));
list_init (&((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list, NULL);
count_sdu_discarded = 0;
// assign sdu discarded to discard procedure
// sdu headers are registered in discard procedure
last_sn_mrw_length = -1;
while ((rlcP->sdu_discarded.head) && (count_sdu_discarded < 15)) { // max 15 sdu discarded per procedure
sdu_discarded = list2_remove_head (&rlcP->sdu_discarded);
// this test is done to avoid signalling n times the same SN_MRW_length if a pdu contains n sdu
// so it can save some discard procedures.
if (last_sn_mrw_length != ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn) {
#ifdef DEBUG_RLC_AM_DISCARD
msg ("[RLC_AM][RB %d] DISCARD IN PROCEDURE %p ADD SDU SN_MRWlength %03X hex\n", rlcP->rb_id, mb_discard_procedure,
((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn);
#endif
list_add_tail_eurecom (sdu_discarded, &((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list);
last_sn_mrw_length = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn;
count_sdu_discarded = 1;
} else {
free_mem_block (sdu_discarded);
}
}
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->length = count_sdu_discarded;
//((struct rlc_am_discard_procedure*)(mb_discard_procedure->data))->nlength = ((struct rlc_am_sdu_discard_management*)((mem_block_t*)(sdu_header_copy_copy->data))->data)->li_index_for_discard;
last_sdu_discarded_mngt = (struct rlc_am_tx_sdu_management*) (sdu_discarded->data);
if ((last_sdu_discarded_mngt->no_new_sdu_segmented_in_last_pdu)) {
last_sdu_discarded_mngt->last_pdu_sn = (last_sdu_discarded_mngt->last_pdu_sn + 1) & SN_12BITS_MASK;
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = 0;
} else {
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength = last_sdu_discarded_mngt->li_index_for_discard;
}
#ifdef DEBUG_RLC_AM_DISCARD
sn_mrw_length = last_sdu_discarded_mngt->last_pdu_sn;
#endif
// make status pdu
if ((le = get_free_mem_block (rlcP->pdu_size + sizeof (struct rlc_am_tx_control_pdu_allocation) + GUARD_CRC_LIH_SIZE))) {
((struct rlc_am_tx_control_pdu_management*) (le->data))->rlc_tb_type = RLC_AM_MRW_STATUS_PDU_TYPE;
pdu = (struct rlc_am_status_header*) (&le->data[sizeof (struct rlc_am_tx_control_pdu_allocation)]);
pdu->byte1 = RLC_PDU_TYPE_STATUS;
p8 = &(pdu->byte1);
*p8 = *p8 | RLC_AM_SUFI_MRW;
p8 = p8 + 1;
// fill field LENGTH
*p8 = (count_sdu_discarded << 4);
byte_aligned = 0;
// fill fields SN_MRWi
sdu_discarded = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->sdu_list.head); // reuse of var sdu_discarded
//*p8 = 0 << 4 | (temp_sn >> 8);
*p8 |= (((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn >> 8);
p8 = p8 + 1;
*p8 = ((struct rlc_am_tx_sdu_management*) (sdu_discarded->data))->last_pdu_sn;
p8 = p8 + 1;
byte_aligned = 1;
// fill field Nlength
*p8 = (((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->nlength << 4) | RLC_AM_SUFI_NO_MORE;
((struct rlc_am_discard_procedure*) (mb_discard_procedure->data))->control_pdu = le;
list2_add_tail (mb_discard_procedure, &rlcP->discard_procedures);
} else {
// out of memory
return;
}
}
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_discard_tx_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_DISCARD_TX_PROTO_EXTERN_H__
# define __RLC_AM_DISCARD_TX_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "rlc_am_entity.h"
# include "rlc_am_structs.h"
# include "mem_block.h"
//-----------------------------------------------------------------------------
extern void rlc_am_schedule_procedure (struct rlc_am_entity *rlcP);
extern void rlc_am_process_sdu_discarded (struct rlc_am_entity *rlcP);
extern void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_configured (struct rlc_am_entity *rlcP);
extern void rlc_am_sdu_discard_with_explicit_signalling_procedure_send_mrw_not_configured (struct rlc_am_entity *rlcP);
# endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_entity.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_ENTITY_H__
# define __RLC_AM_ENTITY_H__
//-----------------------------------------------------------------------------
# include "mem_block.h"
# include "rlc_am_structs.h"
# include "rlc_def.h"
# include "platform_types.h"
# include "platform_constants.h"
//-----------------------------------------------------------------------------
struct rlc_am_entity {
module_id_t module_id;
// for stats and trace purpose :
uint16_t data_plane; // act as a boolean
uint16_t rb_id;
//-----------------------------
// polling info
//-----------------------------
uint16_t poll_pdu_trigger;
uint16_t poll_sdu_trigger;
uint16_t timer_poll_trigger;
uint16_t timer_poll_prohibit_trigger;
uint8_t last_transmission_pdu_poll_trigger;
uint8_t last_retransmission_pdu_poll_trigger;
uint8_t poll_window_trigger;
//-----------------------------
// timers
//-----------------------------
list2_t rlc_am_timer_list;
//uint16_t timer_poll;
//uint16_t timer_poll_prohibit;
uint16_t timer_poll_periodic;
//uint16_t timer_status_prohibit;
uint16_t timer_status_periodic;
signed int timer_status_prohibit;
signed int running_timer_status_prohibit;
mem_block_t *timer_rst;
uint16_t time_out_events;
mem_block_t *timer_mrw; // if NULL : no timer is running
//uint8_t timer_mrw_is_running;
uint8_t max_mrw;
//uint16_t timer_poll_init;
//uint16_t timer_poll_prohibit_init;
//uint16_t timer_epc_init;
uint16_t timer_discard_init;
uint16_t timer_poll_periodic_init;
//uint16_t timer_status_prohibit_init;
//uint16_t timer_status_periodic_init;
uint16_t timer_rst_init;
uint16_t timer_mrw_init;
uint32_t transmitted_pdu_types;
int last_tx_status_frame;
uint32_t *frame_tick_milliseconds; // pointer on this tick variable handled by RRC : READ ONLY
uint8_t missing_pdu_indicator;
//-----------------------------
// tranmission
//-----------------------------
//struct cnt_dbl_lk_list_up segmentation_buffer; // output of segmentation/concatenation function
list2_t sdu_conf_segmented; // contain sdu_headers:sdu processed by the segmentation unit. (we keep them for confirm)
list2_t sdu_discard_segmented; // contain sdu_headers:sdu processed by the segmentation unit. (we keep them for discard)
list2_t sdu_discarded; // contain sdu_headers
list2_t discard_procedures; // contain procedures (struct rlc_am_discard_procedure)
//struct cnt_dbl_lk_list_up transmission_buffer; // output of mux module
//uint16_t data_pdu_size;
//uint16_t control_pdu_size;
//struct cnt_list_up dcch_pdus_to_mac_layer;
//struct cnt_list_up dtch_pdus_to_mac_layer;
//struct list_up dcch_pdus_from_mac_layer;
//struct list_up dtch_pdus_from_mac_layer;
// implementation specific: our transmiter buffer is an array whose size must be a power of 2
# define RLC_AM_DISCARD_REASSEMBLY_AT_LI_INDEX_0 0x00
uint8_t discard_reassembly_after_li; // when received mrw sufi
uint16_t discard_reassembly_start_sn;
//-----------------------------
// management of received PDU for piggybacked status PDU and status PDU
//-----------------------------
struct sufi_to_insert_in_status status_in_construction[NB_MAX_SUFI];
struct sufi_ack ack;
uint8_t sufi_to_insert_index;
//-----------------------------
// Reset
//-----------------------------
uint8_t send_status_pdu_requested;
uint8_t reset_sequence_number;
uint8_t last_received_rsn;
uint8_t max_rst;
//-----------------------------
// Mapping info
//-----------------------------
uint8_t dcch_logical_channel_identity;
uint8_t dtch_logical_channel_identity;
uint8_t nb_logical_channels_per_rlc;
//-----------------------------
// buffer occupancy measurements sent to MAC
//-----------------------------
// note occupancy of other buffers is deducted from nb elements in lists
uint32_t buffer_occupancy_retransmission_buffer; // nb of pdus
//**************************************************************
// new members
//**************************************************************
uint8_t allocation;
uint8_t location; // UTRAN/UE
uint8_t protocol_state;
//-----------------------------
// protocol variables
//-----------------------------
uint16_t first_li_in_next_pdu; // indicates :
// value = 000000000000000 that the previous PDU was exactly
// with the last segment of an RLC SDU and there is no LI that
// indicates the end of the SDU in the previous RLC PDU.
// value = 111111111111011 The last segment of an RLC SDU was one octet
// short of exactly filling the previous RLC PDU and there is no LI that
// indicates the end of the SDU in the previous RLC PDU. The remaining one
// octet in the previous RLC PDU is ignored.
// value = 111111111111110 AMD PDU: The rest of the RLC PDU includes a
// piggybacked STATUS PDU.
// value = 111111111111111 The rest of the RLC PDU is padding. The padding
// length can be zero.
uint16_t vt_s; // send state variable
// The sequence number of the next PDU to be transmitted for the
// first time(i.e. excluding retransmission). It is updated after
// transmission of a PDU, which includes not earlier transmitted
// PDUs and after transmission of a MRW SUFI which includes SN_MRW
// length > VT(S).
uint16_t vt_a; // Acknowledged state variable
// The sequence number of the next in sequence PDU expected to be
// acknowledged, which forms the lower edge of the window of acceptable
// acknowledgments. VT(A) is updated based on a receipt of a STATUS
// PDU including an ACK and/or MRW_ACK super field.
uint16_t max_dat; // This state variable counts the number of times a PDU has been transmited
// There is one vt(dat) for each PDU and it is incremented each time the pdu
// is transmited. The initial value of this variable is 0;
uint16_t vt_ms; // Maximun send state variable
// The sequence number of the first PDU not allowed by the receiver
// [the receiver will allow up to VT(MS)-1], VT(MS) = VT(A)+VT(WS).
// This value represents the upper edge of the transmit window. The
// transmitter shall not transmit a PDU with SN>=VT(MS). VT(MS) is
// updated when either VT(A) or VT(WS) is updated. The PDU with SN
// VT(S)-1 can be transmitted also when VT(S) >= VT(MS).
uint16_t vt_pdu; // not used
uint16_t vt_sdu; // this state variable is used when the poll every Poll_SDU SDU
// function is used. It is incremented with 1 each SDU is
// transmitted. When it reaches Poll_SDU a new poll is transmitted
// the state variable is set to 0. The poll bit should be set in the
// PDU that contains the last segment of the SDU.
uint16_t vt_rst; // Reset state variable
// it is used to count the number of times a RESET PDU is transmitted.
// vt(rst) is incremented with 1 each time a RESET PDU is transmitted. VT(rst) is
// reset only upon the reception of a RESET ACK PDU, i.e. VT(RST) is not reset when
// an RLC RESET occurs which was initiated from the peer RLC entity. The initial value
// of this variable is 0.
uint16_t vt_mrw; // MRW command send state variable
// It is used to count the number of times a MRW command is transmitted.
// VT(MRW) is reset when the discard procedure is terminated.
uint16_t vt_ws; // transmitter window size state variable
// The size that should be used for the transmitter window. VT(WS)
//is set equal to the WSN field when the transmitter receives a
// STATUS PDU including a WindowSize super-field.
uint16_t vr_r; // Receive state variable
// The sequence number of the next in sequence PDU expected to be
// received. It is equal to SNmax+1 upon receipt of the next in
// sequence PDU, where SNmax is the sequence number of the highest
// received in sequence PDU. The initial value of this variable is 0
uint16_t vr_h; // Highest expected state variable
// The sequence number of the highest expected PDU. this state
// variable is set equal to SN+1 only when a new PDU is received
// with VR(MR)>SN>=VR(H). The initial value of this variable is 0.
uint16_t vr_mr; // Maximum acceptable Receive state variable
// The sequence number of the first PDU not allowed by the receiver.
// It shall be set equal to SN+1 upon reception of a PDU. The
// initial value of this variable is 0.
int16_t vr_ep; // Estimated PDU counter state variable
// The number of PDUs that should be received yet as a consequence
// of the transmission of the latest status report. In acknowledged
// mode, this state variable is updated at the end of each TTI. It
// is decremented by the number of PDUs that should have been
// received during the TTI. If VR(EP) is equal to 0, then check if
// all PDUs requested for retransmission in the latest status report
// have been received.
//-----------------------------
// C-SAP
//-----------------------------
list_t c_sap;
//-----------------------------
// discard
//-----------------------------
uint8_t sdu_discard_mode;
uint8_t send_mrw;
//-----------------------------
// tranmission
//-----------------------------
mem_block_t **input_sdus; // should be accessed as an array
mem_block_t *input_sdus_alloc; // allocation of the array
uint16_t size_input_sdus_buffer;
uint16_t nb_sdu;
uint16_t next_sdu_index; // next location of incoming sdu
uint16_t current_sdu_index;
uint32_t buffer_occupancy;
// for segmentation procedures (optimization save space on stack)
uint16_t li[RLC_AM_SEGMENT_NB_MAX_LI_PER_PDU];
uint16_t configured_tx_window_size;
// implementation specific: our transmiter buffer is an array whose size must be a power of 2
uint16_t recomputed_configured_tx_window_size;
mem_block_t *(*rlc_segment) (struct rlc_am_entity * rlcP);
mem_block_t *retransmission_buffer_alloc;
mem_block_t **retransmission_buffer;
list2_t retransmission_buffer_to_send; // contains PDUs that must be immediatly retransmitted
list_t control; // contains control pdus
uint16_t nb_pdu_requested_by_mac_on_ch1;
uint16_t nb_pdu_requested_by_mac_on_ch2;
uint16_t pdu_size;
uint8_t li_one_byte_short_to_add_in_next_pdu;
uint8_t li_exactly_filled_to_add_in_next_pdu;
list_t pdus_to_mac_layer_ch1;
list_t pdus_to_mac_layer_ch2;
//-----------------------------
// receiver
//-----------------------------
sdu_size_t output_sdu_size_to_write;
mem_block_t *output_sdu_in_construction;
mem_block_t *receiver_buffer_alloc;
mem_block_t **receiver_buffer;
uint16_t last_reassemblied_sn;
uint16_t configured_rx_window_size;
uint16_t recomputed_configured_rx_window_size;
list_t pdus_from_mac_layer_ch1;
list_t pdus_from_mac_layer_ch2;
//-----------------------------
// status generation
//-----------------------------
mem_block_t *holes_alloc;
struct rlc_am_hole *holes;
uint16_t nb_missing_pdus;
uint16_t ack_sn;
uint16_t nb_holes;
# ifdef BYPASS_L1
unsigned int pdu_counter;
# endif
unsigned int stat_tx_pdcp_sdu;
unsigned int stat_tx_pdcp_sdu_discarded;
unsigned int stat_tx_retransmit_pdu_unblock;
unsigned int stat_tx_retransmit_pdu_by_status;
unsigned int stat_tx_retransmit_pdu;
unsigned int stat_tx_data_pdu;
unsigned int stat_tx_control_pdu;
unsigned int stat_rx_sdu;
unsigned int stat_rx_error_pdu;
unsigned int stat_rx_data_pdu;
unsigned int stat_rx_data_pdu_out_of_window;
unsigned int stat_rx_control_pdu;
};
# endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
# ifndef __RLC_AM_ERRNO_H__
# define __RLC_AM_ERRNO_H__
# endif
# define RLC_AM_OUT_OF_MEMORY_ERROR 1
# define RLC_AM_VT_S_OVERFLOW_ERROR 2
# define RLC_AM_RETRANS_REQ_PDU_NULL 3
# define RLC_AM_RETRANS_REQ_PDU_DONE_BEFORE 4
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_fsm.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "rlc_am_entity.h"
#include "rlc_am_constants.h"
#include "rlc_def.h"
#include "LAYER2/MAC/extern.h"
//-----------------------------------------------------------------------------
int
rlc_am_fsm_notify_event (struct rlc_am_entity* rlcP, uint8_t eventP)
{
//-----------------------------------------------------------------------------
switch (rlcP->protocol_state) {
//-------------------------------
// RLC_NULL_STATE
//-------------------------------
case RLC_NULL_STATE:
switch (eventP) {
case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_NULL_STATE -> RLC_DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_DATA_TRANSFER_READY_STATE;
return 1;
break;
default:
msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT %02X hex NOT EXPECTED FROM NULL_STATE frame %d\n", rlcP->rb_id, eventP, Mac_rlc_xface->frame);
return 0;
}
break;
//-------------------------------
// RLC_DATA_TRANSFER_READY_STATE
//-------------------------------
case RLC_DATA_TRANSFER_READY_STATE:
switch (eventP) {
case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_DATA_TRANSFER_READY_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_NULL_STATE;
return 1;
break;
case RLC_AM_RECEIVE_RESET_EVENT:
case RLC_AM_TRANSMIT_RESET_ACK_EVENT:
return 1;
break;
case RLC_AM_TRANSMIT_RESET_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_DATA_TRANSFER_READY_STATE -> RLC_RESET_PENDING_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_RESET_PENDING_STATE;
return 1;
break;
case RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT:
case RLC_AM_TRANSMIT_CRLC_SUSPEND_CNF_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_DATA_TRANSFER_READY_STATE -> RLC_LOCAL_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_LOCAL_SUSPEND_STATE;
return 1;
break;
default:
msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, eventP,
Mac_rlc_xface->frame);
return 0;
}
break;
//-------------------------------
// RLC_RESET_PENDING_STATE
//-------------------------------
case RLC_RESET_PENDING_STATE:
switch (eventP) {
case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_RESET_PENDING_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_NULL_STATE;
return 1;
break;
case RLC_AM_RECEIVE_RESET_EVENT:
case RLC_AM_TRANSMIT_RESET_ACK_EVENT:
case RLC_AM_TRANSMIT_RESET_EVENT: // WARNING: THIS EVENT IS NOT IN SPECS BUT MAY BE AN OMISSION ????
return 1;
break;
case RLC_AM_RECEIVE_RESET_ACK_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_RESET_PENDING_STATE -> RLC_DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_DATA_TRANSFER_READY_STATE;
return 1;
break;
case RLC_AM_RECEIVE_CRLC_SUSPEND_REQ_EVENT:
case RLC_AM_TRANSMIT_CRLC_SUSPEND_CNF_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_RESET_PENDING_STATE -> RLC_RESET_AND_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_RESET_AND_SUSPEND_STATE;
return 1;
break;
default:
msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM RLC_RESET_PENDING_STATE frame %d\n", rlcP->rb_id, eventP,
Mac_rlc_xface->frame);
return 0;
}
break;
//-------------------------------
// RLC_RESET_AND_SUSPEND_STATE
//-------------------------------
case RLC_RESET_AND_SUSPEND_STATE:
switch (eventP) {
case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_RESET_AND_SUSPEND_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_NULL_STATE;
return 1;
break;
case RLC_AM_RECEIVE_RESET_ACK_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_RESET_AND_SUSPEND_STATE -> RLC_LOCAL_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_LOCAL_SUSPEND_STATE;
return 1;
break;
case RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_RESET_AND_SUSPEND_STATE -> RLC_RESET_PENDING_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_RESET_PENDING_STATE;
return 1;
break;
default:
msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM RLC_RESET_AND_SUSPEND_STATE frame %d\n", rlcP->rb_id, eventP,
Mac_rlc_xface->frame);
return 0;
}
break;
//-------------------------------
// RLC_LOCAL_SUSPEND_STATE
//-------------------------------
case RLC_LOCAL_SUSPEND_STATE:
switch (eventP) {
case RLC_AM_RECEIVE_CRLC_CONFIG_REQ_ENTER_NULL_STATE_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_LOCAL_SUSPEND_STATE -> RLC_NULL_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_NULL_STATE;
return 1;
break;
case RLC_AM_RECEIVE_CRLC_RESUME_REQ_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_LOCAL_SUSPEND_STATE -> RLC_DATA_TRANSFER_READY_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_DATA_TRANSFER_READY_STATE;
return 1;
break;
case RLC_AM_TRANSMIT_RESET_EVENT:
#ifdef DEBUG_RLC_AM_FSM
msg ("[RLC_AM][RB %d][FSM] RLC_LOCAL_SUSPEND_STATE -> RLC_RESET_AND_SUSPEND_STATE frame %d\n", rlcP->rb_id, Mac_rlc_xface->frame);
#endif
rlcP->protocol_state = RLC_RESET_AND_SUSPEND_STATE;
return 1;
break;
default:
msg ("[RLC_AM][RB %d][FSM] WARNING PROTOCOL ERROR - EVENT 0x%02X NOT EXPECTED FROM RLC_LOCAL_SUSPEND_STATE frame %d\n", rlcP->rb_id, eventP,
Mac_rlc_xface->frame);
return 0;
}
break;
default:
msg ("[RLC_AM][RB %d][FSM] ERROR UNKNOWN STATE %d\n", rlcP->rb_id, rlcP->protocol_state);
return 0;
}
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_fsm_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_FSM_PROTO_EXTERN_H__
# define __RLC_AM_FSM_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "platform_types.h"
# include "rlc_am_entity.h"
//-----------------------------------------------------------------------------
extern int rlc_am_fsm_notify_event (struct rlc_am_entity *rlcP, uint8_t eventP);
# endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_mac_status.c -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#include "rtos_header.h"
#include "platform_types.h"
//-----------------------------------------------------------------------------
#include "rlc_am_entity.h"
#include "rlc_am_timers_proto_extern.h"
#include "rlc_am_discard_notif_proto_extern.h"
#include "rlc_am_reset_proto_extern.h"
#include "rlc_am_fsm_proto_extern.h"
#include "umts_timer_proto_extern.h"
//-----------------------------------------------------------------------------
void
rlc_am_status_report_from_mac (void* rlcP, uint16_t eventP)
{
//-----------------------------------------------------------------------------
struct rlc_am_entity* rlc = (struct rlc_am_entity*) rlcP;
//----------------------------------------
// STATUS
//----------------------------------------
if ((eventP & RLC_AM_FIRST_STATUS_PDU_TYPE) == RLC_AM_FIRST_STATUS_PDU_TYPE) {
#ifdef DEBUG_RLC_AM_MAC_STATUS
msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_FIRST_STATUS_PDU_TYPE\n", rlcP);
#endif
return;
}
//----------------------------------------
// DISCARD
//----------------------------------------
if ((eventP & RLC_AM_MRW_STATUS_PDU_TYPE)) {
#ifdef DEBUG_RLC_AM_MAC_STATUS
msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_MRW_STATUS_PDU_TYPE\n", rlcP);
#endif
// rearm the timer
if (!(rlc->timer_mrw) && (rlc->discard_procedures.head)) {
rlc->timer_mrw = umts_add_timer_list_up (&rlc->rlc_am_timer_list, rlc_am_discard_notify_mrw_ack_time_out, rlc,
rlc->discard_procedures.head, (uint32_t) rlc->timer_mrw_init, *rlc->frame_tick_milliseconds);
}
return;
}
//----------------------------------------
// RESET
//----------------------------------------
if ((eventP & RLC_AM_RESET_PDU_TYPE)) {
#ifdef DEBUG_RESET
msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_RESET_PDU_TYPE SENT ARMING RESET TIMER %d frames frame %d\n", rlcP, (uint32_t) rlc->timer_rst_init,
*rlc->frame_tick_milliseconds);
#endif
rlc->timer_rst = umts_add_timer_list_up (&rlc->rlc_am_timer_list, rlc_am_reset_time_out, rlcP, NULL, (uint32_t) rlc->timer_rst_init,
*rlc->frame_tick_milliseconds);
return;
}
//----------------------------------------
// RESET ACK
//----------------------------------------
if ((eventP & RLC_AM_RESET_ACK_PDU_TYPE)) {
#ifdef DEBUG_RLC_AM_MAC_STATUS
msg ("[RLC_AM %p][MAC_STATUS] EVENT RLC_AM_RESET_ACK_PDU_TYPE\n", rlcP);
#endif
rlc_am_fsm_notify_event (rlc, RLC_AM_TRANSMIT_RESET_ACK_EVENT);
return;
}
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/***************************************************************************
rlc_am_mac_status_proto_extern.h -
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
# ifndef __RLC_AM_MAC_STATUS_PROTO_EXTERN_H__
# define __RLC_AM_MAC_STATUS_PROTO_EXTERN_H__
//-----------------------------------------------------------------------------
# include "platform_types.h"
//-----------------------------------------------------------------------------
extern void rlc_am_status_report_from_mac (void *rlcP, uint16_t eventP);
# endif
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment