blob: 8c69ed7c11cee2b0c87c6b58ffb8fc1c6e92b7a8 [file] [log] [blame]
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +04001/* gprs_rlcmac.h
2 *
3 * Copyright (C) 2012 Ivan Klyuchnikov
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#ifndef GPRS_RLCMAC_H
21#define GPRS_RLCMAC_H
22
Ivan Kluchnikov835f91e2012-04-30 18:00:36 +040023#include <bitvector.h>
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +040024#include <gsm_rlcmac.h>
Ivan Kluchnikov61a33f72012-04-12 15:22:06 +040025#include <gsm_timer.h>
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +040026
27extern "C" {
28#include <osmocom/core/linuxlist.h>
Ivan Kluchnikov61a33f72012-04-12 15:22:06 +040029#include <osmocom/core/timer.h>
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +040030}
31
Andreas Eversberge6228b32012-07-03 13:36:03 +020032/* This special feature will delay assignment of downlink TBF by one second,
33 * in case there is already a TBF.
34 * This is usefull to debug downlink establishment during packet idle mode.
35 */
36//#define DEBUG_DL_ASS_IDLE
37
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020038/*
39 * PDCH instanc
40 */
41
42struct gprs_rlcmac_tbf;
43
44struct gprs_rlcmac_pdch {
45 uint8_t enable; /* TS is enabled */
46 uint8_t tsc; /* TSC of this slot */
47 uint8_t next_ul_tfi; /* next uplink TBF/TFI to schedule (0..31) */
48 uint8_t next_dl_tfi; /* next downlink TBF/TFI to schedule (0..31) */
49 struct gprs_rlcmac_tbf *tbf[32]; /* array of TBF pointers, by TFI */
Andreas Eversberge6228b32012-07-03 13:36:03 +020050 uint32_t last_rts_fn; /* store last frame number of RTS */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020051};
52
53struct gprs_rlcmac_trx {
54 uint16_t arfcn;
55 struct gprs_rlcmac_pdch pdch[8];
56};
57
58struct gprs_rlcmac_bts {
Andreas Eversberge6228b32012-07-03 13:36:03 +020059 uint8_t cs; /* block length 1=CS-1, 2=CS-2, 3=CS-3, 4=CS-4 */
60 uint16_t t3192_msec;
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020061 struct gprs_rlcmac_trx trx[8];
62};
63
64extern struct gprs_rlcmac_bts *gprs_rlcmac_bts;
65
66/*
67 * TBF instance
68 */
69
Ivan Kluchnikovc5d8c272012-06-04 21:55:02 +040070#define LLC_MAX_LEN 1543
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020071#define RLC_MAX_SNS 128 /* GPRS, must be power of 2 */
72#define RLC_MAX_WS 64 /* max window size */
Andreas Eversberge6228b32012-07-03 13:36:03 +020073#define RLC_MAX_LEN 54 /* CS-4 including spare bits */
Ivan Kluchnikovc5d8c272012-06-04 21:55:02 +040074
Andreas Eversberge6228b32012-07-03 13:36:03 +020075#define Tassign_agch 0,500000/* wait for assignment, before transmitting DL */
76#define Tassign_pacch 0,100000/* wait for assignment, before transmitting DL */
77#define T3169 6,0 /* 5 seconds + one second, because we don't use
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020078 * counters before starting timer. */
Andreas Eversberge6228b32012-07-03 13:36:03 +020079#define T3191 5,0 /* 5 Seconds */
80#define T3193 2,0 /* >T3192, which can be max 1,5s */
81#define T3195 5,0 /* 5 Seconds */
82//#define N3101_MAX 12 /* how many missed uplink blocks */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020083#define N3103_MAX 4 /* how many tries to poll PACKET CONTROL ACK */
Andreas Eversberge6228b32012-07-03 13:36:03 +020084#define N3105_MAX 4 /* how many tries to poll PACKET DOWNLINK ACK */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020085
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +040086enum gprs_rlcmac_tbf_state {
Andreas Eversberge6228b32012-07-03 13:36:03 +020087 GPRS_RLCMAC_NULL = 0, /* new created TBF */
88 GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020089 GPRS_RLCMAC_FLOW, /* RLC/MAC flow, ressource needed */
90 GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */
Andreas Eversberge6228b32012-07-03 13:36:03 +020091 GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +020092 GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */
93};
94
95enum gprs_rlcmac_tbf_poll_state {
96 GPRS_RLCMAC_POLL_NONE = 0,
97 GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */
98};
99
Andreas Eversberge6228b32012-07-03 13:36:03 +0200100enum gprs_rlcmac_tbf_dl_ass_state {
101 GPRS_RLCMAC_DL_ASS_NONE = 0,
102 GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */
103 GPRS_RLCMAC_DL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */
104};
105
106enum gprs_rlcmac_tbf_ul_ass_state {
107 GPRS_RLCMAC_UL_ASS_NONE = 0,
108 GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */
109 GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */
110};
111
112enum gprs_rlcmac_tbf_ul_ack_state {
113 GPRS_RLCMAC_UL_ACK_NONE = 0,
114 GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */
115 GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400116};
117
118enum gprs_rlcmac_tbf_direction {
119 GPRS_RLCMAC_DL_TBF,
120 GPRS_RLCMAC_UL_TBF
121};
122
123struct gprs_rlcmac_tbf {
124 struct llist_head list;
125 enum gprs_rlcmac_tbf_state state;
126 enum gprs_rlcmac_tbf_direction direction;
127 uint8_t tfi;
128 uint32_t tlli;
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200129 uint8_t tlli_valid;
Andreas Eversberg0aed6542012-06-23 10:33:16 +0200130 uint8_t trx, ts, tsc;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200131 struct gprs_rlcmac_pdch *pdch;
Andreas Eversberg0aed6542012-06-23 10:33:16 +0200132 uint16_t arfcn, ta;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200133 uint8_t llc_frame[LLC_MAX_LEN]; /* current DL or UL frame */
134 uint16_t llc_index; /* current write/read position of frame */
135 uint16_t llc_length; /* len of current DL LLC_frame, 0 == no frame */
136 llist_head llc_queue; /* queued LLC DL data */
137
138 enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state;
139 enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state;
140 enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state;
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200141
142 enum gprs_rlcmac_tbf_poll_state poll_state;
143 uint32_t poll_fn;
144
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200145 uint16_t ws; /* window size */
146 uint16_t sns; /* sequence number space */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200147
148 /* Please note that all variables here will be reset when changing
149 * from WAIT RELEASE back to FLOW state (re-use of TBF).
150 * All states that need reset must be in this struct, so this is why
151 * variables are in both (dl and ul) structs and not outside union.
152 */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200153 union {
154 struct {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200155 uint16_t bsn; /* block sequence number */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200156 uint16_t v_s; /* send state */
157 uint16_t v_a; /* ack state */
158 char v_b[RLC_MAX_SNS/2]; /* acknowledge state array */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200159 int32_t tx_counter; /* count all transmitted blocks */
160 uint8_t n3105; /* N3105 counter */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200161 } dl;
162 struct {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200163 uint16_t bsn; /* block sequence number */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200164 uint16_t v_r; /* receive state */
165 uint16_t v_q; /* receive window state */
166 char v_n[RLC_MAX_SNS/2]; /* receive state array */
167 int32_t rx_counter; /* count all received blocks */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200168 uint8_t n3103; /* N3103 counter */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200169 uint8_t usf; /* USF */
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200170 } ul;
171 } dir;
172 uint8_t rlc_block[RLC_MAX_SNS/2][RLC_MAX_LEN]; /* block history */
173 uint8_t rlc_block_len[RLC_MAX_SNS/2]; /* block len of history */
Ivan Kluchnikov61a33f72012-04-12 15:22:06 +0400174
175 struct osmo_timer_list timer;
176 unsigned int T; /* Txxxx number */
177 unsigned int num_T_exp; /* number of consecutive T expirations */
178
179 struct osmo_gsm_timer_list gsm_timer;
180 unsigned int fT; /* fTxxxx number */
181 unsigned int num_fT_exp; /* number of consecutive fT expirations */
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400182};
183
184extern struct llist_head gprs_rlcmac_tbfs;
185
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200186int tfi_alloc(uint8_t *_trx, uint8_t *_ts);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400187
Andreas Eversberg0aed6542012-06-23 10:33:16 +0200188struct gprs_rlcmac_tbf *tbf_alloc(uint8_t tfi, uint8_t trx, uint8_t ts);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400189
Andreas Eversberge6228b32012-07-03 13:36:03 +0200190struct gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, int direction);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400191
Andreas Eversberge6228b32012-07-03 13:36:03 +0200192struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, int direction);
193
194struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn);
195
196int find_free_usf(uint8_t trx, uint8_t ts);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400197
Andreas Eversberg0aed6542012-06-23 10:33:16 +0200198void tbf_free(struct gprs_rlcmac_tbf *tbf);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400199
Andreas Eversberge6228b32012-07-03 13:36:03 +0200200void tbf_new_state(struct gprs_rlcmac_tbf *tbf,
201 enum gprs_rlcmac_tbf_state state);
202
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200203void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T,
Andreas Eversberge6228b32012-07-03 13:36:03 +0200204 unsigned int seconds, unsigned int microseconds);
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200205
206void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf);
207
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400208/* TS 44.060 Section 10.4.7 Table 10.4.7.1: Payload Type field */
209enum gprs_rlcmac_block_type {
210 GPRS_RLCMAC_DATA_BLOCK = 0x0,
211 GPRS_RLCMAC_CONTROL_BLOCK = 0x1,
212 GPRS_RLCMAC_CONTROL_BLOCK_OPT = 0x2,
213 GPRS_RLCMAC_RESERVED = 0x3
214};
215
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200216int gprs_rlcmac_rcv_block(uint8_t *data, uint8_t len, uint32_t fn);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400217
Andreas Eversberge6228b32012-07-03 13:36:03 +0200218int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra,
219 uint32_t fn, uint8_t ta, uint16_t arfcn, uint8_t ts, uint8_t tsc,
220 uint8_t tfi, uint8_t usf, uint32_t tlli, uint8_t polling,
221 uint32_t poll_fn);
Andreas Eversberg0aed6542012-06-23 10:33:16 +0200222
Andreas Eversberge6228b32012-07-03 13:36:03 +0200223void write_packet_uplink_assignment(bitvec * dest, uint8_t old_tfi,
224 uint8_t old_downlink, uint32_t tlli, uint8_t use_tlli, uint8_t new_tfi,
225 uint8_t usf, uint16_t arfcn, uint8_t tn, uint8_t ta, uint8_t tsc,
226 uint8_t poll);
Ivan Kluchnikov5310d452012-04-17 22:00:31 +0400227
Andreas Eversberge6228b32012-07-03 13:36:03 +0200228void write_packet_downlink_assignment(bitvec * dest, uint8_t old_tfi,
229 uint8_t old_downlink, uint8_t new_tfi, uint16_t arfcn,
230 uint8_t tn, uint8_t ta, uint8_t tsc, uint8_t poll);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400231
Andreas Eversberge6228b32012-07-03 13:36:03 +0200232void write_packet_uplink_ack(bitvec * dest, struct gprs_rlcmac_tbf *tbf,
233 uint8_t final);
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400234
235void gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
236
Andreas Eversberge6228b32012-07-03 13:36:03 +0200237void tbf_timer_cb(void *_tbf);
Ivan Kluchnikovc320d862012-03-18 15:04:48 +0400238
Andreas Eversberge6228b32012-07-03 13:36:03 +0200239int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf);
Ivan Kluchnikov9c795ab2012-05-24 23:12:59 +0400240
Andreas Eversberge6228b32012-07-03 13:36:03 +0200241int gprs_rlcmac_rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta);
242
243int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint32_t fn);
244
245struct msgb *gprs_rlcmac_send_packet_uplink_assignment(
246 struct gprs_rlcmac_tbf *tbf, uint32_t fn);
247
248struct msgb *gprs_rlcmac_send_packet_downlink_assignment(
249 struct gprs_rlcmac_tbf *tbf, uint32_t fn);
250
251void gprs_rlcmac_trigger_downlink_assignment(gprs_rlcmac_tbf *tbf,
252 uint8_t old_downlink);
253
254int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final,
255 uint8_t ssn, uint8_t *rbb);
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200256
257int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t *data, uint8_t len);
258
Andreas Eversberge6228b32012-07-03 13:36:03 +0200259struct msgb *gprs_rlcmac_send_data_block_acknowledged(
260 struct gprs_rlcmac_tbf *tbf, uint32_t fn);
261
Andreas Eversberg5dac2f02012-06-27 15:52:04 +0200262struct msgb *gprs_rlcmac_send_uplink_ack(struct gprs_rlcmac_tbf *tbf,
263 uint32_t fn);
Ivan Kluchnikov9c795ab2012-05-24 23:12:59 +0400264
Andreas Eversberge6228b32012-07-03 13:36:03 +0200265int gprs_rlcmac_rcv_rts_block(uint8_t trx, uint8_t ts, uint16_t arfcn,
266 uint32_t fn, uint8_t block_nr);
267
Ivan Kluchnikov8ee60512012-03-05 19:24:57 +0400268#endif // GPRS_RLCMAC_H