blob: adc648cef264ff3dfe2a7570a061c9140b5fc6ee [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
Pau Espin Pedrolcd6c4662020-09-22 13:41:00 +020023#include <string>
24
Holger Hans Peter Freytherbe570812013-11-07 08:01:49 +010025#include "llc.h"
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010026#include "rlc.h"
Jacob Erlbeck6835cea2015-08-21 15:24:02 +020027#include "cxx_linuxlist.h"
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010028#include "pcu_utils.h"
Daniel Willmanneb100242014-08-08 11:43:53 +020029#include <gprs_debug.h>
Holger Hans Peter Freyther17c31ce2013-08-24 18:31:27 +020030#include <stdint.h>
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020031
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010032struct bssgp_bvc_ctx;
33struct gprs_rlcmac_bts;
34
35#endif
36
37struct GprsMs;
38
39#ifdef __cplusplus
Maxe66de5b2017-01-05 18:26:58 +010040extern "C" {
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010041#endif
Maxe66de5b2017-01-05 18:26:58 +010042#include <osmocom/core/utils.h>
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020043#include <osmocom/core/linuxlist.h>
44#include <osmocom/core/logging.h>
45#include <osmocom/core/timer.h>
Vadim Yanitskiycb988942020-11-08 13:27:35 +070046#include <osmocom/gsm/gsm48.h>
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +020047
48#include "coding_scheme.h"
Pau Espin Pedrol86580e12021-03-29 18:15:30 +020049#include <pdch_ul_controller.h>
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +020050#include <tbf_fsm.h>
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010051#ifdef __cplusplus
Maxe66de5b2017-01-05 18:26:58 +010052}
Vadim Yanitskiycef2f842019-10-09 21:52:50 +070053#endif
54
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020055/*
56 * TBF instance
57 */
58
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020059enum gprs_rlcmac_tbf_dl_ass_state {
60 GPRS_RLCMAC_DL_ASS_NONE = 0,
61 GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */
62 GPRS_RLCMAC_DL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */
63};
64
Maxe66de5b2017-01-05 18:26:58 +010065extern const struct value_string gprs_rlcmac_tbf_dl_ass_state_names[];
66
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020067enum gprs_rlcmac_tbf_ul_ass_state {
68 GPRS_RLCMAC_UL_ASS_NONE = 0,
69 GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */
aravind sirsikared3413e2016-11-11 17:15:10 +053070 GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ, /* send assignment reject next RTS */
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020071 GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */
72};
73
Maxe66de5b2017-01-05 18:26:58 +010074extern const struct value_string gprs_rlcmac_tbf_ul_ass_state_names[];
75
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020076enum gprs_rlcmac_tbf_ul_ack_state {
77 GPRS_RLCMAC_UL_ACK_NONE = 0,
78 GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */
79 GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */
80};
81
Max088c7df2018-01-23 20:16:23 +010082extern const struct value_string gprs_rlcmac_tbf_ul_ack_state_names[];
83
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020084enum gprs_rlcmac_tbf_direction {
85 GPRS_RLCMAC_DL_TBF,
86 GPRS_RLCMAC_UL_TBF
87};
88
Max847ed9f2018-02-20 18:16:11 +010089enum tbf_rlc_counters {
sivasankari53950732016-12-08 17:15:17 +053090 TBF_CTR_RLC_NACKED,
91};
92
93enum tbf_gprs_counters {
94 TBF_CTR_GPRS_DL_CS1,
95 TBF_CTR_GPRS_DL_CS2,
96 TBF_CTR_GPRS_DL_CS3,
97 TBF_CTR_GPRS_DL_CS4,
98};
99
100enum tbf_egprs_counters {
101 TBF_CTR_EGPRS_DL_MCS1,
102 TBF_CTR_EGPRS_DL_MCS2,
103 TBF_CTR_EGPRS_DL_MCS3,
104 TBF_CTR_EGPRS_DL_MCS4,
105 TBF_CTR_EGPRS_DL_MCS5,
106 TBF_CTR_EGPRS_DL_MCS6,
107 TBF_CTR_EGPRS_DL_MCS7,
108 TBF_CTR_EGPRS_DL_MCS8,
109 TBF_CTR_EGPRS_DL_MCS9,
110};
111
Pau Espin Pedrol442198c2020-10-23 22:30:04 +0200112extern const struct rate_ctr_group_desc tbf_ctrg_desc;
113extern unsigned int next_tbf_ctr_group_id;
114
Max0524e382018-01-19 18:22:25 +0100115#define LOGPTBF(tbf, level, fmt, args...) LOGP(DTBF, level, "%s " fmt, tbf_name(tbf), ## args)
Maxc21f0072017-12-15 17:36:45 +0100116
Maxee5be3a2017-12-20 17:31:13 +0100117enum tbf_timers {
Maxb2de1f72017-12-20 18:05:29 +0100118 /* internal assign/reject timer */
119 T0,
120
Pau Espin Pedrol4b6f0bf2021-05-10 18:54:52 +0200121 /* Wait contention resolution success on UL TBFs assigned over CCCH */
122 T3141,
123
Maxee5be3a2017-12-20 17:31:13 +0100124 /* Wait for reuse of USF and TFI(s) after the MS uplink assignment for this TBF is invalid. */
125 T3169,
126
127 /* Wait for reuse of TFI(s) after sending of the last RLC Data Block on this TBF.
128 Wait for reuse of TFI(s) after sending the PACKET TBF RELEASE for an MBMS radio bearer. */
129 T3191,
130
131 /* Wait for reuse of TFI(s) after reception of the final PACKET DOWNLINK ACK/NACK from the
132 MS for this TBF. */
133 T3193,
134
135 /* Wait for reuse of TFI(s) when there is no response from the MS
136 (radio failure or cell change) for this TBF/MBMS radio bearer. */
137 T3195,
138 T_MAX
139};
140
Max847ed9f2018-02-20 18:16:11 +0100141enum tbf_counters { /* TBF counters from 3GPP TS 44.060 ยง13.4 */
142 /* counters are reset when: */
143 N3101, /* received a valid data block from mobile station in a block assigned for this USF */
144 N3103, /* transmitting the final PACKET UPLINK ACK/NACK message */
145 N3105, /* after sending a RRBP field in the downlink RLC data block, receives a valid RLC/MAC control message */
146 N_MAX
147};
148
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200149#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */
150#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */
151#define GPRS_RLCMAC_FLAG_UL_DATA 2 /* uplink data received */
152#define GPRS_RLCMAC_FLAG_DL_ACK 3 /* downlink acknowledge received */
153#define GPRS_RLCMAC_FLAG_TO_UL_ACK 4
154#define GPRS_RLCMAC_FLAG_TO_DL_ACK 5
155#define GPRS_RLCMAC_FLAG_TO_UL_ASS 6
156#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7
157#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */
158
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +0200159#define T_START(tbf, t, T, r, f) tbf->t_start(t, T, r, f, __FILE__, __LINE__)
Max467f6332017-12-20 18:13:29 +0100160
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200161#define TBF_SET_STATE(t, st) do { tbf_fsm_state_chg(t->state_fsm.fi, st); } while(0)
Max0e599802018-01-23 20:09:06 +0100162#define TBF_SET_ASS_STATE_DL(t, st) do { t->set_ass_state_dl(st, __FILE__, __LINE__); } while(0)
163#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 +0100164#define TBF_SET_ACK_STATE(t, st) do { t->set_ack_state(st, __FILE__, __LINE__); } while(0)
Max2399b1d2018-01-12 15:48:12 +0100165
Vadim Yanitskiycef2f842019-10-09 21:52:50 +0700166#ifdef __cplusplus
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100167extern "C" {
168#endif
169struct gprs_rlcmac_tbf;
Pau Espin Pedrol57dcde42021-02-01 18:14:23 +0100170const char *tbf_name(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200171enum tbf_fsm_states tbf_state(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100172enum gprs_rlcmac_tbf_direction tbf_direction(const struct gprs_rlcmac_tbf *tbf);
173void tbf_set_ms(struct gprs_rlcmac_tbf *tbf, struct GprsMs *ms);
174struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol1a1557a2021-05-13 18:39:36 +0200175struct llist_head *tbf_trx_list(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol1e77ca82021-01-27 13:22:03 +0100176struct GprsMs *tbf_ms(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100177bool tbf_timers_pending(struct gprs_rlcmac_tbf *tbf, enum tbf_timers t);
178void tbf_free(struct gprs_rlcmac_tbf *tbf);
179struct gprs_llc *tbf_llc(struct gprs_rlcmac_tbf *tbf);
180uint8_t tbf_first_common_ts(const struct gprs_rlcmac_tbf *tbf);
181uint8_t tbf_dl_slots(const struct gprs_rlcmac_tbf *tbf);
182uint8_t tbf_ul_slots(const struct gprs_rlcmac_tbf *tbf);
183bool tbf_is_tfi_assigned(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolc0a250d2021-01-21 18:46:13 +0100184uint8_t tbf_tfi(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100185int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol952cb3d2021-02-01 14:52:48 +0100186int tbf_check_polling(const struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts, uint32_t *poll_fn, unsigned int *rrbp);
Pau Espin Pedrol86580e12021-03-29 18:15:30 +0200187void tbf_set_polling(struct gprs_rlcmac_tbf *tbf, uint32_t new_poll_fn, uint8_t ts, enum pdch_ulc_tbf_poll_reason t);
Pau Espin Pedrol16e16782021-03-29 19:10:19 +0200188void tbf_poll_timeout(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch, uint32_t poll_fn, enum pdch_ulc_tbf_poll_reason reason);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200189void tbf_update_state_fsm_name(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100190#ifdef __cplusplus
191}
192#endif
193
194#ifdef __cplusplus
Vadim Yanitskiycef2f842019-10-09 21:52:50 +0700195
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200196struct gprs_rlcmac_tbf {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100197 gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200198 virtual ~gprs_rlcmac_tbf();
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200199
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200200 virtual gprs_rlc_window *window() = 0;
201
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200202 int setup(int8_t use_trx, bool single_slot);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200203 bool state_is(enum tbf_fsm_states rhs) const;
204 bool state_is_not(enum tbf_fsm_states rhs) const;
Max0e599802018-01-23 20:09:06 +0100205 bool dl_ass_state_is(enum gprs_rlcmac_tbf_dl_ass_state rhs) const;
206 bool ul_ass_state_is(enum gprs_rlcmac_tbf_ul_ass_state rhs) const;
Max088c7df2018-01-23 20:16:23 +0100207 bool ul_ack_state_is(enum gprs_rlcmac_tbf_ul_ack_state rhs) const;
Max0e599802018-01-23 20:09:06 +0100208 void set_ass_state_dl(enum gprs_rlcmac_tbf_dl_ass_state new_state, const char *file, int line);
209 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 +0100210 void set_ack_state(enum gprs_rlcmac_tbf_ul_ack_state new_state, const char *file, int line);
Maxcac6b662018-01-24 11:00:17 +0100211 void poll_sched_set(const char *file, int line);
212 void poll_sched_unset(const char *file, int line);
Max8dce1de2018-01-02 14:17:04 +0100213 bool check_n_clear(uint8_t state_flag);
Daniel Willmann08e57c82014-08-15 18:11:57 +0200214 const char *state_name() const;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200215
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100216 const char *name() const;
217
Jacob Erlbeck5a3c84d2016-01-22 17:25:38 +0100218 struct msgb *create_dl_ass(uint32_t fn, uint8_t ts);
219 struct msgb *create_ul_ass(uint32_t fn, uint8_t ts);
aravind sirsikared3413e2016-11-11 17:15:10 +0530220 struct msgb *create_packet_access_reject();
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200221
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200222 GprsMs *ms() const;
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200223 void set_ms(GprsMs *ms);
224
Holger Hans Peter Freyther8f399de2013-12-25 20:22:35 +0100225 uint8_t tsc() const;
Holger Hans Peter Freythera1da2512013-11-07 07:32:51 +0100226
Pau Espin Pedrolcd6c4662020-09-22 13:41:00 +0200227 std::string rlcmac_diag();
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200228
Max847ed9f2018-02-20 18:16:11 +0100229 bool n_inc(enum tbf_counters n);
230 void n_reset(enum tbf_counters n);
231
Jacob Erlbecke0c734d2015-07-03 14:03:33 +0200232 int update();
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200233 void handle_timeout();
Maxee5be3a2017-12-20 17:31:13 +0100234 void stop_timers(const char *reason);
235 bool timers_pending(enum tbf_timers t);
236 void t_stop(enum tbf_timers t, const char *reason);
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +0200237 void t_start(enum tbf_timers t, int T, const char *reason, bool force,
Max467f6332017-12-20 18:13:29 +0100238 const char *file, unsigned line);
Jacob Erlbeck91ff7d12015-09-01 11:20:29 +0200239 int establish_dl_tbf_on_pacch();
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200240
Jacob Erlbeckf2694b72016-01-26 21:46:26 +0100241 int check_polling(uint32_t fn, uint8_t ts,
Pau Espin Pedrol57dcde42021-02-01 18:14:23 +0100242 uint32_t *poll_fn, unsigned int *rrbp) const;
Pau Espin Pedrol86580e12021-03-29 18:15:30 +0200243 void set_polling(uint32_t poll_fn, uint8_t ts, enum pdch_ulc_tbf_poll_reason reason);
Pau Espin Pedrol16e16782021-03-29 19:10:19 +0200244 void poll_timeout(struct gprs_rlcmac_pdch *pdch, uint32_t poll_fn, enum pdch_ulc_tbf_poll_reason reason);
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200245
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100246 /** tlli handling */
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100247 uint32_t tlli() const;
248 bool is_tlli_valid() const;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100249
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200250 /** MS updating */
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200251 void update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction);
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200252
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100253 uint8_t tfi() const;
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100254 bool is_tfi_assigned() const;
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100255
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100256 const char *imsi() const;
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200257 uint8_t ta() const;
258 void set_ta(uint8_t);
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200259 uint8_t ms_class() const;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200260 enum CodingScheme current_cs() const;
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100261
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100262 time_t created_ts() const;
Jacob Erlbeck617c7122015-06-30 09:18:30 +0200263 uint8_t dl_slots() const;
264 uint8_t ul_slots() const;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100265
Jacob Erlbeck646da1b2016-01-22 17:41:33 +0100266 bool is_control_ts(uint8_t ts) const;
267
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100268 /* EGPRS */
269 bool is_egprs_enabled() const;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100270
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100271 /* attempt to make things a bit more fair */
272 void rotate_in_list();
273
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200274 enum gprs_rlcmac_tbf_direction direction;
Holger Hans Peter Freyther743bafa2013-09-29 07:50:50 +0200275 struct gprs_rlcmac_trx *trx;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200276 uint8_t first_ts; /* first TS used by TBF */
Pau Espin Pedrol01aef5e2020-09-22 19:08:57 +0200277 uint8_t first_common_ts; /* first TS where the phone can send and
278 receive simultaniously */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200279 uint8_t control_ts; /* timeslot control messages and polling */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200280 struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */
Holger Hans Peter Freyther28e53782013-11-06 20:23:56 +0100281
282 gprs_llc m_llc;
Holger Hans Peter Freyther9241fd02013-11-13 19:51:55 +0100283 gprs_rlc m_rlc;
Max847ed9f2018-02-20 18:16:11 +0100284
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200285 unsigned int fT; /* fTxxxx number */
286 unsigned int num_fT_exp; /* number of consecutive fT expirations */
287
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200288 struct Meas {
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200289 struct timespec rssi_tv; /* timestamp for rssi calculation */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200290 int32_t rssi_sum; /* sum of rssi values */
291 int rssi_num; /* number of rssi values added since rssi_tv */
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200292
293 Meas();
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200294 } meas;
295
Daniel Willmann73191a42014-05-30 17:58:00 +0200296 /* Remember if the tbf was in wait_release state when we want to
297 * schedule a new dl assignment */
298 uint8_t was_releasing;
299
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200300 /* Can/should we upgrade this tbf to use multiple slots? */
301 uint8_t upgrade_to_multislot;
302
Holger Hans Peter Freyther9f0c1d22013-10-19 21:24:34 +0200303 /* store the BTS this TBF belongs to */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100304 struct gprs_rlcmac_bts *bts;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200305
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100306 /*
307 * private fields. We can't make it private as it is breaking the
308 * llist macros.
309 */
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100310 uint8_t m_tfi;
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100311 time_t m_created_ts;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100312
sivasankari53950732016-12-08 17:15:17 +0530313 struct rate_ctr_group *m_ctrs;
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200314 struct tbf_fsm_ctx state_fsm;
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100315 struct llist_item m_ms_list;
Pau Espin Pedrol1a1557a2021-05-13 18:39:36 +0200316 struct llist_item m_trx_list;
sivasankari53950732016-12-08 17:15:17 +0530317
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200318protected:
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200319 void merge_and_clear_ms(GprsMs *old_ms);
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100320
Alexander Couzensd38b92e2016-08-21 19:38:30 +0200321 gprs_llc_queue *llc_queue();
322 const gprs_llc_queue *llc_queue() const;
323
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100324 struct GprsMs *m_ms;
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100325private:
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200326 void enable_egprs();
Max0e599802018-01-23 20:09:06 +0100327 enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state;
328 enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state;
Max088c7df2018-01-23 20:16:23 +0100329 enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100330 bool m_egprs_enabled;
Pau Espin Pedrolef1fe582019-09-05 14:40:24 +0200331 struct osmo_timer_list Tarr[T_MAX];
332 uint8_t Narr[N_MAX];
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100333 mutable char m_name_buf[60];
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200334};
335
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200336inline bool gprs_rlcmac_tbf::state_is(enum tbf_fsm_states rhs) const
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200337{
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200338 return tbf_state(this) == rhs;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200339}
340
Max0e599802018-01-23 20:09:06 +0100341inline bool gprs_rlcmac_tbf::dl_ass_state_is(enum gprs_rlcmac_tbf_dl_ass_state rhs) const
342{
343 return dl_ass_state == rhs;
344}
345
346inline bool gprs_rlcmac_tbf::ul_ass_state_is(enum gprs_rlcmac_tbf_ul_ass_state rhs) const
347{
348 return ul_ass_state == rhs;
349}
350
Max088c7df2018-01-23 20:16:23 +0100351inline bool gprs_rlcmac_tbf::ul_ack_state_is(enum gprs_rlcmac_tbf_ul_ack_state rhs) const
352{
353 return ul_ack_state == rhs;
354}
355
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200356inline bool gprs_rlcmac_tbf::state_is_not(enum tbf_fsm_states rhs) const
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200357{
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200358 return tbf_state(this) != rhs;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200359}
360
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200361
Daniel Willmann08e57c82014-08-15 18:11:57 +0200362inline const char *gprs_rlcmac_tbf::state_name() const
363{
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200364 return osmo_fsm_inst_state_name(state_fsm.fi);
Daniel Willmann08e57c82014-08-15 18:11:57 +0200365}
366
Max0e599802018-01-23 20:09:06 +0100367inline void gprs_rlcmac_tbf::set_ass_state_dl(enum gprs_rlcmac_tbf_dl_ass_state new_state, const char *file, int line)
368{
369 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes DL ASS state from %s to %s\n",
370 tbf_name(this),
371 get_value_string(gprs_rlcmac_tbf_dl_ass_state_names, dl_ass_state),
372 get_value_string(gprs_rlcmac_tbf_dl_ass_state_names, new_state));
373 dl_ass_state = new_state;
374}
375
376inline void gprs_rlcmac_tbf::set_ass_state_ul(enum gprs_rlcmac_tbf_ul_ass_state new_state, const char *file, int line)
377{
378 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes UL ASS state from %s to %s\n",
379 tbf_name(this),
380 get_value_string(gprs_rlcmac_tbf_ul_ass_state_names, ul_ass_state),
381 get_value_string(gprs_rlcmac_tbf_ul_ass_state_names, new_state));
382 ul_ass_state = new_state;
383}
384
Max088c7df2018-01-23 20:16:23 +0100385inline void gprs_rlcmac_tbf::set_ack_state(enum gprs_rlcmac_tbf_ul_ack_state new_state, const char *file, int line)
386{
387 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes UL ACK state from %s to %s\n",
388 tbf_name(this),
389 get_value_string(gprs_rlcmac_tbf_ul_ack_state_names, ul_ack_state),
390 get_value_string(gprs_rlcmac_tbf_ul_ack_state_names, new_state));
391 ul_ack_state = new_state;
392}
393
Max8dce1de2018-01-02 14:17:04 +0100394inline bool gprs_rlcmac_tbf::check_n_clear(uint8_t state_flag)
395{
Pau Espin Pedrol33e80072021-07-22 19:20:50 +0200396 if ((state_fsm.state_flags & (1 << state_flag))) {
397 state_fsm.state_flags &= ~(1 << state_flag);
Max8dce1de2018-01-02 14:17:04 +0100398 return true;
399 }
400
401 return false;
402}
403
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200404inline GprsMs *gprs_rlcmac_tbf::ms() const
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200405{
406 return m_ms;
407}
408
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100409inline bool gprs_rlcmac_tbf::is_tlli_valid() const
410{
Vadim Yanitskiycb988942020-11-08 13:27:35 +0700411 return tlli() != GSM_RESERVED_TMSI;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100412}
413
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100414inline bool gprs_rlcmac_tbf::is_tfi_assigned() const
415{
416 /* The TBF is established or has been assigned by a IMM.ASS for
417 * download */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200418 return state_fsm.fi->state > TBF_ST_ASSIGN ||
Neels Hofmeyr4ea45262016-06-08 15:27:40 +0200419 (direction == GPRS_RLCMAC_DL_TBF &&
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200420 state_fsm.fi->state == TBF_ST_ASSIGN &&
Pau Espin Pedrol33e80072021-07-22 19:20:50 +0200421 (state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)));
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100422}
423
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100424inline uint8_t gprs_rlcmac_tbf::tfi() const
425{
426 return m_tfi;
427}
428
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100429inline time_t gprs_rlcmac_tbf::created_ts() const
Daniel Willmann80367aa2014-01-15 17:40:28 +0100430{
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100431 return m_created_ts;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100432}
433
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100434inline bool gprs_rlcmac_tbf::is_egprs_enabled() const
435{
436 return m_egprs_enabled;
437}
438
439inline void gprs_rlcmac_tbf::enable_egprs()
440{
441 m_egprs_enabled = true;
Pau Espin Pedrol7bde60f2020-10-23 21:21:09 +0200442 window()->set_sns(RLC_EGPRS_SNS);
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100443}
444
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200445inline enum gprs_rlcmac_tbf_direction reverse(enum gprs_rlcmac_tbf_direction dir)
446{
447 return (enum gprs_rlcmac_tbf_direction)
448 ((int)GPRS_RLCMAC_UL_TBF - (int)dir + (int)GPRS_RLCMAC_DL_TBF);
449}
Jacob Erlbeckaa9daa12015-12-28 18:49:12 +0100450
Pau Espin Pedrol0ece97d2021-01-18 12:53:54 +0100451uint16_t egprs_window_size(const struct gprs_rlcmac_bts *bts, uint8_t slots);
Max9d7357e2017-12-14 15:02:33 +0100452
Daniel Willmannafa72f52014-01-15 17:06:19 +0100453#endif