rlc_am_timer_poll_retransmit.c 8.35 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22
23
#define RLC_AM_MODULE 1
#define RLC_AM_TIMER_POLL_RETRANSMIT_C 1
24
25
26
27
28
29
30
31
//-----------------------------------------------------------------------------
//#include "rtos_header.h"
#include "platform_types.h"
#include "platform_constants.h"
//-----------------------------------------------------------------------------
#include "rlc_am.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
32
#include "msc.h"
33
//-----------------------------------------------------------------------------
34
35
void
rlc_am_check_timer_poll_retransmit(
36
37
38
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t * const      rlc_pP
)
39
40
41
42
43
44
45
46
47
48
{
  // 5.2.2.3 Expiry of t-PollRetransmit
  // Upon expiry of t-PollRetransmit, the transmitting side of an AM RLC entity shall:
  //     - if both the transmission buffer and the retransmission buffer are empty (excluding transmitted RLC data PDU
  //           awaiting for acknowledgements); or
  //     - if no new RLC data PDU can be transmitted (e.g. due to window stalling):
  //         - consider the AMD PDU with SN = VT(S) – 1 for retransmission; or
  //         - consider any AMD PDU which has not been positively acknowledged for retransmission;
  //     - include a poll in a RLC data PDU as described in section 5.2.2.1.

49
50
51
52
53
54
55
  if (rlc_pP->t_poll_retransmit.running) {
    if (
      // CASE 1:          start              time out
      //        +-----------+------------------+----------+
      //        |           |******************|          |
      //        +-----------+------------------+----------+
      //FRAME # 0                                     FRAME MAX
56
57
58
      ((rlc_pP->t_poll_retransmit.ms_start < rlc_pP->t_poll_retransmit.ms_time_out) &&
       ((PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) >= rlc_pP->t_poll_retransmit.ms_time_out) ||
        (PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) < rlc_pP->t_poll_retransmit.ms_start)))                                   ||
59
60
61
62
63
      // CASE 2:        time out            start
      //        +-----------+------------------+----------+
      //        |***********|                  |**********|
      //        +-----------+------------------+----------+
      //FRAME # 0                                     FRAME MAX VALUE
64
65
66
      ((rlc_pP->t_poll_retransmit.ms_start > rlc_pP->t_poll_retransmit.ms_time_out) &&
       (PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) < rlc_pP->t_poll_retransmit.ms_start) &&
       (PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) >= rlc_pP->t_poll_retransmit.ms_time_out))
67
68
69
70
71
    ) {
      //if (rlc_pP->t_poll_retransmit.frame_time_out <= ctxt_pP->frame) {
      rlc_pP->t_poll_retransmit.running   = 0;
      rlc_pP->t_poll_retransmit.timed_out = 1;
      rlc_pP->stat_timer_poll_retransmit_timed_out += 1;
72
#if MESSAGE_CHART_GENERATOR_RLC_MAC
73
74
75
76
      MSC_LOG_EVENT((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
                             "0 "PROTOCOL_RLC_AM_MSC_FMT" t_poll_retransmit timed-out",\
                             PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP));
#endif
77
78
      LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T_POLL_RETRANSMIT] TIME-OUT\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
79

80
81
82
83
84
85
      /* Check for any retransmittable PDU if Buffer Occupancy empty or window stall */
	  if (((rlc_pP->sdu_buffer_occupancy == 0) && (rlc_pP->retrans_num_bytes_to_retransmit == 0)) ||
			    (rlc_pP->vt_s == rlc_pP->vt_ms)) {
		  // force BO to be > 0
		  rlc_sn_t             sn           = RLC_AM_PREV_SN(rlc_pP->vt_s);
		  rlc_sn_t             sn_end       = RLC_AM_PREV_SN(rlc_pP->vt_a);
86
		  rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p;
87
88
89

          /* Look for the first retransmittable PDU starting from vtS - 1 */
		  while (sn != sn_end) {
90
91
			tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE];
			AssertFatal (tx_data_pdu_buffer_p->mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n",
92
					sn, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
93
94
95
96
		    if ((tx_data_pdu_buffer_p->flags.ack == 0) && (tx_data_pdu_buffer_p->flags.max_retransmit == 0)) {
		    	tx_data_pdu_buffer_p->flags.retransmit = 1;
		    	if (tx_data_pdu_buffer_p->retx_count == tx_data_pdu_buffer_p->retx_count_next) {
		    		tx_data_pdu_buffer_p->retx_count_next ++;
97
		    	}
98
		    	rlc_pP->retrans_num_pdus += 1;
99
		    	rlc_pP->retrans_num_bytes_to_retransmit += tx_data_pdu_buffer_p->payload_size;
100
		    	break;
101
102
103
104
105
106
107
108
		    }
		    else
		    {
		    	sn = RLC_AM_PREV_SN(sn);
		    }
		  }
	  }

