blob: 8713596ef7a121d0c2bb63db3fe19268b9612b7f [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"
27/*
28 * TBF instance
29 */
30
31enum tbf_gprs_ul_counters {
32 TBF_CTR_GPRS_UL_CS1,
33 TBF_CTR_GPRS_UL_CS2,
34 TBF_CTR_GPRS_UL_CS3,
35 TBF_CTR_GPRS_UL_CS4,
36};
37
38enum tbf_egprs_ul_counters {
39 TBF_CTR_EGPRS_UL_MCS1,
40 TBF_CTR_EGPRS_UL_MCS2,
41 TBF_CTR_EGPRS_UL_MCS3,
42 TBF_CTR_EGPRS_UL_MCS4,
43 TBF_CTR_EGPRS_UL_MCS5,
44 TBF_CTR_EGPRS_UL_MCS6,
45 TBF_CTR_EGPRS_UL_MCS7,
46 TBF_CTR_EGPRS_UL_MCS8,
47 TBF_CTR_EGPRS_UL_MCS9,
48};
49
50#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)
51
52struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
Pau Espin Pedrol2182e622021-01-14 16:48:38 +010053 gprs_rlcmac_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms);
Pau Espin Pedrolb3f23972020-10-23 21:00:23 +020054 gprs_rlc_window *window();
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020055 struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);
56 bool ctrl_ack_to_toggle();
57 bool handle_ctrl_ack();
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +020058 /* blocks were acked */
59 int rcv_data_block_acknowledged(
60 const struct gprs_rlc_data_info *rlc,
61 uint8_t *data, struct pcu_l1_meas *meas);
62
63
64 /* TODO: extract LLC class? */
65 int assemble_forward_llc(const gprs_rlc_data *data);
66 int snd_ul_ud();
67
68 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(
69 const struct gprs_rlc_data_info *rlc,
70 struct gprs_rlc_data *block,
71 uint8_t *data, const uint8_t block_idx);
72
73 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(
74 const struct gprs_rlc_data_info *rlc,
75 struct gprs_rlc_data *block,
76 uint8_t *data, const uint8_t block_idx);
77
78 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(
79 const struct gprs_rlc_data_info *rlc,
80 struct gprs_rlc_data *block,
81 uint8_t *data, const uint8_t block_idx);
82
83 uint16_t window_size() const;
84 void set_window_size();
85 void update_coding_scheme_counter_ul(enum CodingScheme cs);
86
87 /* Please note that all variables here will be reset when changing
88 * from WAIT RELEASE back to FLOW state (re-use of TBF).
89 * All states that need reset must be in this struct, so this is why
90 * variables are in both (dl and ul) structs and not outside union.
91 */
92 int32_t m_rx_counter; /* count all received blocks */
93 uint8_t m_usf[8]; /* list USFs per PDCH (timeslot) */
94 uint8_t m_contention_resolution_done; /* set after done */
95 uint8_t m_final_ack_sent; /* set if we sent final ack */
96
97 struct rate_ctr_group *m_ul_gprs_ctrs;
98 struct rate_ctr_group *m_ul_egprs_ctrs;
99
100protected:
Pau Espin Pedrolc33a0242020-05-15 16:57:48 +0200101 void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc, bool countdown_finished);
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200102
103 /* Please note that all variables below will be reset when changing
104 * from WAIT RELEASE back to FLOW state (re-use of TBF).
105 * All states that need reset must be in this struct, so this is why
106 * variables are in both (dl and ul) structs and not outside union.
107 */
108 gprs_rlc_ul_window m_window;
109};
110
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200111inline uint16_t gprs_rlcmac_ul_tbf::window_size() const
112{
113 return m_window.ws();
114}
115
Pau Espin Pedrol442198c2020-10-23 22:30:04 +0200116struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, bool single_slot);
117struct gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, GprsMs *ms,
118 int8_t use_trx, uint32_t tlli);
119struct gprs_rlcmac_ul_tbf *handle_tbf_reject(struct gprs_rlcmac_bts *bts,
120 GprsMs *ms, uint32_t tlli, uint8_t trx_no, uint8_t ts_no);
121
Pau Espin Pedrolda971ee2020-12-16 15:59:45 +0100122#else /* ifdef __cplusplus */
123struct gprs_rlcmac_ul_tbf;
124#endif
125
126
127#ifdef __cplusplus
128extern "C" {
129#endif
130void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);
131void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);
132struct gprs_rlcmac_ul_tbf *as_ul_tbf(struct gprs_rlcmac_tbf *tbf);
133#ifdef __cplusplus
134}
Pau Espin Pedrol9d1cdb12019-09-25 17:47:02 +0200135#endif