blob: 85da4f610c4b7384fc6c2a437ec6e0a7d314bcc3 [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
24#include "tbf.h"
25/*
26 * TBF instance
27 */
28
29enum tbf_gprs_ul_counters {
30 TBF_CTR_GPRS_UL_CS1,
31 TBF_CTR_GPRS_UL_CS2,
32 TBF_CTR_GPRS_UL_CS3,
33 TBF_CTR_GPRS_UL_CS4,
34};
35
36enum tbf_egprs_ul_counters {
37 TBF_CTR_EGPRS_UL_MCS1,
38 TBF_CTR_EGPRS_UL_MCS2,
39 TBF_CTR_EGPRS_UL_MCS3,
40 TBF_CTR_EGPRS_UL_MCS4,
41 TBF_CTR_EGPRS_UL_MCS5,
42 TBF_CTR_EGPRS_UL_MCS6,
43 TBF_CTR_EGPRS_UL_MCS7,
44 TBF_CTR_EGPRS_UL_MCS8,
45 TBF_CTR_EGPRS_UL_MCS9,
46};
47
48#define LOGPTBFUL(tbf, level, fmt, args...) LOGP(DTBFUL, level, "%s " fmt, tbf_name(tbf), ## args)
49
50struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf {
51 gprs_rlcmac_ul_tbf(BTS *bts);
52 gprs_rlc_ul_window *window();
53 struct msgb *create_ul_ack(uint32_t fn, uint8_t ts);
54 bool ctrl_ack_to_toggle();
55 bool handle_ctrl_ack();
56 void enable_egprs();
57 /* blocks were acked */
58 int rcv_data_block_acknowledged(
59 const struct gprs_rlc_data_info *rlc,
60 uint8_t *data, struct pcu_l1_meas *meas);
61
62
63 /* TODO: extract LLC class? */
64 int assemble_forward_llc(const gprs_rlc_data *data);
65 int snd_ul_ud();
66
67 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_spb(
68 const struct gprs_rlc_data_info *rlc,
69 struct gprs_rlc_data *block,
70 uint8_t *data, const uint8_t block_idx);
71
72 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_first_seg(
73 const struct gprs_rlc_data_info *rlc,
74 struct gprs_rlc_data *block,
75 uint8_t *data, const uint8_t block_idx);
76
77 egprs_rlc_ul_reseg_bsn_state handle_egprs_ul_second_seg(
78 const struct gprs_rlc_data_info *rlc,
79 struct gprs_rlc_data *block,
80 uint8_t *data, const uint8_t block_idx);
81
82 uint16_t window_size() const;
83 void set_window_size();
84 void update_coding_scheme_counter_ul(enum CodingScheme cs);
85
86 /* Please note that all variables here will be reset when changing
87 * from WAIT RELEASE back to FLOW state (re-use of TBF).
88 * All states that need reset must be in this struct, so this is why
89 * variables are in both (dl and ul) structs and not outside union.
90 */
91 int32_t m_rx_counter; /* count all received blocks */
92 uint8_t m_usf[8]; /* list USFs per PDCH (timeslot) */
93 uint8_t m_contention_resolution_done; /* set after done */
94 uint8_t m_final_ack_sent; /* set if we sent final ack */
95
96 struct rate_ctr_group *m_ul_gprs_ctrs;
97 struct rate_ctr_group *m_ul_egprs_ctrs;
98
99protected:
100 void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc);
101
102 /* Please note that all variables below will be reset when changing
103 * from WAIT RELEASE back to FLOW state (re-use of TBF).
104 * All states that need reset must be in this struct, so this is why
105 * variables are in both (dl and ul) structs and not outside union.
106 */
107 gprs_rlc_ul_window m_window;
108};
109
110#ifdef __cplusplus
111extern "C" {
112#endif
113void update_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, int8_t ta_delta);
114void set_tbf_ta(struct gprs_rlcmac_ul_tbf *tbf, uint8_t ta);
115#ifdef __cplusplus
116}
117#endif
118
119inline uint16_t gprs_rlcmac_ul_tbf::window_size() const
120{
121 return m_window.ws();
122}
123
124inline void gprs_rlcmac_ul_tbf::enable_egprs()
125{
126 m_window.set_sns(RLC_EGPRS_SNS);
127 gprs_rlcmac_tbf::enable_egprs();
128}
129
130inline gprs_rlcmac_ul_tbf *as_ul_tbf(gprs_rlcmac_tbf *tbf)
131{
132 if (tbf && tbf->direction == GPRS_RLCMAC_UL_TBF)
133 return static_cast<gprs_rlcmac_ul_tbf *>(tbf);
134 else
135 return NULL;
136}
137
138#endif