blob: 4489695ebf4f3d51727302d127bbd9233166e5b9 [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
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020042#define Tassign_agch 0,200000 /* waiting after IMM.ASS confirm */
43#define Tassign_pacch 2,0 /* timeout for pacch assigment */
aravind sirsikare9a138e2017-01-24 12:36:08 +053044#define Treject_pacch 0,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
90enum gprs_rlcmac_tbf_direction {
91 GPRS_RLCMAC_DL_TBF,
92 GPRS_RLCMAC_UL_TBF
93};
94
sivasankari53950732016-12-08 17:15:17 +053095enum tbf_counters {
96 TBF_CTR_RLC_NACKED,
97};
98
99enum tbf_gprs_counters {
100 TBF_CTR_GPRS_DL_CS1,
101 TBF_CTR_GPRS_DL_CS2,
102 TBF_CTR_GPRS_DL_CS3,
103 TBF_CTR_GPRS_DL_CS4,
104};
105
106enum tbf_egprs_counters {
107 TBF_CTR_EGPRS_DL_MCS1,
108 TBF_CTR_EGPRS_DL_MCS2,
109 TBF_CTR_EGPRS_DL_MCS3,
110 TBF_CTR_EGPRS_DL_MCS4,
111 TBF_CTR_EGPRS_DL_MCS5,
112 TBF_CTR_EGPRS_DL_MCS6,
113 TBF_CTR_EGPRS_DL_MCS7,
114 TBF_CTR_EGPRS_DL_MCS8,
115 TBF_CTR_EGPRS_DL_MCS9,
116};
117
sivasankarida7250a2016-12-16 12:57:18 +0530118enum tbf_gprs_ul_counters {
119 TBF_CTR_GPRS_UL_CS1,
120 TBF_CTR_GPRS_UL_CS2,
121 TBF_CTR_GPRS_UL_CS3,
122 TBF_CTR_GPRS_UL_CS4,
123};
124
125enum tbf_egprs_ul_counters {
126 TBF_CTR_EGPRS_UL_MCS1,
127 TBF_CTR_EGPRS_UL_MCS2,
128 TBF_CTR_EGPRS_UL_MCS3,
129 TBF_CTR_EGPRS_UL_MCS4,
130 TBF_CTR_EGPRS_UL_MCS5,
131 TBF_CTR_EGPRS_UL_MCS6,
132 TBF_CTR_EGPRS_UL_MCS7,
133 TBF_CTR_EGPRS_UL_MCS8,
134 TBF_CTR_EGPRS_UL_MCS9,
135};
136
Maxc21f0072017-12-15 17:36:45 +0100137#define LOGPTBF(tbf, level, fmt, args...) LOGP(DRLCMAC, level, "%s " fmt, tbf_name(tbf), ## args)
138#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DRLCMACUL, level, "%s " fmt, tbf_name(tbf), ## args)
139#define LOGPTBFDL(tbf, level, fmt, args...) LOGP(DRLCMACDL, level, "%s " fmt, tbf_name(tbf), ## args)
140
Maxee5be3a2017-12-20 17:31:13 +0100141enum tbf_timers {
142 /* Wait for reuse of USF and TFI(s) after the MS uplink assignment for this TBF is invalid. */
143 T3169,
144
145 /* Wait for reuse of TFI(s) after sending of the last RLC Data Block on this TBF.
146 Wait for reuse of TFI(s) after sending the PACKET TBF RELEASE for an MBMS radio bearer. */
147 T3191,
148
149 /* Wait for reuse of TFI(s) after reception of the final PACKET DOWNLINK ACK/NACK from the
150 MS for this TBF. */
151 T3193,
152
153 /* Wait for reuse of TFI(s) when there is no response from the MS
154 (radio failure or cell change) for this TBF/MBMS radio bearer. */
155 T3195,
156 T_MAX
157};
158
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200159#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */
160#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */
161#define GPRS_RLCMAC_FLAG_UL_DATA 2 /* uplink data received */
162#define GPRS_RLCMAC_FLAG_DL_ACK 3 /* downlink acknowledge received */
163#define GPRS_RLCMAC_FLAG_TO_UL_ACK 4
164#define GPRS_RLCMAC_FLAG_TO_DL_ACK 5
165#define GPRS_RLCMAC_FLAG_TO_UL_ASS 6
166#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7
167#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */
168
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200169struct gprs_rlcmac_tbf {
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200170 gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir);
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200171
172 static void free_all(struct gprs_rlcmac_trx *trx);
Holger Hans Peter Freyther4f6a4e5d2013-10-16 17:58:46 +0200173 static void free_all(struct gprs_rlcmac_pdch *pdch);
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200174
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200175 bool state_is(enum gprs_rlcmac_tbf_state rhs) const;
176 bool state_is_not(enum gprs_rlcmac_tbf_state rhs) const;
177 void set_state(enum gprs_rlcmac_tbf_state new_state);
Daniel Willmann08e57c82014-08-15 18:11:57 +0200178 const char *state_name() const;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200179
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100180 const char *name() const;
181
Jacob Erlbeck5a3c84d2016-01-22 17:25:38 +0100182 struct msgb *create_dl_ass(uint32_t fn, uint8_t ts);
183 struct msgb *create_ul_ass(uint32_t fn, uint8_t ts);
aravind sirsikared3413e2016-11-11 17:15:10 +0530184 struct msgb *create_packet_access_reject();
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200185
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200186 GprsMs *ms() const;
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200187 void set_ms(GprsMs *ms);
188
Jacob Erlbeck13965ae2016-01-19 14:10:40 +0100189 gprs_rlc_window *window();
190
Holger Hans Peter Freyther8f399de2013-12-25 20:22:35 +0100191 uint8_t tsc() const;
Holger Hans Peter Freythera1da2512013-11-07 07:32:51 +0100192
Holger Hans Peter Freyther7380bab2013-10-16 18:09:19 +0200193 int rlcmac_diag();
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200194
Jacob Erlbecke0c734d2015-07-03 14:03:33 +0200195 int update();
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200196 void handle_timeout();
Maxcea806e2017-12-01 17:40:20 +0100197 void stop_timer(const char *reason);
Maxee5be3a2017-12-20 17:31:13 +0100198 void stop_timers(const char *reason);
199 bool timers_pending(enum tbf_timers t);
200 void t_stop(enum tbf_timers t, const char *reason);
201 void t_start(enum tbf_timers t, uint32_t sec, uint32_t microsec, const char *reason, bool force);
Jacob Erlbeck91ff7d12015-09-01 11:20:29 +0200202 int establish_dl_tbf_on_pacch();
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200203
Jacob Erlbeckf2694b72016-01-26 21:46:26 +0100204 int check_polling(uint32_t fn, uint8_t ts,
205 uint32_t *poll_fn, unsigned int *rrbp);
Maxf60cf622017-07-10 14:40:09 +0200206 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 +0200207 void poll_timeout();
208
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100209 /** tlli handling */
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100210 uint32_t tlli() const;
211 bool is_tlli_valid() const;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100212
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200213 /** MS updating */
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200214 void update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction);
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200215
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100216 uint8_t tfi() const;
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100217 bool is_tfi_assigned() const;
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100218
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100219 const char *imsi() const;
220 void assign_imsi(const char *imsi);
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200221 uint8_t ta() const;
222 void set_ta(uint8_t);
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200223 uint8_t ms_class() const;
224 void set_ms_class(uint8_t);
Jacob Erlbeckcb728902016-01-05 15:33:03 +0100225 GprsCodingScheme current_cs() const;
Alexander Couzensd38b92e2016-08-21 19:38:30 +0200226 int llc_queue_size() const;
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100227
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100228 time_t created_ts() const;
Jacob Erlbeck617c7122015-06-30 09:18:30 +0200229 uint8_t dl_slots() const;
230 uint8_t ul_slots() const;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100231
Jacob Erlbeck646da1b2016-01-22 17:41:33 +0100232 bool is_control_ts(uint8_t ts) const;
233
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100234 /* EGPRS */
235 bool is_egprs_enabled() const;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100236 void disable_egprs();
237
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100238 /* attempt to make things a bit more fair */
239 void rotate_in_list();
240
Jacob Erlbeck6835cea2015-08-21 15:24:02 +0200241 LListHead<gprs_rlcmac_tbf>& ms_list() {return this->m_ms_list;}
242 const LListHead<gprs_rlcmac_tbf>& ms_list() const {return this->m_ms_list;}
243
Jacob Erlbecked2dbf62015-12-28 19:15:40 +0100244 LListHead<gprs_rlcmac_tbf>& list();
245 const LListHead<gprs_rlcmac_tbf>& list() const;
246
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200247 uint32_t state_flags;
248 enum gprs_rlcmac_tbf_direction direction;
Holger Hans Peter Freyther743bafa2013-09-29 07:50:50 +0200249 struct gprs_rlcmac_trx *trx;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200250 uint8_t first_ts; /* first TS used by TBF */
251 uint8_t first_common_ts; /* first TS that the phone can send and
252 reveive simultaniously */
253 uint8_t control_ts; /* timeslot control messages and polling */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200254 struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */
Holger Hans Peter Freyther28e53782013-11-06 20:23:56 +0100255
256 gprs_llc m_llc;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200257
258 enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state;
259 enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state;
260 enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state;
261
262 enum gprs_rlcmac_tbf_poll_state poll_state;
263 uint32_t poll_fn; /* frame number to poll */
Jacob Erlbeck8eb17142016-01-22 17:58:17 +0100264 uint8_t poll_ts; /* TS to poll */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200265
Holger Hans Peter Freyther9241fd02013-11-13 19:51:55 +0100266 gprs_rlc m_rlc;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200267
268 uint8_t n3105; /* N3105 counter */
269
270 struct osmo_timer_list timer;
271 unsigned int T; /* Txxxx number */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200272
273 struct osmo_gsm_timer_list gsm_timer;
274 unsigned int fT; /* fTxxxx number */
275 unsigned int num_fT_exp; /* number of consecutive fT expirations */
276
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200277 struct Meas {
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200278 struct timeval rssi_tv; /* timestamp for rssi calculation */
279 int32_t rssi_sum; /* sum of rssi values */
280 int rssi_num; /* number of rssi values added since rssi_tv */
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200281
282 Meas();
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200283 } meas;
284
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200285 /* these should become protected but only after gprs_rlcmac_data.c
286 * stops to iterate over all tbf in its current form */
287 enum gprs_rlcmac_tbf_state state;
Holger Hans Peter Freyther9f0c1d22013-10-19 21:24:34 +0200288
Daniel Willmann73191a42014-05-30 17:58:00 +0200289 /* Remember if the tbf was in wait_release state when we want to
290 * schedule a new dl assignment */
291 uint8_t was_releasing;
292
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200293 /* Can/should we upgrade this tbf to use multiple slots? */
294 uint8_t upgrade_to_multislot;
295
Holger Hans Peter Freyther9f0c1d22013-10-19 21:24:34 +0200296 /* store the BTS this TBF belongs to */
297 BTS *bts;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200298
Max59e4a4f2017-12-20 18:01:55 +0100299 uint8_t m_n3101; /* N3101 counter */
300
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100301 /*
302 * private fields. We can't make it private as it is breaking the
303 * llist macros.
304 */
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100305 uint8_t m_tfi;
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100306 time_t m_created_ts;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100307
sivasankari53950732016-12-08 17:15:17 +0530308 struct rate_ctr_group *m_ctrs;
309
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200310protected:
311 gprs_rlcmac_bts *bts_data() const;
Max25a3ca42017-12-13 18:47:52 +0100312 void enable_egprs();
Jacob Erlbecke8f5fe52015-12-14 13:23:15 +0100313 int set_tlli_from_ul(uint32_t new_tlli);
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200314 void merge_and_clear_ms(GprsMs *old_ms);
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100315
Alexander Couzensd38b92e2016-08-21 19:38:30 +0200316 gprs_llc_queue *llc_queue();
317 const gprs_llc_queue *llc_queue() const;
318
Neels Hofmeyr4ea45262016-06-08 15:27:40 +0200319 static const char *tbf_state_name[6];
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100320
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200321 class GprsMs *m_ms;
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200322
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200323 /* Fields to take the TA/MS class values if no MS is associated */
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200324 uint8_t m_ta;
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200325 uint8_t m_ms_class;
Jacob Erlbeck6dbe8222015-05-29 10:37:09 +0200326
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100327private:
Jacob Erlbecked2dbf62015-12-28 19:15:40 +0100328 LListHead<gprs_rlcmac_tbf> m_list;
Jacob Erlbeck6835cea2015-08-21 15:24:02 +0200329 LListHead<gprs_rlcmac_tbf> m_ms_list;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100330 bool m_egprs_enabled;
Maxee5be3a2017-12-20 17:31:13 +0100331 struct osmo_timer_list T31[T_MAX];
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100332 mutable char m_name_buf[60];
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200333};
334
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +0200335
Daniel Willmann0d12a2f2014-07-10 17:44:07 +0200336struct gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100337 int8_t use_trx, uint8_t ms_class, uint8_t egprs_ms_class,
Jacob Erlbecke2e004e2015-06-18 17:16:26 +0200338 uint32_t tlli, uint8_t ta, GprsMs *ms);
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200339
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200340struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck5879c642015-07-10 10:41:36 +0200341 GprsMs *ms, int8_t use_trx,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100342 uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot);
Daniel Willmann48aa0b02014-07-16 18:54:10 +0200343
344struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck5879c642015-07-10 10:41:36 +0200345 GprsMs *ms, int8_t use_trx,
Jacob Erlbeck86b6f052015-11-27 15:17:34 +0100346 uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot);
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200347
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200348void tbf_free(struct gprs_rlcmac_tbf *tbf);
349
aravind sirsikare9a138e2017-01-24 12:36:08 +0530350struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
351 GprsMs *ms, uint32_t tlli, uint8_t trx_no, uint8_t ts_no);
352
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200353int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf);
354
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200355void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
Maxcea806e2017-12-01 17:40:20 +0100356 unsigned int seconds, unsigned int microseconds, const char *reason);
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200357
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200358inline bool gprs_rlcmac_tbf::state_is(enum gprs_rlcmac_tbf_state rhs) const
359{
360 return state == rhs;
361}
362
363inline bool gprs_rlcmac_tbf::state_is_not(enum gprs_rlcmac_tbf_state rhs) const
364{
365 return state != rhs;
366}
367
Daniel Willmanneb100242014-08-08 11:43:53 +0200368const char *tbf_name(gprs_rlcmac_tbf *tbf);
369
Daniel Willmann08e57c82014-08-15 18:11:57 +0200370inline const char *gprs_rlcmac_tbf::state_name() const
371{
372 return tbf_state_name[state];
373}
374
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200375inline void gprs_rlcmac_tbf::set_state(enum gprs_rlcmac_tbf_state new_state)
376{
Daniel Willmanneb100242014-08-08 11:43:53 +0200377 LOGP(DRLCMAC, LOGL_DEBUG, "%s changes state from %s to %s\n",
378 tbf_name(this),
379 tbf_state_name[state], tbf_state_name[new_state]);
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200380 state = new_state;
381}
Holger Hans Peter Freytherbd449f52013-10-27 16:39:36 +0100382
Jacob Erlbecked2dbf62015-12-28 19:15:40 +0100383inline LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list()
384{
385 return this->m_list;
386}
387
388inline const LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list() const
389{
390 return this->m_list;
391}
392
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200393inline GprsMs *gprs_rlcmac_tbf::ms() const
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200394{
395 return m_ms;
396}
397
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100398inline bool gprs_rlcmac_tbf::is_tlli_valid() const
399{
Jacob Erlbeck767193e2015-05-20 12:06:46 +0200400 return tlli() != 0;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100401}
402
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100403inline bool gprs_rlcmac_tbf::is_tfi_assigned() const
404{
405 /* The TBF is established or has been assigned by a IMM.ASS for
406 * download */
Neels Hofmeyr4ea45262016-06-08 15:27:40 +0200407 return state > GPRS_RLCMAC_ASSIGN ||
408 (direction == GPRS_RLCMAC_DL_TBF &&
409 state == GPRS_RLCMAC_ASSIGN &&
410 (state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)));
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100411}
412
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100413inline uint8_t gprs_rlcmac_tbf::tfi() const
414{
415 return m_tfi;
416}
417
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100418inline time_t gprs_rlcmac_tbf::created_ts() const
Daniel Willmann80367aa2014-01-15 17:40:28 +0100419{
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100420 return m_created_ts;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100421}
422
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100423inline bool gprs_rlcmac_tbf::is_egprs_enabled() const
424{
425 return m_egprs_enabled;
426}
427
428inline void gprs_rlcmac_tbf::enable_egprs()
429{
430 m_egprs_enabled = true;
431}
432
433inline void gprs_rlcmac_tbf::disable_egprs()
434{
435 m_egprs_enabled = false;
436}
437
Daniel Willmann078bb712014-07-10 17:44:06 +0200438struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200439 gprs_rlcmac_dl_tbf(BTS *bts);
Jacob Erlbeck444bc822015-08-20 17:49:03 +0200440
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200441 void cleanup();
Max25a3ca42017-12-13 18:47:52 +0100442 void enable_egprs();
Daniel Willmann30168882014-08-07 12:48:29 +0200443 /* dispatch Unitdata.DL messages */
444 static int handle(struct gprs_rlcmac_bts *bts,
Jacob Erlbeck93990462015-05-15 15:50:43 +0200445 const uint32_t tlli, const uint32_t old_tlli,
446 const char *imsi, const uint8_t ms_class,
Jacob Erlbeck14e00f82015-11-27 18:10:39 +0100447 const uint8_t egprs_ms_class, const uint16_t delay_csec,
448 const uint8_t *data, const uint16_t len);
Daniel Willmann30168882014-08-07 12:48:29 +0200449
Daniel Willmann538ac5b2014-07-30 19:12:27 +0200450 int append_data(const uint8_t ms_class,
451 const uint16_t pdu_delay_csec,
452 const uint8_t *data, const uint16_t len);
453
Daniel Willmann6c813fc2014-07-30 19:12:27 +0200454 int rcvd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb);
Jacob Erlbeckeb08f862016-02-05 17:07:12 +0100455 int rcvd_dl_ack(uint8_t final_ack, unsigned first_bsn, struct bitvec *rbb);
Daniel Willmannb8f26012014-07-30 19:12:28 +0200456 struct msgb *create_dl_acked_block(uint32_t fn, uint8_t ts);
Maxa10c3982017-07-07 18:25:41 +0200457 void trigger_ass(struct gprs_rlcmac_tbf *old_tbf);
Maxaae1bfb2017-07-07 13:49:29 +0200458 void clear_poll_timeout_flag();
459 bool handle_ack_nack();
Jacob Erlbeck7c444152015-03-12 12:08:54 +0100460 void request_dl_ack();
Jacob Erlbeckeceb9102015-03-20 14:41:50 +0100461 bool need_control_ts() const;
462 bool have_data() const;
Jacob Erlbeck005ee7f2015-03-20 14:53:54 +0100463 int frames_since_last_poll(unsigned fn) const;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100464 int frames_since_last_drain(unsigned fn) const;
465 bool keep_open(unsigned fn) const;
Jacob Erlbeck91ff7d12015-09-01 11:20:29 +0200466 int release();
Jacob Erlbeckf04a5b32016-01-21 20:42:40 +0100467 int abort();
Jacob Erlbeckeceb9102015-03-20 14:41:50 +0100468
Aravind Sirsikar8e70bb52016-09-15 17:51:16 +0530469 void egprs_calc_window_size();
Mrinal Mishraf86307e2016-11-10 18:16:30 +0530470 void update_coding_scheme_counter_dl(const GprsCodingScheme cs);
Aravind Sirsikar8e70bb52016-09-15 17:51:16 +0530471
Daniel Willmanncf706b02014-08-07 17:35:22 +0200472 /* TODO: add the gettimeofday as parameter */
473 struct msgb *llc_dequeue(bssgp_bvc_ctx *bctx);
474
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200475 /* Please note that all variables here will be reset when changing
476 * from WAIT RELEASE back to FLOW state (re-use of TBF).
477 * All states that need reset must be in this struct, so this is why
478 * variables are in both (dl and ul) structs and not outside union.
479 */
Daniel Willmann7e994e32014-08-07 15:49:21 +0200480 gprs_rlc_dl_window m_window;
481 int32_t m_tx_counter; /* count all transmitted blocks */
482 uint8_t m_wait_confirm; /* wait for CCCH IMM.ASS cnf */
Jacob Erlbeck7c444152015-03-12 12:08:54 +0100483 bool m_dl_ack_requested;
Jacob Erlbeck005ee7f2015-03-20 14:53:54 +0100484 int32_t m_last_dl_poll_fn;
Jacob Erlbeck3bed5d12015-03-19 11:22:38 +0100485 int32_t m_last_dl_drained_fn;
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200486
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200487 struct BandWidth {
Daniel Willmann418a4232014-08-08 11:21:04 +0200488 struct timeval dl_bw_tv; /* timestamp for dl bw calculation */
489 uint32_t dl_bw_octets; /* number of octets since bw_tv */
sivasankari53950732016-12-08 17:15:17 +0530490 uint32_t dl_throughput; /* throughput to be displayed in stats */
Daniel Willmann418a4232014-08-08 11:21:04 +0200491
492 struct timeval dl_loss_tv; /* timestamp for loss calculation */
493 uint16_t dl_loss_lost; /* sum of lost packets */
494 uint16_t dl_loss_received; /* sum of received packets */
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200495
496 BandWidth();
Daniel Willmann418a4232014-08-08 11:21:04 +0200497 } m_bw;
498
sivasankari53950732016-12-08 17:15:17 +0530499 struct rate_ctr_group *m_dl_gprs_ctrs;
500 struct rate_ctr_group *m_dl_egprs_ctrs;
501
Daniel Willmannb8f26012014-07-30 19:12:28 +0200502protected:
Jacob Erlbeck2db0f082015-09-07 18:49:00 +0200503 struct ana_result {
504 unsigned received_packets;
505 unsigned lost_packets;
506 unsigned received_bytes;
507 unsigned lost_bytes;
508 };
509
Jacob Erlbeckd6752492016-02-02 18:12:46 +0100510 int take_next_bsn(uint32_t fn, int previous_bsn,
Jacob Erlbeck64e7b832016-02-04 15:16:47 +0100511 bool *may_combine);
Jacob Erlbeckd6752492016-02-02 18:12:46 +0100512 bool restart_bsn_cycle();
513 int create_new_bsn(const uint32_t fn, GprsCodingScheme cs);
Daniel Willmannb8f26012014-07-30 19:12:28 +0200514 struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,
Jacob Erlbeckbe314d92016-02-02 15:32:10 +0100515 int index, int index2 = -1);
Daniel Willmann30168882014-08-07 12:48:29 +0200516 int update_window(const uint8_t ssn, const uint8_t *rbb);
Jacob Erlbeckeb08f862016-02-05 17:07:12 +0100517 int update_window(unsigned first_bsn, const struct bitvec *rbb);
Daniel Willmann30168882014-08-07 12:48:29 +0200518 int maybe_start_new_window();
519 bool dl_window_stalled() const;
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200520 void reuse_tbf();
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200521 void start_llc_timer();
Jacob Erlbeck2db0f082015-09-07 18:49:00 +0200522 int analyse_errors(char *show_rbb, uint8_t ssn, ana_result *res);
Jacob Erlbeck409efa12015-06-12 14:06:09 +0200523 void schedule_next_frame();
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200524
Aravind Sirsikar50b09702016-08-22 17:21:10 +0530525 enum egprs_rlc_dl_reseg_bsn_state egprs_dl_get_data
526 (int bsn, uint8_t **block_data);
527 unsigned int get_egprs_dl_spb_status(int bsn);
528 enum egprs_rlcmac_dl_spb get_egprs_dl_spb(int bsn);
529
Jacob Erlbeckd0261b72015-04-02 13:58:09 +0200530 struct osmo_timer_list m_llc_timer;
Daniel Willmann078bb712014-07-10 17:44:06 +0200531};
532
533struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200534 gprs_rlcmac_ul_tbf(BTS *bts);
Jacob Erlbeck444bc822015-08-20 17:49:03 +0200535
Jacob Erlbeck5a3c84d2016-01-22 17:25:38 +0100536 struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);
Maxfd13f6c2017-07-07 14:29:36 +0200537 bool ctrl_ack_to_toggle();
538 bool handle_ctrl_ack();
Max25a3ca42017-12-13 18:47:52 +0100539 void enable_egprs();
Daniel Willmann350f64d2014-08-07 14:54:11 +0200540 /* blocks were acked */
Jacob Erlbeckb3100e12015-12-14 13:36:13 +0100541 int rcv_data_block_acknowledged(
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100542 const struct gprs_rlc_data_info *rlc,
Jacob Erlbeckfc1b3e62016-01-11 09:58:11 +0100543 uint8_t *data, struct pcu_l1_meas *meas);
Jacob Erlbeckb3100e12015-12-14 13:36:13 +0100544
Daniel Willmann350f64d2014-08-07 14:54:11 +0200545
Daniel Willmanne2732e22014-08-07 17:32:01 +0200546 /* TODO: extract LLC class? */
547 int assemble_forward_llc(const gprs_rlc_data *data);
548 int snd_ul_ud();
549
Aravind Sirsikar505a86d2016-07-26 18:26:21 +0530550 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(
551 const struct gprs_rlc_data_info *rlc,
552 struct gprs_rlc_data *block,
553 uint8_t *data, const uint8_t block_idx);
554
555 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(
556 const struct gprs_rlc_data_info *rlc,
557 struct gprs_rlc_data *block,
558 uint8_t *data, const uint8_t block_idx);
559
560 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(
561 const struct gprs_rlc_data_info *rlc,
562 struct gprs_rlc_data *block,
563 uint8_t *data, const uint8_t block_idx);
564
sivasankari8adfcd02017-01-16 15:41:21 +0530565 void egprs_calc_ulwindow_size();
566
Mrinal Mishraf86307e2016-11-10 18:16:30 +0530567 void update_coding_scheme_counter_ul(const GprsCodingScheme cs);
568
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200569 /* Please note that all variables here will be reset when changing
570 * from WAIT RELEASE back to FLOW state (re-use of TBF).
571 * All states that need reset must be in this struct, so this is why
572 * variables are in both (dl and ul) structs and not outside union.
573 */
Daniel Willmann7e994e32014-08-07 15:49:21 +0200574 gprs_rlc_ul_window m_window;
575 int32_t m_rx_counter; /* count all received blocks */
576 uint8_t m_n3103; /* N3103 counter */
577 uint8_t m_usf[8]; /* list USFs per PDCH (timeslot) */
578 uint8_t m_contention_resolution_done; /* set after done */
579 uint8_t m_final_ack_sent; /* set if we sent final ack */
Daniel Willmann6a8a1dc2014-08-07 15:14:08 +0200580
sivasankarida7250a2016-12-16 12:57:18 +0530581 struct rate_ctr_group *m_ul_gprs_ctrs;
582 struct rate_ctr_group *m_ul_egprs_ctrs;
583
Daniel Willmann350f64d2014-08-07 14:54:11 +0200584protected:
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100585 void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc);
Daniel Willmann078bb712014-07-10 17:44:06 +0200586};
587
Max701afa42017-12-01 17:13:22 +0100588#ifdef __cplusplus
589extern "C" {
590#endif
591void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);
592void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);
593#ifdef __cplusplus
594}
595#endif
596
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200597inline enum gprs_rlcmac_tbf_direction reverse(enum gprs_rlcmac_tbf_direction dir)
598{
599 return (enum gprs_rlcmac_tbf_direction)
600 ((int)GPRS_RLCMAC_UL_TBF - (int)dir + (int)GPRS_RLCMAC_DL_TBF);
601}
Jacob Erlbeckaa9daa12015-12-28 18:49:12 +0100602
Max25a3ca42017-12-13 18:47:52 +0100603inline void gprs_rlcmac_ul_tbf::enable_egprs()
604{
605 m_window.set_sns(RLC_EGPRS_SNS);
606 gprs_rlcmac_tbf::enable_egprs();
607}
608
609inline void gprs_rlcmac_dl_tbf::enable_egprs()
610{
611 m_window.set_sns(RLC_EGPRS_SNS);
612 gprs_rlcmac_tbf::enable_egprs();
613}
614
Jacob Erlbeckaa9daa12015-12-28 18:49:12 +0100615inline gprs_rlcmac_ul_tbf *as_ul_tbf(gprs_rlcmac_tbf *tbf)
616{
617 if (tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)
618 return static_cast<gprs_rlcmac_ul_tbf *>(tbf);
619 else
620 return NULL;
621}
622
623inline gprs_rlcmac_dl_tbf *as_dl_tbf(gprs_rlcmac_tbf *tbf)
624{
625 if (tbf && tbf->direction == GPRS_RLCMAC_DL_TBF)
626 return static_cast<gprs_rlcmac_dl_tbf *>(tbf);
627 else
628 return NULL;
629}
630
Jacob Erlbeck13965ae2016-01-19 14:10:40 +0100631inline gprs_rlc_window *gprs_rlcmac_tbf::window()
632{
633 switch (direction)
634 {
635 case GPRS_RLCMAC_UL_TBF: return &as_ul_tbf(this)->m_window;
636 case GPRS_RLCMAC_DL_TBF: return &as_dl_tbf(this)->m_window;
637 }
638 return NULL;
639}
640
Daniel Willmannafa72f52014-01-15 17:06:19 +0100641#endif