109
110

      rlc_pP->force_poll= TRUE;
111
      //BugFix : new ms_time_out is computed when next poll is transmitter
112
    }
113
  }
114
115
}
//-----------------------------------------------------------------------------
116
117
int
rlc_am_is_timer_poll_retransmit_timed_out(
118
119
120
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t * const      rlc_pP
)
121
{
122
  return rlc_pP->t_poll_retransmit.timed_out;
123
124
}
//-----------------------------------------------------------------------------
125
126
void
rlc_am_stop_and_reset_timer_poll_retransmit(
127
128
129
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t * const      rlc_pP
)
130
{
131
132
  LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T_POLL_RETRANSMIT] STOPPED AND RESET\n",
        PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
133
  rlc_pP->t_poll_retransmit.running         = 0;
134
135
  rlc_pP->t_poll_retransmit.ms_time_out     = 0;
  rlc_pP->t_poll_retransmit.ms_start        = 0;
136
  rlc_pP->t_poll_retransmit.timed_out       = 0;
137
#if MESSAGE_CHART_GENERATOR_RLC_MAC
138
139
140
141
    MSC_LOG_EVENT((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
                  "0 "PROTOCOL_RLC_AM_MSC_FMT" t_poll_retransmit stopped & reseted",\
                  PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP));
#endif
142
143
}
//-----------------------------------------------------------------------------
144
145
void
rlc_am_start_timer_poll_retransmit(
146
147
148
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t * const      rlc_pP
)
149
{
150
151
  /* Stop timer if it was previously running */
  rlc_am_stop_and_reset_timer_poll_retransmit(ctxt_pP,rlc_pP);
152

153
154
155
156
157
    if (rlc_pP->t_poll_retransmit.ms_duration > 0) {
      rlc_pP->t_poll_retransmit.running         = 1;
      rlc_pP->t_poll_retransmit.ms_time_out     = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) + rlc_pP->t_poll_retransmit.ms_duration;
      rlc_pP->t_poll_retransmit.ms_start        = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP);
      LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T_POLL_RETRANSMIT] STARTED (TIME-OUT = FRAME %05d)\n",
158
159
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
          rlc_pP->t_poll_retransmit.ms_time_out);
160
#if MESSAGE_CHART_GENERATOR_RLC_MAC
161
162
163
164
165
      MSC_LOG_EVENT((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\
                             "0 "PROTOCOL_RLC_AM_MSC_FMT" t_poll_retransmit started (TO %u ms)",\
                             PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP), rlc_pP->t_poll_retransmit.ms_time_out);
#endif
    } else {
166
167
    LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T_POLL_RETRANSMIT] NOT STARTED, CAUSE CONFIGURED 0 ms\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
168
169
    }

170
171
}
//-----------------------------------------------------------------------------
172
173
void
rlc_am_init_timer_poll_retransmit(
174
175
  const protocol_ctxt_t* const ctxt_pP,
  rlc_am_entity_t * const      rlc_pP,
176
  const uint32_t ms_durationP)
177
{
178
  rlc_pP->t_poll_retransmit.running         = 0;
179
180
181
  rlc_pP->t_poll_retransmit.ms_time_out     = 0;
  rlc_pP->t_poll_retransmit.ms_start        = 0;
  rlc_pP->t_poll_retransmit.ms_duration     = ms_durationP;
182
  rlc_pP->t_poll_retransmit.timed_out       = 0;
183
}