blob: 2828772a34dc3705da4103c44a36417ae50234d3 [file] [log] [blame]
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +02001/*
2 * Copyright (C) 2013 by Holger Hans Peter Freyther
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19#pragma once
20
Daniel Willmannafa72f52014-01-15 17:06:19 +010021#ifdef __cplusplus
22
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +020023#include "gprs_rlcmac.h"
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010024#include "llc.h"
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010025#include "rlc.h"
Jacob Erlbeck6835cea2015-08-21 15:24:02 +020026#include "cxx_linuxlist.h"
Daniel Willmanneb100242014-08-08 11:43:53 +020027#include <gprs_debug.h>
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +020028
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +020029#include <stdint.h>
Maxe66de5b2017-01-05 18:26:58 +010030extern "C" {
31#include <osmocom/core/utils.h>
32}
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +020033
Holger Hans Peter Freyther1702f102013-10-20 08:44:02 +020034struct bssgp_bvc_ctx;
Jacob Erlbeck20f6fd12015-06-08 11:05:45 +020035struct pcu_l1_meas;
Jacob Erlbeckfecece02015-05-08 12:13:08 +020036class GprsMs;
Holger Hans Peter Freyther1702f102013-10-20 08:44:02 +020037
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020038/*
39 * TBF instance
40 */
41
Maxb2de1f72017-12-20 18:05:29 +010042#define T_ASS_AGCH_USEC 200000 /* waiting after IMM.ASS confirm */
43#define T_ASS_PACCH_SEC 2 /* timeout for pacch assigment */
44#define T_REJ_PACCH_USEC 2000 /* timeout for tbf reject for PRR*/
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020045
46enum gprs_rlcmac_tbf_state {
47 GPRS_RLCMAC_NULL = 0, /* new created TBF */
Neels Hofmeyr4ea45262016-06-08 15:27:40 +020048 GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020049 GPRS_RLCMAC_FLOW, /* RLC/MAC flow, resource needed */
50 GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */
51 GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */
52 GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */
53};
54
Maxf60cf622017-07-10 14:40:09 +020055enum gprs_rlcmac_tbf_poll_type {
56 GPRS_RLCMAC_POLL_UL_ASS,
57 GPRS_RLCMAC_POLL_DL_ASS,
58 GPRS_RLCMAC_POLL_UL_ACK,
59 GPRS_RLCMAC_POLL_DL_ACK,
60};
61
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020062enum gprs_rlcmac_tbf_poll_state {
63 GPRS_RLCMAC_POLL_NONE = 0,
64 GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */
65};
66
67enum gprs_rlcmac_tbf_dl_ass_state {
68 GPRS_RLCMAC_DL_ASS_NONE = 0,
69 GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */
70 GPRS_RLCMAC_DL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */
71};
72
Maxe66de5b2017-01-05 18:26:58 +010073extern const struct value_string gprs_rlcmac_tbf_dl_ass_state_names[];
74
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020075enum gprs_rlcmac_tbf_ul_ass_state {
76 GPRS_RLCMAC_UL_ASS_NONE = 0,
77 GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */
aravind sirsikared3413e2016-11-11 17:15:10 +053078 GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ, /* send assignment reject next RTS */
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020079 GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */
80};
81
Maxe66de5b2017-01-05 18:26:58 +010082extern const struct value_string gprs_rlcmac_tbf_ul_ass_state_names[];
83
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020084enum gprs_rlcmac_tbf_ul_ack_state {
85 GPRS_RLCMAC_UL_ACK_NONE = 0,
86 GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */
87 GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */
88};
89
Max088c7df2018-01-23 20:16:23 +010090extern const struct value_string gprs_rlcmac_tbf_ul_ack_state_names[];
91
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020092enum gprs_rlcmac_tbf_direction {
93 GPRS_RLCMAC_DL_TBF,
94 GPRS_RLCMAC_UL_TBF
95};
96
Maxd0532b52017-12-13 18:27:32 +010097enum tbf_dl_prio {
98 DL_PRIO_NONE,
99 DL_PRIO_SENT_DATA, /* the data has been sent and not (yet) nacked */
100 DL_PRIO_LOW_AGE, /* the age has reached the first threshold */
101 DL_PRIO_NEW_DATA, /* the data has not been sent yet or nacked */
102 DL_PRIO_HIGH_AGE, /* the age has reached the second threshold */
103 DL_PRIO_CONTROL, /* a control block needs to be sent */
104};
105
sivasankari53950732016-12-08 17:15:17 +0530106enum tbf_counters {
107 TBF_CTR_RLC_NACKED,
108};
109
110enum tbf_gprs_counters {
111 TBF_CTR_GPRS_DL_CS1,
112 TBF_CTR_GPRS_DL_CS2,
113 TBF_CTR_GPRS_DL_CS3,
114 TBF_CTR_GPRS_DL_CS4,
115};
116
117enum tbf_egprs_counters {
118 TBF_CTR_EGPRS_DL_MCS1,
119 TBF_CTR_EGPRS_DL_MCS2,
120 TBF_CTR_EGPRS_DL_MCS3,
121 TBF_CTR_EGPRS_DL_MCS4,
122 TBF_CTR_EGPRS_DL_MCS5,
123 TBF_CTR_EGPRS_DL_MCS6,
124 TBF_CTR_EGPRS_DL_MCS7,
125 TBF_CTR_EGPRS_DL_MCS8,
126 TBF_CTR_EGPRS_DL_MCS9,
127};
128
sivasankarida7250a2016-12-16 12:57:18 +0530129enum tbf_gprs_ul_counters {
130 TBF_CTR_GPRS_UL_CS1,
131 TBF_CTR_GPRS_UL_CS2,
132 TBF_CTR_GPRS_UL_CS3,
133 TBF_CTR_GPRS_UL_CS4,
134};
135
136enum tbf_egprs_ul_counters {
137 TBF_CTR_EGPRS_UL_MCS1,
138 TBF_CTR_EGPRS_UL_MCS2,
139 TBF_CTR_EGPRS_UL_MCS3,
140 TBF_CTR_EGPRS_UL_MCS4,
141 TBF_CTR_EGPRS_UL_MCS5,
142 TBF_CTR_EGPRS_UL_MCS6,
143 TBF_CTR_EGPRS_UL_MCS7,
144 TBF_CTR_EGPRS_UL_MCS8,
145 TBF_CTR_EGPRS_UL_MCS9,
146};
147
Max0524e382018-01-19 18:22:25 +0100148#define LOGPTBF(tbf, level, fmt, args...) LOGP(DTBF, level, "%s " fmt, tbf_name(tbf), ## args)
149#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)
150#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DTBFDL, level, "%s " fmt, tbf_name(tbf), ## args)
Maxc21f0072017-12-15 17:36:45 +0100151
Maxee5be3a2017-12-20 17:31:13 +0100152enum tbf_timers {
Maxb2de1f72017-12-20 18:05:29 +0100153 /* internal assign/reject timer */
154 T0,
155
Maxee5be3a2017-12-20 17:31:13 +0100156 /* Wait for reuse of USF and TFI(s) after the MS uplink assignment for this TBF is invalid. */
157 T3169,
158
159 /* Wait for reuse of TFI(s) after sending of the last RLC Data Block on this TBF.
160 Wait for reuse of TFI(s) after sending the PACKET TBF RELEASE for an MBMS radio bearer. */
161 T3191,
162
163 /* Wait for reuse of TFI(s) after reception of the final PACKET DOWNLINK ACK/NACK from the
164 MS for this TBF. */
165 T3193,
166
167 /* Wait for reuse of TFI(s) when there is no response from the MS
168 (radio failure or cell change) for this TBF/MBMS radio bearer. */
169 T3195,
170 T_MAX
171};
172
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200173#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */
174#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */
175#define GPRS_RLCMAC_FLAG_UL_DATA 2 /* uplink data received */
176#define GPRS_RLCMAC_FLAG_DL_ACK 3 /* downlink acknowledge received */
177#define GPRS_RLCMAC_FLAG_TO_UL_ACK 4
178#define GPRS_RLCMAC_FLAG_TO_DL_ACK 5
179#define GPRS_RLCMAC_FLAG_TO_UL_ASS 6
180#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7
181#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */
182
Max467f6332017-12-20 18:13:29 +0100183#define T_START(tbf, t, sec, usec, r, f) tbf->t_start(t, sec, usec, r, f, __FILE__, __LINE__)
184
Max2399b1d2018-01-12 15:48:12 +0100185#define TBF_SET_STATE(t, st) do { t->set_state(st, __FILE__, __LINE__); } while(0)
Max0e599802018-01-23 20:09:06 +0100186#define TBF_SET_ASS_STATE_DL(t, st) do { t->set_ass_state_dl(st, __FILE__, __LINE__); } while(0)
187#define TBF_SET_ASS_STATE_UL(t, st) do { t->set_ass_state_ul(st, __FILE__, __LINE__); } while(0)
Max088c7df2018-01-23 20:16:23 +0100188#define TBF_SET_ACK_STATE(t, st) do { t->set_ack_state(st, __FILE__, __LINE__); } while(0)
Max2399b1d2018-01-12 15:48:12 +0100189#define TBF_SET_ASS_ON(t, fl, chk) do { t->set_assigned_on(fl, chk, __FILE__, __LINE__); } while(0)
190
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200191struct gprs_rlcmac_tbf {
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200192 gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir);
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200193
194 static void free_all(struct gprs_rlcmac_trx *trx);
Holger Hans Peter Freyther4f6a4e5d2013-10-16 17:58:46 +0200195 static void free_all(struct gprs_rlcmac_pdch *pdch);
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200196
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200197 bool state_is(enum gprs_rlcmac_tbf_state rhs) const;
198 bool state_is_not(enum gprs_rlcmac_tbf_state rhs) const;
Max0e599802018-01-23 20:09:06 +0100199 bool dl_ass_state_is(enum gprs_rlcmac_tbf_dl_ass_state rhs) const;
200 bool ul_ass_state_is(enum gprs_rlcmac_tbf_ul_ass_state rhs) const;
Max088c7df2018-01-23 20:16:23 +0100201 bool ul_ack_state_is(enum gprs_rlcmac_tbf_ul_ack_state rhs) const;
Max2399b1d2018-01-12 15:48:12 +0100202 void set_state(enum gprs_rlcmac_tbf_state new_state, const char *file, int line);
Max0e599802018-01-23 20:09:06 +0100203 void set_ass_state_dl(enum gprs_rlcmac_tbf_dl_ass_state new_state, const char *file, int line);
204 void set_ass_state_ul(enum gprs_rlcmac_tbf_ul_ass_state new_state, const char *file, int line);
Max088c7df2018-01-23 20:16:23 +0100205 void set_ack_state(enum gprs_rlcmac_tbf_ul_ack_state new_state, const char *file, int line);
Max0e599802018-01-23 20:09:06 +0100206 void check_pending_ass();
Max8dce1de2018-01-02 14:17:04 +0100207 bool check_n_clear(uint8_t state_flag);
Max2399b1d2018-01-12 15:48:12 +0100208 void set_assigned_on(uint8_t state_flag, bool check_ccch, const char *file, int line);
Daniel Willmann08e57c82014-08-15 18:11:57 +0200209 const char *state_name() const;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200210
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100211 const char *name() const;
212
Jacob Erlbeck5a3c84d2016-01-22 17:25:38 +0100213 struct msgb *create_dl_ass(uint32_t fn, uint8_t ts);
214 struct msgb *create_ul_ass(uint32_t fn, uint8_t ts);
aravind sirsikared3413e2016-11-11 17:15:10 +0530215 struct msgb *create_packet_access_reject();
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200216
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200217 GprsMs *ms() const;
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200218 void set_ms(GprsMs *ms);
219
Holger Hans Peter Freyther8f399de2013-12-25 20:22:35 +0100220 uint8_t tsc() const;
Holger Hans Peter Freythera1da2512013-11-07 07:32:51 +0100221
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200222 int rlcmac_diag();
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200223
Jacob Erlbecke0c734d2015-07-03 14:03:33 +0200224 int update();
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200225 void handle_timeout();
Maxee5be3a2017-12-20 17:31:13 +0100226 void stop_timers(const char *reason);
227 bool timers_pending(enum tbf_timers t);
228 void t_stop(enum tbf_timers t, const char *reason);
Max467f6332017-12-20 18:13:29 +0100229 void t_start(enum tbf_timers t, uint32_t sec, uint32_t microsec, const char *reason, bool force,
230 const char *file, unsigned line);
Jacob Erlbeck91ff7d12015-09-01 11:20:29 +0200231 int establish_dl_tbf_on_pacch();
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200232
Jacob Erlbeckf2694b72016-01-26 21:46:26 +0100233 int check_polling(uint32_t fn, uint8_t ts,
234 uint32_t *poll_fn, unsigned int *rrbp);
Maxf60cf622017-07-10 14:40:09 +0200235 void set_polling(uint32_t poll_fn, uint8_t ts, enum gprs_rlcmac_tbf_poll_type t);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200236 void poll_timeout();
237
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100238 /** tlli handling */
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100239 uint32_t tlli() const;
240 bool is_tlli_valid() const;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100241
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200242 /** MS updating */
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200243 void update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction);
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200244
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100245 uint8_t tfi() const;
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100246 bool is_tfi_assigned() const;
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100247
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100248 const char *imsi() const;
249 void assign_imsi(const char *imsi);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200250 uint8_t ta() const;
251 void set_ta(uint8_t);
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200252 uint8_t ms_class() const;
253 void set_ms_class(uint8_t);
Jacob Erlbeckcb728902016-01-05 15:33:03 +0100254 GprsCodingScheme current_cs() const;
Max869c0c22018-01-03 12:00:36 +0100255 size_t llc_queue_size() const;
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100256
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100257 time_t created_ts() const;
Jacob Erlbeck617c7122015-06-30 09:18:30 +0200258 uint8_t dl_slots() const;
259 uint8_t ul_slots() const;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100260
Jacob Erlbeck646da1b2016-01-22 17:41:33 +0100261 bool is_control_ts(uint8_t ts) const;
262
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100263 /* EGPRS */
264 bool is_egprs_enabled() const;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100265 void disable_egprs();
266
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100267 /* attempt to make things a bit more fair */
268 void rotate_in_list();
269
Jacob Erlbeck6835cea2015-08-21 15:24:02 +0200270 LListHead<gprs_rlcmac_tbf>& ms_list() {return this->m_ms_list;}
271 const LListHead<gprs_rlcmac_tbf>& ms_list() const {return this->m_ms_list;}
272
Jacob Erlbecked2dbf62015-12-28 19:15:40 +0100273 LListHead<gprs_rlcmac_tbf>& list();
274 const LListHead<gprs_rlcmac_tbf>& list() const;
275
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200276 uint32_t state_flags;
277 enum gprs_rlcmac_tbf_direction direction;
Holger Hans Peter Freyther743bafa2013-09-29 07:50:50 +0200278 struct gprs_rlcmac_trx *trx;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200279 uint8_t first_ts; /* first TS used by TBF */
280 uint8_t first_common_ts; /* first TS that the phone can send and
281 reveive simultaniously */
282 uint8_t control_ts; /* timeslot control messages and polling */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200283 struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */
Holger Hans Peter Freyther28e53782013-11-06 20:23:56 +0100284
285 gprs_llc m_llc;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200286
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200287 enum gprs_rlcmac_tbf_poll_state poll_state;
288 uint32_t poll_fn; /* frame number to poll */
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100289 uint8_t poll_ts; /* TS to poll */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200290
Holger Hans Peter Freyther9241fd02013-11-13 19:51:55 +0100291 gprs_rlc m_rlc;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200292
293 uint8_t n3105; /* N3105 counter */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200294
295 struct osmo_gsm_timer_list gsm_timer;
296 unsigned int fT; /* fTxxxx number */
297 unsigned int num_fT_exp; /* number of consecutive fT expirations */
298
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200299 struct Meas {
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200300 struct timeval rssi_tv; /* timestamp for rssi calculation */
301 int32_t rssi_sum; /* sum of rssi values */
302 int rssi_num; /* number of rssi values added since rssi_tv */
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200303
304 Meas();
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200305 } meas;
306
Daniel Willmann73191a42014-05-30 17:58:00 +0200307 /* Remember if the tbf was in wait_release state when we want to
308 * schedule a new dl assignment */
309 uint8_t was_releasing;
310
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200311 /* Can/should we upgrade this tbf to use multiple slots? */
312 uint8_t upgrade_to_multislot;
313
Holger Hans Peter Freyther9f0c1d22013-10-19 21:24:34 +0200314 /* store the BTS this TBF belongs to */
315 BTS *bts;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200316
Max59e4a4f2017-12-20 18:01:55 +0100317 uint8_t m_n3101; /* N3101 counter */
318
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100319 /*
320 * private fields. We can't make it private as it is breaking the
321 * llist macros.
322 */
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100323 uint8_t m_tfi;
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100324 time_t m_created_ts;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100325
sivasankari53950732016-12-08 17:15:17 +0530326 struct rate_ctr_group *m_ctrs;
327
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200328protected:
329 gprs_rlcmac_bts *bts_data() const;
Max25a3ca42017-12-13 18:47:52 +0100330 void enable_egprs();
Jacob Erlbecke8f5fe52015-12-14 13:23:15 +0100331 int set_tlli_from_ul(uint32_t new_tlli);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200332 void merge_and_clear_ms(GprsMs *old_ms);
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100333
Alexander Couzensd38b92e2016-08-21 19:38:30 +0200334 gprs_llc_queue *llc_queue();
335 const gprs_llc_queue *llc_queue() const;
336
Neels Hofmeyr4ea45262016-06-08 15:27:40 +0200337 static const char *tbf_state_name[6];
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100338
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200339 class GprsMs *m_ms;
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200340
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200341 /* Fields to take the TA/MS class values if no MS is associated */
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200342 uint8_t m_ta;
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200343 uint8_t m_ms_class;
Jacob Erlbeck6dbe8222015-05-29 10:37:09 +0200344
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100345private:
Max50818062017-12-06 13:35:08 +0100346 enum gprs_rlcmac_tbf_state state;
Max0e599802018-01-23 20:09:06 +0100347 enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state;
348 enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state;
Max088c7df2018-01-23 20:16:23 +0100349 enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state;
Jacob Erlbecked2dbf62015-12-28 19:15:40 +0100350 LListHead<gprs_rlcmac_tbf> m_list;
Jacob Erlbeck6835cea2015-08-21 15:24:02 +0200351 LListHead<gprs_rlcmac_tbf> m_ms_list;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100352 bool m_egprs_enabled;
Maxb2de1f72017-12-20 18:05:29 +0100353 struct osmo_timer_list T[T_MAX];
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100354 mutable char m_name_buf[60];
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200355};
356
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +0200357
Daniel Willmann0d12a2f2014-07-10 17:44:07 +0200358struct gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100359 int8_t use_trx, uint8_t ms_class, uint8_t egprs_ms_class,
Jacob Erlbecke2e004e2015-06-18 17:16:26 +0200360 uint32_t tlli, uint8_t ta, GprsMs *ms);
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200361
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200362struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck5879c642015-07-10 10:41:36 +0200363 GprsMs *ms, int8_t use_trx,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100364 uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot);
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200365
366struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck5879c642015-07-10 10:41:36 +0200367 GprsMs *ms, int8_t use_trx,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100368 uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot);
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200369
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200370void tbf_free(struct gprs_rlcmac_tbf *tbf);
371
aravind sirsikare9a138e2017-01-24 12:36:08 +0530372struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
373 GprsMs *ms, uint32_t tlli, uint8_t trx_no, uint8_t ts_no);
374
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200375int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf);
376
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200377inline bool gprs_rlcmac_tbf::state_is(enum gprs_rlcmac_tbf_state rhs) const
378{
379 return state == rhs;
380}
381
Max0e599802018-01-23 20:09:06 +0100382inline bool gprs_rlcmac_tbf::dl_ass_state_is(enum gprs_rlcmac_tbf_dl_ass_state rhs) const
383{
384 return dl_ass_state == rhs;
385}
386
387inline bool gprs_rlcmac_tbf::ul_ass_state_is(enum gprs_rlcmac_tbf_ul_ass_state rhs) const
388{
389 return ul_ass_state == rhs;
390}
391
Max088c7df2018-01-23 20:16:23 +0100392inline bool gprs_rlcmac_tbf::ul_ack_state_is(enum gprs_rlcmac_tbf_ul_ack_state rhs) const
393{
394 return ul_ack_state == rhs;
395}
396
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200397inline bool gprs_rlcmac_tbf::state_is_not(enum gprs_rlcmac_tbf_state rhs) const
398{
399 return state != rhs;
400}
401
Daniel Willmanneb100242014-08-08 11:43:53 +0200402const char *tbf_name(gprs_rlcmac_tbf *tbf);
403
Daniel Willmann08e57c82014-08-15 18:11:57 +0200404inline const char *gprs_rlcmac_tbf::state_name() const
405{
406 return tbf_state_name[state];
407}
408
Max8dce1de2018-01-02 14:17:04 +0100409/* Set assignment state and corrsponding flags */
Max2399b1d2018-01-12 15:48:12 +0100410inline void gprs_rlcmac_tbf::set_assigned_on(uint8_t state_flag, bool check_ccch, const char *file, int line)
Max8dce1de2018-01-02 14:17:04 +0100411{
Max2399b1d2018-01-12 15:48:12 +0100412 set_state(GPRS_RLCMAC_ASSIGN, file, line);
Max8dce1de2018-01-02 14:17:04 +0100413 if (check_ccch) {
414 if (!(state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
415 state_flags |= (1 << state_flag);
416 } else
417 state_flags |= (1 << state_flag);
418}
419
Max2399b1d2018-01-12 15:48:12 +0100420inline void gprs_rlcmac_tbf::set_state(enum gprs_rlcmac_tbf_state new_state, const char *file, int line)
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200421{
Max0524e382018-01-19 18:22:25 +0100422 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes state from %s to %s\n",
Daniel Willmanneb100242014-08-08 11:43:53 +0200423 tbf_name(this),
424 tbf_state_name[state], tbf_state_name[new_state]);
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200425 state = new_state;
426}
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100427
Max0e599802018-01-23 20:09:06 +0100428inline void gprs_rlcmac_tbf::set_ass_state_dl(enum gprs_rlcmac_tbf_dl_ass_state new_state, const char *file, int line)
429{
430 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes DL ASS state from %s to %s\n",
431 tbf_name(this),
432 get_value_string(gprs_rlcmac_tbf_dl_ass_state_names, dl_ass_state),
433 get_value_string(gprs_rlcmac_tbf_dl_ass_state_names, new_state));
434 dl_ass_state = new_state;
435}
436
437inline void gprs_rlcmac_tbf::set_ass_state_ul(enum gprs_rlcmac_tbf_ul_ass_state new_state, const char *file, int line)
438{
439 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes UL ASS state from %s to %s\n",
440 tbf_name(this),
441 get_value_string(gprs_rlcmac_tbf_ul_ass_state_names, ul_ass_state),
442 get_value_string(gprs_rlcmac_tbf_ul_ass_state_names, new_state));
443 ul_ass_state = new_state;
444}
445
Max088c7df2018-01-23 20:16:23 +0100446inline void gprs_rlcmac_tbf::set_ack_state(enum gprs_rlcmac_tbf_ul_ack_state new_state, const char *file, int line)
447{
448 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes UL ACK state from %s to %s\n",
449 tbf_name(this),
450 get_value_string(gprs_rlcmac_tbf_ul_ack_state_names, ul_ack_state),
451 get_value_string(gprs_rlcmac_tbf_ul_ack_state_names, new_state));
452 ul_ack_state = new_state;
453}
454
Max0e599802018-01-23 20:09:06 +0100455inline void gprs_rlcmac_tbf::check_pending_ass()
456{
457 if (ul_ass_state != GPRS_RLCMAC_UL_ASS_NONE)
458 LOGPTBF(this, LOGL_ERROR, "FIXME: Software error: Pending uplink assignment in state %s. "
459 "This may not happen, because the assignment message never gets transmitted. "
460 "Please be sure not to free in this state. PLEASE FIX!\n",
461 get_value_string(gprs_rlcmac_tbf_ul_ass_state_names, ul_ass_state));
462
463 if (dl_ass_state != GPRS_RLCMAC_DL_ASS_NONE)
464 LOGPTBF(this, LOGL_ERROR, "FIXME: Software error: Pending downlink assignment in state %s. "
465 "This may not happen, because the assignment message never gets transmitted. "
466 "Please be sure not to free in this state. PLEASE FIX!\n",
467 get_value_string(gprs_rlcmac_tbf_dl_ass_state_names, dl_ass_state));
468}
469
Max8dce1de2018-01-02 14:17:04 +0100470inline bool gprs_rlcmac_tbf::check_n_clear(uint8_t state_flag)
471{
472 if ((state_flags & (1 << state_flag))) {
473 state_flags &= ~(1 << state_flag);
474 return true;
475 }
476
477 return false;
478}
479
Jacob Erlbecked2dbf62015-12-28 19:15:40 +0100480inline LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list()
481{
482 return this->m_list;
483}
484
485inline const LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list() const
486{
487 return this->m_list;
488}
489
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200490inline GprsMs *gprs_rlcmac_tbf::ms() const
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200491{
492 return m_ms;
493}
494
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100495inline bool gprs_rlcmac_tbf::is_tlli_valid() const
496{
Jacob Erlbeck767193e2015-05-20 12:06:46 +0200497 return tlli() != 0;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100498}
499
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100500inline bool gprs_rlcmac_tbf::is_tfi_assigned() const
501{
502 /* The TBF is established or has been assigned by a IMM.ASS for
503 * download */
Neels Hofmeyr4ea45262016-06-08 15:27:40 +0200504 return state > GPRS_RLCMAC_ASSIGN ||
505 (direction == GPRS_RLCMAC_DL_TBF &&
506 state == GPRS_RLCMAC_ASSIGN &&
507 (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)));
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100508}
509
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100510inline uint8_t gprs_rlcmac_tbf::tfi() const
511{
512 return m_tfi;
513}
514
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100515inline time_t gprs_rlcmac_tbf::created_ts() const
Daniel Willmann80367aa2014-01-15 17:40:28 +0100516{
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100517 return m_created_ts;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100518}
519
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100520inline bool gprs_rlcmac_tbf::is_egprs_enabled() const
521{
522 return m_egprs_enabled;
523}
524
525inline void gprs_rlcmac_tbf::enable_egprs()
526{
527 m_egprs_enabled = true;
528}
529
530inline void gprs_rlcmac_tbf::disable_egprs()
531{
532 m_egprs_enabled = false;
533}
534
Daniel Willmann078bb712014-07-10 17:44:06 +0200535struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200536 gprs_rlcmac_dl_tbf(BTS *bts);
Maxea98b7d2018-01-04 15:13:27 +0100537 gprs_rlc_dl_window *window();
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200538 void cleanup();
Max25a3ca42017-12-13 18:47:52 +0100539 void enable_egprs();
Daniel Willmann30168882014-08-07 12:48:29 +0200540 /* dispatch Unitdata.DL messages */
541 static int handle(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck93990462015-05-15 15:50:43 +0200542 const uint32_t tlli, const uint32_t old_tlli,
543 const char *imsi, const uint8_t ms_class,
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100544 const uint8_t egprs_ms_class, const uint16_t delay_csec,
545 const uint8_t *data, const uint16_t len);
Daniel Willmann30168882014-08-07 12:48:29 +0200546
Daniel Willmann538ac5b2014-07-30 19:12:27 +0200547 int append_data(const uint8_t ms_class,
548 const uint16_t pdu_delay_csec,
549 const uint8_t *data, const uint16_t len);
550
Max7df82d42017-12-15 11:14:30 +0100551 int rcvd_dl_ack(bool final, uint8_t ssn, uint8_t *rbb);
552 int rcvd_dl_ack(bool final_ack, unsigned first_bsn, struct bitvec *rbb);
Daniel Willmannb8f26012014-07-30 19:12:28 +0200553 struct msgb *create_dl_acked_block(uint32_t fn, uint8_t ts);
Maxa10c3982017-07-07 18:25:41 +0200554 void trigger_ass(struct gprs_rlcmac_tbf *old_tbf);
Max8dce1de2018-01-02 14:17:04 +0100555
Maxaae1bfb2017-07-07 13:49:29 +0200556 bool handle_ack_nack();
Jacob Erlbeck7c444152015-03-12 12:08:54 +0100557 void request_dl_ack();
Jacob Erlbeckeceb9102015-03-20 14:41:50 +0100558 bool need_control_ts() const;
559 bool have_data() const;
Jacob Erlbeck005ee7f2015-03-20 14:53:54 +0100560 int frames_since_last_poll(unsigned fn) const;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100561 int frames_since_last_drain(unsigned fn) const;
562 bool keep_open(unsigned fn) const;
Jacob Erlbeck91ff7d12015-09-01 11:20:29 +0200563 int release();
Jacob Erlbeckf04a5b32016-01-21 20:42:40 +0100564 int abort();
Maxa4f570f2017-12-15 11:21:57 +0100565 uint16_t window_size() const;
Max9d7357e2017-12-14 15:02:33 +0100566 void set_window_size();
Mrinal Mishraf86307e2016-11-10 18:16:30 +0530567 void update_coding_scheme_counter_dl(const GprsCodingScheme cs);
Aravind Sirsikar8e70bb52016-09-15 17:51:16 +0530568
Daniel Willmanncf706b02014-08-07 17:35:22 +0200569 /* TODO: add the gettimeofday as parameter */
570 struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx);
571
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200572 /* Please note that all variables here will be reset when changing
573 * from WAIT RELEASE back to FLOW state (re-use of TBF).
574 * All states that need reset must be in this struct, so this is why
575 * variables are in both (dl and ul) structs and not outside union.
576 */
Daniel Willmann7e994e32014-08-07 15:49:21 +0200577 int32_t m_tx_counter; /* count all transmitted blocks */
578 uint8_t m_wait_confirm; /* wait for CCCH IMM.ASS cnf */
Jacob Erlbeck7c444152015-03-12 12:08:54 +0100579 bool m_dl_ack_requested;
Jacob Erlbeck005ee7f2015-03-20 14:53:54 +0100580 int32_t m_last_dl_poll_fn;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100581 int32_t m_last_dl_drained_fn;
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200582
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200583 struct BandWidth {
Daniel Willmann418a4232014-08-08 11:21:04 +0200584 struct timeval dl_bw_tv; /* timestamp for dl bw calculation */
585 uint32_t dl_bw_octets; /* number of octets since bw_tv */
sivasankari53950732016-12-08 17:15:17 +0530586 uint32_t dl_throughput; /* throughput to be displayed in stats */
Daniel Willmann418a4232014-08-08 11:21:04 +0200587
588 struct timeval dl_loss_tv; /* timestamp for loss calculation */
589 uint16_t dl_loss_lost; /* sum of lost packets */
590 uint16_t dl_loss_received; /* sum of received packets */
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200591
592 BandWidth();
Daniel Willmann418a4232014-08-08 11:21:04 +0200593 } m_bw;
594
sivasankari53950732016-12-08 17:15:17 +0530595 struct rate_ctr_group *m_dl_gprs_ctrs;
596 struct rate_ctr_group *m_dl_egprs_ctrs;
597
Daniel Willmannb8f26012014-07-30 19:12:28 +0200598protected:
Jacob Erlbeck2db0f082015-09-07 18:49:00 +0200599 struct ana_result {
600 unsigned received_packets;
601 unsigned lost_packets;
602 unsigned received_bytes;
603 unsigned lost_bytes;
604 };
605
Jacob Erlbeckd6752492016-02-02 18:12:46 +0100606 int take_next_bsn(uint32_t fn, int previous_bsn,
Jacob Erlbeck64e7b832016-02-04 15:16:47 +0100607 bool *may_combine);
Jacob Erlbeckd6752492016-02-02 18:12:46 +0100608 bool restart_bsn_cycle();
609 int create_new_bsn(const uint32_t fn, GprsCodingScheme cs);
Daniel Willmannb8f26012014-07-30 19:12:28 +0200610 struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,
Jacob Erlbeckbe314d92016-02-02 15:32:10 +0100611 int index, int index2 = -1);
Daniel Willmann30168882014-08-07 12:48:29 +0200612 int update_window(const uint8_t ssn, const uint8_t *rbb);
Jacob Erlbeckeb08f862016-02-05 17:07:12 +0100613 int update_window(unsigned first_bsn, const struct bitvec *rbb);
Daniel Willmann30168882014-08-07 12:48:29 +0200614 int maybe_start_new_window();
615 bool dl_window_stalled() const;
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200616 void reuse_tbf();
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200617 void start_llc_timer();
Jacob Erlbeck2db0f082015-09-07 18:49:00 +0200618 int analyse_errors(char *show_rbb, uint8_t ssn, ana_result *res);
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200619 void schedule_next_frame();
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200620
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530621 enum egprs_rlc_dl_reseg_bsn_state egprs_dl_get_data
622 (int bsn, uint8_t **block_data);
623 unsigned int get_egprs_dl_spb_status(int bsn);
624 enum egprs_rlcmac_dl_spb get_egprs_dl_spb(int bsn);
625
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200626 struct osmo_timer_list m_llc_timer;
Maxea98b7d2018-01-04 15:13:27 +0100627
628 /* Please note that all variables below will be reset when changing
629 * from WAIT RELEASE back to FLOW state (re-use of TBF).
630 * All states that need reset must be in this struct, so this is why
631 * variables are in both (dl and ul) structs and not outside union.
632 */
633 gprs_rlc_dl_window m_window;
Daniel Willmann078bb712014-07-10 17:44:06 +0200634};
635
636struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200637 gprs_rlcmac_ul_tbf(BTS *bts);
Maxea98b7d2018-01-04 15:13:27 +0100638 gprs_rlc_ul_window *window();
Jacob Erlbeck5a3c84d2016-01-22 17:25:38 +0100639 struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);
Maxfd13f6c2017-07-07 14:29:36 +0200640 bool ctrl_ack_to_toggle();
641 bool handle_ctrl_ack();
Max25a3ca42017-12-13 18:47:52 +0100642 void enable_egprs();
Daniel Willmann350f64d2014-08-07 14:54:11 +0200643 /* blocks were acked */
Jacob Erlbeckb3100e12015-12-14 13:36:13 +0100644 int rcv_data_block_acknowledged(
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100645 const struct gprs_rlc_data_info *rlc,
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +0100646 uint8_t *data, struct pcu_l1_meas *meas);
Jacob Erlbeckb3100e12015-12-14 13:36:13 +0100647
Daniel Willmann350f64d2014-08-07 14:54:11 +0200648
Daniel Willmanne2732e22014-08-07 17:32:01 +0200649 /* TODO: extract LLC class? */
650 int assemble_forward_llc(const gprs_rlc_data *data);
651 int snd_ul_ud();
652
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530653 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(
654 const struct gprs_rlc_data_info *rlc,
655 struct gprs_rlc_data *block,
656 uint8_t *data, const uint8_t block_idx);
657
658 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(
659 const struct gprs_rlc_data_info *rlc,
660 struct gprs_rlc_data *block,
661 uint8_t *data, const uint8_t block_idx);
662
663 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(
664 const struct gprs_rlc_data_info *rlc,
665 struct gprs_rlc_data *block,
666 uint8_t *data, const uint8_t block_idx);
667
Maxa4f570f2017-12-15 11:21:57 +0100668 uint16_t window_size() const;
Max9d7357e2017-12-14 15:02:33 +0100669 void set_window_size();
Mrinal Mishraf86307e2016-11-10 18:16:30 +0530670 void update_coding_scheme_counter_ul(const GprsCodingScheme cs);
671
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200672 /* Please note that all variables here will be reset when changing
673 * from WAIT RELEASE back to FLOW state (re-use of TBF).
674 * All states that need reset must be in this struct, so this is why
675 * variables are in both (dl and ul) structs and not outside union.
676 */
Daniel Willmann7e994e32014-08-07 15:49:21 +0200677 int32_t m_rx_counter; /* count all received blocks */
678 uint8_t m_n3103; /* N3103 counter */
679 uint8_t m_usf[8]; /* list USFs per PDCH (timeslot) */
680 uint8_t m_contention_resolution_done; /* set after done */
681 uint8_t m_final_ack_sent; /* set if we sent final ack */
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200682
sivasankarida7250a2016-12-16 12:57:18 +0530683 struct rate_ctr_group *m_ul_gprs_ctrs;
684 struct rate_ctr_group *m_ul_egprs_ctrs;
685
Daniel Willmann350f64d2014-08-07 14:54:11 +0200686protected:
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100687 void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc);
Maxea98b7d2018-01-04 15:13:27 +0100688
689 /* Please note that all variables below will be reset when changing
690 * from WAIT RELEASE back to FLOW state (re-use of TBF).
691 * All states that need reset must be in this struct, so this is why
692 * variables are in both (dl and ul) structs and not outside union.
693 */
694 gprs_rlc_ul_window m_window;
Daniel Willmann078bb712014-07-10 17:44:06 +0200695};
696
Max701afa42017-12-01 17:13:22 +0100697#ifdef __cplusplus
698extern "C" {
699#endif
700void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);
701void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);
702#ifdef __cplusplus
703}
704#endif
705
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200706inline enum gprs_rlcmac_tbf_direction reverse(enum gprs_rlcmac_tbf_direction dir)
707{
708 return (enum gprs_rlcmac_tbf_direction)
709 ((int)GPRS_RLCMAC_UL_TBF - (int)dir + (int)GPRS_RLCMAC_DL_TBF);
710}
Jacob Erlbeckaa9daa12015-12-28 18:49:12 +0100711
Maxa4f570f2017-12-15 11:21:57 +0100712inline uint16_t gprs_rlcmac_ul_tbf::window_size() const
713{
714 return m_window.ws();
715}
716
717inline uint16_t gprs_rlcmac_dl_tbf::window_size() const
718{
719 return m_window.ws();
720}
721
Max25a3ca42017-12-13 18:47:52 +0100722inline void gprs_rlcmac_ul_tbf::enable_egprs()
723{
724 m_window.set_sns(RLC_EGPRS_SNS);
725 gprs_rlcmac_tbf::enable_egprs();
726}
727
728inline void gprs_rlcmac_dl_tbf::enable_egprs()
729{
730 m_window.set_sns(RLC_EGPRS_SNS);
731 gprs_rlcmac_tbf::enable_egprs();
732}
733
Jacob Erlbeckaa9daa12015-12-28 18:49:12 +0100734inline gprs_rlcmac_ul_tbf *as_ul_tbf(gprs_rlcmac_tbf *tbf)
735{
736 if (tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)
737 return static_cast<gprs_rlcmac_ul_tbf *>(tbf);
738 else
739 return NULL;
740}
741
742inline gprs_rlcmac_dl_tbf *as_dl_tbf(gprs_rlcmac_tbf *tbf)
743{
744 if (tbf && tbf->direction == GPRS_RLCMAC_DL_TBF)
745 return static_cast<gprs_rlcmac_dl_tbf *>(tbf);
746 else
747 return NULL;
748}
749
Max9d7357e2017-12-14 15:02:33 +0100750uint16_t egprs_window_size(const struct gprs_rlcmac_bts *bts_data, uint8_t slots);
751
Daniel Willmannafa72f52014-01-15 17:06:19 +0100752#endif