blob: 358a7ad6effc4bdab85a0d7cd07bcbebd7a7bd60 [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 Pedrol6ad11a62021-07-27 12:27:08 +020051#include <tbf_ul_ass_fsm.h>
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +020052#include <tbf_dl_ass_fsm.h>
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +010053#ifdef __cplusplus
Maxe66de5b2017-01-05 18:26:58 +010054}
Vadim Yanitskiycef2f842019-10-09 21:52:50 +070055#endif
56
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020057/*
58 * TBF instance
59 */
60
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020061enum gprs_rlcmac_tbf_ul_ack_state {
62 GPRS_RLCMAC_UL_ACK_NONE = 0,
63 GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */
64 GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */
65};
66
Max088c7df2018-01-23 20:16:23 +010067extern const struct value_string gprs_rlcmac_tbf_ul_ack_state_names[];
68
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +020069enum gprs_rlcmac_tbf_direction {
70 GPRS_RLCMAC_DL_TBF,
71 GPRS_RLCMAC_UL_TBF
72};
73
Max847ed9f2018-02-20 18:16:11 +010074enum tbf_rlc_counters {
sivasankari53950732016-12-08 17:15:17 +053075 TBF_CTR_RLC_NACKED,
76};
77
78enum tbf_gprs_counters {
79 TBF_CTR_GPRS_DL_CS1,
80 TBF_CTR_GPRS_DL_CS2,
81 TBF_CTR_GPRS_DL_CS3,
82 TBF_CTR_GPRS_DL_CS4,
83};
84
85enum tbf_egprs_counters {
86 TBF_CTR_EGPRS_DL_MCS1,
87 TBF_CTR_EGPRS_DL_MCS2,
88 TBF_CTR_EGPRS_DL_MCS3,
89 TBF_CTR_EGPRS_DL_MCS4,
90 TBF_CTR_EGPRS_DL_MCS5,
91 TBF_CTR_EGPRS_DL_MCS6,
92 TBF_CTR_EGPRS_DL_MCS7,
93 TBF_CTR_EGPRS_DL_MCS8,
94 TBF_CTR_EGPRS_DL_MCS9,
95};
96
Pau Espin Pedrol442198c2020-10-23 22:30:04 +020097extern const struct rate_ctr_group_desc tbf_ctrg_desc;
98extern unsigned int next_tbf_ctr_group_id;
99
Max0524e382018-01-19 18:22:25 +0100100#define LOGPTBF(tbf, level, fmt, args...) LOGP(DTBF, level, "%s " fmt, tbf_name(tbf), ## args)
Maxc21f0072017-12-15 17:36:45 +0100101
Maxee5be3a2017-12-20 17:31:13 +0100102enum tbf_timers {
Pau Espin Pedrol4b6f0bf2021-05-10 18:54:52 +0200103 /* Wait contention resolution success on UL TBFs assigned over CCCH */
104 T3141,
105
Maxee5be3a2017-12-20 17:31:13 +0100106 /* Wait for reuse of TFI(s) after sending of the last RLC Data Block on this TBF.
107 Wait for reuse of TFI(s) after sending the PACKET TBF RELEASE for an MBMS radio bearer. */
108 T3191,
109
110 /* Wait for reuse of TFI(s) after reception of the final PACKET DOWNLINK ACK/NACK from the
111 MS for this TBF. */
112 T3193,
113
Maxee5be3a2017-12-20 17:31:13 +0100114 T_MAX
115};
116
Max847ed9f2018-02-20 18:16:11 +0100117enum tbf_counters { /* TBF counters from 3GPP TS 44.060 ยง13.4 */
118 /* counters are reset when: */
119 N3101, /* received a valid data block from mobile station in a block assigned for this USF */
120 N3103, /* transmitting the final PACKET UPLINK ACK/NACK message */
121 N3105, /* after sending a RRBP field in the downlink RLC data block, receives a valid RLC/MAC control message */
122 N_MAX
123};
124
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200125#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */
126#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */
Pau Espin Pedrol3e48cfd2021-07-29 18:29:56 +0200127#define GPRS_RLCMAC_FLAG_DL_ACK 2 /* DL TBF: At least one DL ACK/NACK was recieved since it was assigned */
128#define GPRS_RLCMAC_FLAG_TO_UL_ACK 3 /* UL TBF: Failed to receive last polled CTRL ACK confirming our UL ACK/NACK */
129#define GPRS_RLCMAC_FLAG_TO_DL_ACK 4 /* DL TBF: Failed to receive last polled DL ACK/NACK */
Holger Hans Peter Freyther9e21d842013-10-16 17:48:12 +0200130#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */
131
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +0200132#define T_START(tbf, t, T, r, f) tbf->t_start(t, T, r, f, __FILE__, __LINE__)
Max088c7df2018-01-23 20:16:23 +0100133#define TBF_SET_ACK_STATE(t, st) do { t->set_ack_state(st, __FILE__, __LINE__); } while(0)
Max2399b1d2018-01-12 15:48:12 +0100134
Vadim Yanitskiycef2f842019-10-09 21:52:50 +0700135#ifdef __cplusplus
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100136extern "C" {
137#endif
138struct gprs_rlcmac_tbf;
Pau Espin Pedrol57dcde42021-02-01 18:14:23 +0100139const char *tbf_name(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200140enum tbf_fsm_states tbf_state(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200141struct osmo_fsm_inst *tbf_ul_ass_fi(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200142struct osmo_fsm_inst *tbf_dl_ass_fi(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100143enum gprs_rlcmac_tbf_direction tbf_direction(const struct gprs_rlcmac_tbf *tbf);
144void tbf_set_ms(struct gprs_rlcmac_tbf *tbf, struct GprsMs *ms);
145struct llist_head *tbf_ms_list(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol1a1557a2021-05-13 18:39:36 +0200146struct llist_head *tbf_trx_list(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol1e77ca82021-01-27 13:22:03 +0100147struct GprsMs *tbf_ms(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100148bool tbf_timers_pending(struct gprs_rlcmac_tbf *tbf, enum tbf_timers t);
149void tbf_free(struct gprs_rlcmac_tbf *tbf);
150struct gprs_llc *tbf_llc(struct gprs_rlcmac_tbf *tbf);
151uint8_t tbf_first_common_ts(const struct gprs_rlcmac_tbf *tbf);
152uint8_t tbf_dl_slots(const struct gprs_rlcmac_tbf *tbf);
153uint8_t tbf_ul_slots(const struct gprs_rlcmac_tbf *tbf);
154bool tbf_is_tfi_assigned(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolc0a250d2021-01-21 18:46:13 +0100155uint8_t tbf_tfi(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200156bool tbf_is_egprs_enabled(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100157int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol952cb3d2021-02-01 14:52:48 +0100158int 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 +0200159void 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 +0200160void 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 +0200161void tbf_update_state_fsm_name(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolab8fba32021-07-27 16:35:00 +0200162const char* tbf_rlcmac_diag(const struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200163bool tbf_is_control_ts(const struct gprs_rlcmac_tbf *tbf, uint8_t ts);
Pau Espin Pedrol32252902021-07-29 16:44:11 +0200164bool tbf_can_upgrade_to_multislot(const struct gprs_rlcmac_tbf *tbf);
165int tbf_update(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100166#ifdef __cplusplus
167}
168#endif
169
170#ifdef __cplusplus
Vadim Yanitskiycef2f842019-10-09 21:52:50 +0700171
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200172struct gprs_rlcmac_tbf {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100173 gprs_rlcmac_tbf(struct gprs_rlcmac_bts *bts_, GprsMs *ms, gprs_rlcmac_tbf_direction dir);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200174 virtual ~gprs_rlcmac_tbf();
Holger Hans Peter Freyther964ddb62013-10-16 17:53:23 +0200175
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +0200176 virtual gprs_rlc_window *window() = 0;
177
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200178 int setup(int8_t use_trx, bool single_slot);
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200179 bool state_is(enum tbf_fsm_states rhs) const;
180 bool state_is_not(enum tbf_fsm_states rhs) const;
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200181 bool dl_ass_state_is(enum tbf_dl_ass_fsm_states rhs) const;
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200182 bool ul_ass_state_is(enum tbf_ul_ass_fsm_states rhs) const;
Max088c7df2018-01-23 20:16:23 +0100183 bool ul_ack_state_is(enum gprs_rlcmac_tbf_ul_ack_state rhs) const;
Max088c7df2018-01-23 20:16:23 +0100184 void set_ack_state(enum gprs_rlcmac_tbf_ul_ack_state new_state, const char *file, int line);
Maxcac6b662018-01-24 11:00:17 +0100185 void poll_sched_set(const char *file, int line);
186 void poll_sched_unset(const char *file, int line);
Max8dce1de2018-01-02 14:17:04 +0100187 bool check_n_clear(uint8_t state_flag);
Daniel Willmann08e57c82014-08-15 18:11:57 +0200188 const char *state_name() const;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200189
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100190 const char *name() const;
191
Jacob Erlbeck5a3c84d2016-01-22 17:25:38 +0100192 struct msgb *create_dl_ass(uint32_t fn, uint8_t ts);
Holger Hans Peter Freyther2db7e7e2013-10-26 20:45:35 +0200193
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200194 GprsMs *ms() const;
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200195 void set_ms(GprsMs *ms);
196
Holger Hans Peter Freyther8f399de2013-12-25 20:22:35 +0100197 uint8_t tsc() const;
Holger Hans Peter Freythera1da2512013-11-07 07:32:51 +0100198
Max847ed9f2018-02-20 18:16:11 +0100199 bool n_inc(enum tbf_counters n);
200 void n_reset(enum tbf_counters n);
201
Jacob Erlbecke0c734d2015-07-03 14:03:33 +0200202 int update();
Holger Hans Peter Freytheraf8094d2013-10-26 17:56:15 +0200203 void handle_timeout();
Maxee5be3a2017-12-20 17:31:13 +0100204 void stop_timers(const char *reason);
205 bool timers_pending(enum tbf_timers t);
206 void t_stop(enum tbf_timers t, const char *reason);
Pau Espin Pedrol28f160e2019-09-05 14:48:35 +0200207 void t_start(enum tbf_timers t, int T, const char *reason, bool force,
Max467f6332017-12-20 18:13:29 +0100208 const char *file, unsigned line);
Jacob Erlbeck91ff7d12015-09-01 11:20:29 +0200209 int establish_dl_tbf_on_pacch();
Holger Hans Peter Freytheraa9c3262013-10-26 17:49:36 +0200210
Jacob Erlbeckf2694b72016-01-26 21:46:26 +0100211 int check_polling(uint32_t fn, uint8_t ts,
Pau Espin Pedrol57dcde42021-02-01 18:14:23 +0100212 uint32_t *poll_fn, unsigned int *rrbp) const;
Pau Espin Pedrol86580e12021-03-29 18:15:30 +0200213 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 +0200214 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 +0200215
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100216 /** tlli handling */
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100217 uint32_t tlli() const;
218 bool is_tlli_valid() const;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100219
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200220 /** MS updating */
Jacob Erlbeckbe0cbc12015-05-18 14:35:11 +0200221 void update_ms(uint32_t tlli, enum gprs_rlcmac_tbf_direction);
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200222
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100223 uint8_t tfi() const;
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100224 bool is_tfi_assigned() const;
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100225
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100226 const char *imsi() const;
Jacob Erlbeck9200ce62015-05-22 17:48:04 +0200227 uint8_t ta() const;
228 void set_ta(uint8_t);
Jacob Erlbeckbefc7602015-06-02 12:33:30 +0200229 uint8_t ms_class() const;
Pau Espin Pedrol2ae83372020-05-18 11:35:35 +0200230 enum CodingScheme current_cs() const;
Holger Hans Peter Freyther5464c9b2013-10-27 20:57:35 +0100231
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100232 time_t created_ts() const;
Jacob Erlbeck617c7122015-06-30 09:18:30 +0200233 uint8_t dl_slots() const;
234 uint8_t ul_slots() const;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100235
Jacob Erlbeck646da1b2016-01-22 17:41:33 +0100236 bool is_control_ts(uint8_t ts) const;
237
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100238 /* EGPRS */
239 bool is_egprs_enabled() const;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100240
Holger Hans Peter Freyther7a5f3c22013-11-26 13:08:12 +0100241 /* attempt to make things a bit more fair */
242 void rotate_in_list();
243
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200244 enum gprs_rlcmac_tbf_direction direction;
Holger Hans Peter Freyther743bafa2013-09-29 07:50:50 +0200245 struct gprs_rlcmac_trx *trx;
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200246 uint8_t first_ts; /* first TS used by TBF */
Pau Espin Pedrol01aef5e2020-09-22 19:08:57 +0200247 uint8_t first_common_ts; /* first TS where the phone can send and
248 receive simultaniously */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200249 uint8_t control_ts; /* timeslot control messages and polling */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200250 struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */
Holger Hans Peter Freyther28e53782013-11-06 20:23:56 +0100251
252 gprs_llc m_llc;
Holger Hans Peter Freyther9241fd02013-11-13 19:51:55 +0100253 gprs_rlc m_rlc;
Max847ed9f2018-02-20 18:16:11 +0100254
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200255 unsigned int fT; /* fTxxxx number */
256 unsigned int num_fT_exp; /* number of consecutive fT expirations */
257
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200258 struct Meas {
Stefan Sperlingf0f7df12018-05-25 15:12:30 +0200259 struct timespec rssi_tv; /* timestamp for rssi calculation */
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200260 int32_t rssi_sum; /* sum of rssi values */
261 int rssi_num; /* number of rssi values added since rssi_tv */
Jacob Erlbeckb6b3c7e2015-08-28 12:07:14 +0200262
263 Meas();
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200264 } meas;
265
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200266 /* Can/should we upgrade this tbf to use multiple slots? */
Pau Espin Pedrol907f0372021-07-29 16:34:04 +0200267 bool upgrade_to_multislot;
Daniel Willmanncf1fae72014-05-30 17:58:01 +0200268
Holger Hans Peter Freyther9f0c1d22013-10-19 21:24:34 +0200269 /* store the BTS this TBF belongs to */
Pau Espin Pedrol2182e622021-01-14 16:48:38 +0100270 struct gprs_rlcmac_bts *bts;
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200271
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100272 /*
273 * private fields. We can't make it private as it is breaking the
274 * llist macros.
275 */
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100276 uint8_t m_tfi;
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100277 time_t m_created_ts;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100278
sivasankari53950732016-12-08 17:15:17 +0530279 struct rate_ctr_group *m_ctrs;
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200280 struct tbf_fsm_ctx state_fsm;
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200281 struct tbf_ul_ass_fsm_ctx ul_ass_fsm;
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200282 struct tbf_ul_ass_fsm_ctx dl_ass_fsm;
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200283
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100284 struct llist_item m_ms_list;
Pau Espin Pedrol1a1557a2021-05-13 18:39:36 +0200285 struct llist_item m_trx_list;
sivasankari53950732016-12-08 17:15:17 +0530286
Holger Hans Peter Freytherd9262b32013-10-26 20:12:59 +0200287protected:
Jacob Erlbeck28c40b12015-08-16 18:19:32 +0200288 void merge_and_clear_ms(GprsMs *old_ms);
Holger Hans Peter Freyther4c06d912013-11-25 23:05:26 +0100289
Alexander Couzensd38b92e2016-08-21 19:38:30 +0200290 gprs_llc_queue *llc_queue();
291 const gprs_llc_queue *llc_queue() const;
292
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100293 struct GprsMs *m_ms;
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100294private:
Pau Espin Pedrole9f77d32020-10-23 18:41:40 +0200295 void enable_egprs();
Max088c7df2018-01-23 20:16:23 +0100296 enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state;
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100297 bool m_egprs_enabled;
Pau Espin Pedrolef1fe582019-09-05 14:40:24 +0200298 struct osmo_timer_list Tarr[T_MAX];
299 uint8_t Narr[N_MAX];
Jacob Erlbeckadcdf152015-03-03 14:45:55 +0100300 mutable char m_name_buf[60];
Holger Hans Peter Freyther099535a2013-10-16 17:42:31 +0200301};
302
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200303inline bool gprs_rlcmac_tbf::state_is(enum tbf_fsm_states rhs) const
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200304{
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200305 return tbf_state(this) == rhs;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200306}
307
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200308inline bool gprs_rlcmac_tbf::dl_ass_state_is(enum tbf_dl_ass_fsm_states rhs) const
Max0e599802018-01-23 20:09:06 +0100309{
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200310 return tbf_dl_ass_fi(this)->state == rhs;
Max0e599802018-01-23 20:09:06 +0100311}
312
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200313inline bool gprs_rlcmac_tbf::ul_ass_state_is(enum tbf_ul_ass_fsm_states rhs) const
Max0e599802018-01-23 20:09:06 +0100314{
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200315 return tbf_ul_ass_fi(this)->state == rhs;
Max0e599802018-01-23 20:09:06 +0100316}
317
Max088c7df2018-01-23 20:16:23 +0100318inline bool gprs_rlcmac_tbf::ul_ack_state_is(enum gprs_rlcmac_tbf_ul_ack_state rhs) const
319{
320 return ul_ack_state == rhs;
321}
322
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200323inline bool gprs_rlcmac_tbf::state_is_not(enum tbf_fsm_states rhs) const
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200324{
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200325 return tbf_state(this) != rhs;
Holger Hans Peter Freyther1c344e22013-10-16 18:33:18 +0200326}
327
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200328
Daniel Willmann08e57c82014-08-15 18:11:57 +0200329inline const char *gprs_rlcmac_tbf::state_name() const
330{
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200331 return osmo_fsm_inst_state_name(state_fsm.fi);
Daniel Willmann08e57c82014-08-15 18:11:57 +0200332}
333
Max088c7df2018-01-23 20:16:23 +0100334inline void gprs_rlcmac_tbf::set_ack_state(enum gprs_rlcmac_tbf_ul_ack_state new_state, const char *file, int line)
335{
336 LOGPSRC(DTBF, LOGL_DEBUG, file, line, "%s changes UL ACK state from %s to %s\n",
337 tbf_name(this),
338 get_value_string(gprs_rlcmac_tbf_ul_ack_state_names, ul_ack_state),
339 get_value_string(gprs_rlcmac_tbf_ul_ack_state_names, new_state));
340 ul_ack_state = new_state;
341}
342
Max8dce1de2018-01-02 14:17:04 +0100343inline bool gprs_rlcmac_tbf::check_n_clear(uint8_t state_flag)
344{
Pau Espin Pedrol33e80072021-07-22 19:20:50 +0200345 if ((state_fsm.state_flags & (1 << state_flag))) {
346 state_fsm.state_flags &= ~(1 << state_flag);
Max8dce1de2018-01-02 14:17:04 +0100347 return true;
348 }
349
350 return false;
351}
352
Jacob Erlbeck10ed7952015-06-02 11:37:22 +0200353inline GprsMs *gprs_rlcmac_tbf::ms() const
Jacob Erlbeckfecece02015-05-08 12:13:08 +0200354{
355 return m_ms;
356}
357
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100358inline bool gprs_rlcmac_tbf::is_tlli_valid() const
359{
Vadim Yanitskiycb988942020-11-08 13:27:35 +0700360 return tlli() != GSM_RESERVED_TMSI;
Holger Hans Peter Freyther474685e2013-10-27 17:01:14 +0100361}
362
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100363inline bool gprs_rlcmac_tbf::is_tfi_assigned() const
364{
365 /* The TBF is established or has been assigned by a IMM.ASS for
366 * download */
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200367 return state_fsm.fi->state > TBF_ST_ASSIGN ||
Neels Hofmeyr4ea45262016-06-08 15:27:40 +0200368 (direction == GPRS_RLCMAC_DL_TBF &&
Pau Espin Pedroldc2aaac2021-05-14 12:50:46 +0200369 state_fsm.fi->state == TBF_ST_ASSIGN &&
Pau Espin Pedrol33e80072021-07-22 19:20:50 +0200370 (state_fsm.state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)));
Jacob Erlbeck6b356a52016-01-29 16:39:21 +0100371}
372
Holger Hans Peter Freyther34f6e5e2013-10-27 20:31:47 +0100373inline uint8_t gprs_rlcmac_tbf::tfi() const
374{
375 return m_tfi;
376}
377
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100378inline time_t gprs_rlcmac_tbf::created_ts() const
Daniel Willmann80367aa2014-01-15 17:40:28 +0100379{
Holger Hans Peter Freythera0047992014-01-16 10:07:20 +0100380 return m_created_ts;
Daniel Willmann80367aa2014-01-15 17:40:28 +0100381}
382
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100383inline bool gprs_rlcmac_tbf::is_egprs_enabled() const
384{
385 return m_egprs_enabled;
386}
387
388inline void gprs_rlcmac_tbf::enable_egprs()
389{
390 m_egprs_enabled = true;
Pau Espin Pedrol7bde60f2020-10-23 21:21:09 +0200391 window()->set_sns(RLC_EGPRS_SNS);
Jacob Erlbeck5643f352015-11-27 16:17:40 +0100392}
393
Jacob Erlbeckac89a552015-06-29 14:18:46 +0200394inline enum gprs_rlcmac_tbf_direction reverse(enum gprs_rlcmac_tbf_direction dir)
395{
396 return (enum gprs_rlcmac_tbf_direction)
397 ((int)GPRS_RLCMAC_UL_TBF - (int)dir + (int)GPRS_RLCMAC_DL_TBF);
398}
Jacob Erlbeckaa9daa12015-12-28 18:49:12 +0100399
Pau Espin Pedrol0ece97d2021-01-18 12:53:54 +0100400uint16_t egprs_window_size(const struct gprs_rlcmac_bts *bts, uint8_t slots);
Max9d7357e2017-12-14 15:02:33 +0100401
Daniel Willmannafa72f52014-01-15 17:06:19 +0100402#endif