blob: defdfba85ec541c2ae5bebfc8eccdaa1e70a3b6d [file] [log] [blame]
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +02001/*
2 * Copyright (C) 2013 by Holger Hans Peter Freyther
3 * Copyright (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#pragma once
21
22#ifdef __cplusplus
23
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +020024#include <stdbool.h>
25
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020026#include "tbf.h"
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +020027
28#ifdef __cplusplus
29extern "C" {
30#endif
31#include <tbf_ul_ack_fsm.h>
32#ifdef __cplusplus
33}
34#endif
35
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020036/*
37 * TBF instance
38 */
39
40enum tbf_gprs_ul_counters {
41 TBF_CTR_GPRS_UL_CS1,
42 TBF_CTR_GPRS_UL_CS2,
43 TBF_CTR_GPRS_UL_CS3,
44 TBF_CTR_GPRS_UL_CS4,
45};
46
47enum tbf_egprs_ul_counters {
48 TBF_CTR_EGPRS_UL_MCS1,
49 TBF_CTR_EGPRS_UL_MCS2,
50 TBF_CTR_EGPRS_UL_MCS3,
51 TBF_CTR_EGPRS_UL_MCS4,
52 TBF_CTR_EGPRS_UL_MCS5,
53 TBF_CTR_EGPRS_UL_MCS6,
54 TBF_CTR_EGPRS_UL_MCS7,
55 TBF_CTR_EGPRS_UL_MCS8,
56 TBF_CTR_EGPRS_UL_MCS9,
57};
58
Pau Espin Pedrol7bd92a32021-03-24 13:14:09 +010059/* Used in ul_tbf->m_usf[] to flag unassigned USF on a given TS: */
60#define USF_INVALID 0xFF
61
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020062struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010063 gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms);
Pau Espin Pedrol131deb02021-07-26 18:24:14 +020064 ~gprs_rlcmac_ul_tbf();
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +020065 gprs_rlc_window *window();
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020066 /* blocks were acked */
67 int rcv_data_block_acknowledged(
68 const struct gprs_rlc_data_info *rlc,
69 uint8_t *data, struct pcu_l1_meas *meas);
70
71
72 /* TODO: extract LLC class? */
73 int assemble_forward_llc(const gprs_rlc_data *data);
74 int snd_ul_ud();
75
76 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(
77 const struct gprs_rlc_data_info *rlc,
78 struct gprs_rlc_data *block,
79 uint8_t *data, const uint8_t block_idx);
80
81 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(
82 const struct gprs_rlc_data_info *rlc,
83 struct gprs_rlc_data *block,
84 uint8_t *data, const uint8_t block_idx);
85
86 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(
87 const struct gprs_rlc_data_info *rlc,
88 struct gprs_rlc_data *block,
89 uint8_t *data, const uint8_t block_idx);
90
91 uint16_t window_size() const;
92 void set_window_size();
93 void update_coding_scheme_counter_ul(enum CodingScheme cs);
Pau Espin Pedrol0b998b12021-03-24 14:45:43 +010094 void usf_timeout();
Pau Espin Pedrol4b6f0bf2021-05-10 18:54:52 +020095 void contention_resolution_start();
96 void contention_resolution_success();
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020097
98 /* Please note that all variables here will be reset when changing
99 * from WAIT RELEASE back to FLOW state (re-use of TBF).
100 * All states that need reset must be in this struct, so this is why
101 * variables are in both (dl and ul) structs and not outside union.
102 */
103 int32_t m_rx_counter; /* count all received blocks */
Pau Espin Pedrol7bd92a32021-03-24 13:14:09 +0100104 uint8_t m_usf[8]; /* list USFs per PDCH (timeslot), initialized to USF_INVALID */
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200105 uint8_t m_contention_resolution_done; /* set after done */
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200106
107 struct rate_ctr_group *m_ul_gprs_ctrs;
108 struct rate_ctr_group *m_ul_egprs_ctrs;
109
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200110 struct tbf_ul_ass_fsm_ctx ul_ack_fsm;
111
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200112protected:
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +0200113 void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc, bool countdown_finished);
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200114
115 /* Please note that all variables below will be reset when changing
116 * from WAIT RELEASE back to FLOW state (re-use of TBF).
117 * All states that need reset must be in this struct, so this is why
118 * variables are in both (dl and ul) structs and not outside union.
119 */
120 gprs_rlc_ul_window m_window;
121};
122
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200123inline uint16_t gprs_rlcmac_ul_tbf::window_size() const
124{
125 return m_window.ws();
126}
127
Pau Espin Pedrol442198c2020-10-23 22:30:04 +0200128struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, bool single_slot);
Pau Espin Pedrolc6571b52021-05-10 17:10:37 +0200129struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_pacch(struct gprs_rlcmac_bts *bts, GprsMs *ms,
130 int8_t use_trx, uint32_t tlli);
Pau Espin Pedrol20271c42021-05-10 17:21:03 +0200131struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_ccch(struct gprs_rlcmac_bts *bts, struct GprsMs *ms);
Pau Espin Pedrol442198c2020-10-23 22:30:04 +0200132struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
Pau Espin Pedrol54742f22021-04-26 16:48:34 +0200133 GprsMs *ms, uint8_t trx_no, uint8_t ts_no);
Pau Espin Pedrol442198c2020-10-23 22:30:04 +0200134
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100135#else /* ifdef __cplusplus */
136struct gprs_rlcmac_ul_tbf;
137#endif
138
139
140#ifdef __cplusplus
141extern "C" {
142#endif
143void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);
144void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);
145struct gprs_rlcmac_ul_tbf *as_ul_tbf(struct gprs_rlcmac_tbf *tbf);
Pau Espin Pedrol0b998b12021-03-24 14:45:43 +0100146void tbf_usf_timeout(struct gprs_rlcmac_ul_tbf *tbf);
Pau Espin Pedrol49a2f402021-07-27 17:33:07 +0200147bool ul_tbf_contention_resolution_done(const struct gprs_rlcmac_ul_tbf *tbf);
Pau Espin Pedrolea8dbdd2021-07-29 18:39:16 +0200148struct osmo_fsm_inst *tbf_ul_ack_fi(const struct gprs_rlcmac_ul_tbf *tbf);
149void ul_tbf_contention_resolution_success(struct gprs_rlcmac_ul_tbf *tbf);
Pau Espin Pedrol6ad11a62021-07-27 12:27:08 +0200150
151#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100152#ifdef __cplusplus
153}
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200154#endif