blob: b6d506220aade777ee273484ee994c60e576aa0e [file] [log] [blame]
Andreas Eversberg66690dd2012-06-27 15:44:31 +02001/* Data block transfer
2 *
3 * Copyright (C) 2012 Ivan Klyuchnikov
4 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <gprs_bssgp_pcu.h>
22#include <gprs_rlcmac.h>
Andreas Eversberge6228b32012-07-03 13:36:03 +020023#include <pcu_l1_if.h>
Andreas Eversberg66690dd2012-06-27 15:44:31 +020024
Andreas Eversberg6681bb82012-07-25 08:48:44 +020025extern void *tall_pcu_ctx;
26
Andreas Eversberg24131bf2012-07-21 11:09:58 +020027extern "C" {
28int bssgp_tx_llc_discarded(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
29 uint8_t num_frames, uint32_t num_octets);
30}
31
Andreas Eversbergf54a89e2012-07-16 11:56:11 +020032/* After receiving these frames, we send ack/nack. */
33#define SEND_ACK_AFTER_FRAMES 20
34
35/* After sending these frames, we poll for ack/nack. */
36#define POLL_ACK_AFTER_FRAMES 10
Andreas Eversberg66690dd2012-06-27 15:44:31 +020037
Andreas Eversberg802bb6e2012-08-06 11:15:05 +020038/* If acknowledgement to uplink/downlink assignmentshould be polled */
39#define POLLING_ASSIGNMENT_DL 1
40#define POLLING_ASSIGNMENT_UL 1
Andreas Eversberge6228b32012-07-03 13:36:03 +020041
Andreas Eversberg66690dd2012-06-27 15:44:31 +020042extern "C" {
43/* TS 04.60 10.2.2 */
Andreas Eversberge6228b32012-07-03 13:36:03 +020044struct rlc_ul_header {
Andreas Eversberg66690dd2012-06-27 15:44:31 +020045 uint8_t r:1,
46 si:1,
47 cv:4,
48 pt:2;
49 uint8_t ti:1,
50 tfi:5,
51 pi:1,
52 spare:1;
53 uint8_t e:1,
54 bsn:7;
55} __attribute__ ((packed));
56
Andreas Eversberge6228b32012-07-03 13:36:03 +020057struct rlc_dl_header {
58 uint8_t usf:3,
59 s_p:1,
60 rrbp:2,
61 pt:2;
62 uint8_t fbi:1,
63 tfi:5,
64 pr:2;
65 uint8_t e:1,
66 bsn:7;
67} __attribute__ ((packed));
68
Andreas Eversberg66690dd2012-06-27 15:44:31 +020069struct rlc_li_field {
70 uint8_t e:1,
71 m:1,
72 li:6;
73} __attribute__ ((packed));
74}
75
Andreas Eversberg14db19e2012-08-06 15:03:03 +020076static int gprs_rlcmac_diag(struct gprs_rlcmac_tbf *tbf)
77{
78 if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH)))
79 LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n");
80 if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH)))
81 LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n");
82 if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA)))
83 LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n");
84 else if (tbf->direction == GPRS_RLCMAC_UL_TBF)
85 LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n");
86 if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK)))
87 LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n");
88 else if (tbf->direction == GPRS_RLCMAC_DL_TBF)
89 LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n");
90
91 return 0;
92}
93
Andreas Eversberge6228b32012-07-03 13:36:03 +020094int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf)
95{
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +020096 LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for %s TBF=%d\n",
97 (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi);
Andreas Eversberge6228b32012-07-03 13:36:03 +020098
99 tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
100
101 if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200102 if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) {
103 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
104 "PACKET CONTROL ACK for PACKET UPLINK ACK\n");
105 gprs_rlcmac_diag(tbf);
106 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
107 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200108 tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
109 if (tbf->state == GPRS_RLCMAC_FINISHED) {
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200110 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
111
Andreas Eversberge6228b32012-07-03 13:36:03 +0200112 tbf->dir.ul.n3103++;
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200113 if (tbf->dir.ul.n3103 == bts->n3103) {
Andreas Eversberg4b470ff2012-07-16 12:02:40 +0200114 LOGP(DRLCMAC, LOGL_NOTICE,
115 "- N3103 exceeded\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200116 tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200117 tbf_timer_start(tbf, 3169, bts->t3169, 0);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200118 return 0;
119 }
120 /* reschedule UL ack */
121 tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK;
122 }
123 } else
124 if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200125 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
126
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200127 if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
128 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
129 "PACKET CONTROL ACK for PACKET UPLINK "
130 "ASSIGNMENT.\n");
131 gprs_rlcmac_diag(tbf);
132 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
133 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200134 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200135 tbf->n3105++;
136 if (tbf->n3105 == bts->n3105) {
137 LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
138 tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
139 tbf_timer_start(tbf, 3195, bts->t3195, 0);
140 return 0;
141 }
142 /* reschedule UL assignment */
143 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200144 } else
145 if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200146 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
147
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200148 if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
149 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
150 "PACKET CONTROL ACK for PACKET DOWNLINK "
151 "ASSIGNMENT.\n");
152 gprs_rlcmac_diag(tbf);
153 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
154 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200155 tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200156 tbf->n3105++;
157 if (tbf->n3105 == bts->n3105) {
158 LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
159 tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
160 tbf_timer_start(tbf, 3195, bts->t3195, 0);
161 return 0;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200162 }
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200163 /* reschedule DL assignment */
164 tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200165 } else
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200166 if (tbf->direction == GPRS_RLCMAC_DL_TBF) {
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200167 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
168
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200169 if (!(tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
170 LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling "
171 "PACKET DOWNLINK ACK.\n");
172 gprs_rlcmac_diag(tbf);
173 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
174 }
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200175 tbf->n3105++;
176 if (tbf->n3105 == bts->n3105) {
Andreas Eversberg4b470ff2012-07-16 12:02:40 +0200177 LOGP(DRLCMAC, LOGL_NOTICE, "- N3105 exceeded\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200178 tbf_new_state(tbf, GPRS_RLCMAC_RELEASING);
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200179 tbf_timer_start(tbf, 3195, bts->t3195, 0);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200180 return 0;
181 }
Andreas Eversberg4b470ff2012-07-16 12:02:40 +0200182 } else
183 LOGP(DRLCMAC, LOGL_ERROR, "- Poll Timeout, but no event!\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200184
185 return 0;
186}
187
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200188static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap)
189{
190 int i;
191
192 for (i = 0; i < cap->Count_MS_RA_capability_value; i++) {
193 if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability)
194 continue;
195 if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_GPRS_multislot_class)
196 continue;
197 return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.GPRS_multislot_class;
198 }
199
200 return 0;
201}
202
203static struct gprs_rlcmac_tbf *alloc_ul_tbf(int8_t use_trx, int8_t first_ts,
204 uint8_t ms_class, uint32_t tlli, uint8_t ta,
205 struct gprs_rlcmac_tbf *dl_tbf)
206{
207 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
208 uint8_t trx, ts;
209 struct gprs_rlcmac_tbf *tbf;
210 uint8_t tfi;
211
212 /* create new TBF, use sme TRX as DL TBF */
213 tfi = tfi_alloc(GPRS_RLCMAC_UL_TBF, &trx, &ts, use_trx, first_ts);
214 if (tfi < 0) {
215 LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n");
216 /* FIXME: send reject */
217 return NULL;
218 }
219 /* use multislot class of downlink TBF */
220 tbf = tbf_alloc(dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx, ts, ms_class, 0);
221 if (!tbf) {
222 LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n");
223 /* FIXME: send reject */
224 return NULL;
225 }
226 tbf->tlli = tlli;
227 tbf->tlli_valid = 1; /* no contention resolution */
228 tbf->dir.ul.contention_resolution_done = 1;
229 tbf->ta = ta; /* use current TA */
230 tbf_new_state(tbf, GPRS_RLCMAC_ASSIGN);
231 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
232 tbf_timer_start(tbf, 3169, bts->t3169, 0);
233
234 return tbf;
235}
236
237
238
Andreas Eversberge6228b32012-07-03 13:36:03 +0200239/* Received Uplink RLC control block. */
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200240int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
241 uint32_t fn)
Andreas Eversberge6228b32012-07-03 13:36:03 +0200242{
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200243 int8_t tfi = 0; /* must be signed */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200244 uint32_t tlli = 0;
245 struct gprs_rlcmac_tbf *tbf;
Andreas Eversberg0f13c402012-07-16 11:59:23 +0200246 int rc;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200247
Andreas Eversberg6681bb82012-07-25 08:48:44 +0200248 RlcMacUplink_t * ul_control_block = (RlcMacUplink_t *)talloc_zero(tall_pcu_ctx, RlcMacUplink_t);
Andreas Eversberg0e403092012-07-06 11:04:57 +0200249 LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200250 decode_gsm_rlcmac_uplink(rlc_block, ul_control_block);
Andreas Eversberg0e403092012-07-06 11:04:57 +0200251 LOGPC(DCSN1, LOGL_NOTICE, "\n");
252 LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200253 switch (ul_control_block->u.MESSAGE_TYPE) {
254 case MT_PACKET_CONTROL_ACK:
255 tlli = ul_control_block->u.Packet_Control_Acknowledgement.TLLI;
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200256 tbf = tbf_by_poll_fn(fn, trx, ts);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200257 if (!tbf) {
258 LOGP(DRLCMAC, LOGL_NOTICE, "PACKET CONTROL ACK with "
Andreas Eversberg592e04a2012-07-15 06:25:37 +0200259 "unknown FN=%u TLL=0x%08x (TRX %d TS %d)\n",
260 fn, tlli, trx, ts);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200261 break;
262 }
263 tfi = tbf->tfi;
264 if (tlli != tbf->tlli) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200265 LOGP(DRLCMAC, LOGL_INFO, "Phone changed TLLI to "
Andreas Eversberge6228b32012-07-03 13:36:03 +0200266 "0x%08x\n", tlli);
267 tbf->tlli = tlli;
268 }
Andreas Eversberg0e403092012-07-06 11:04:57 +0200269 LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Control Ack\n", tbf->tfi, tbf->tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200270 tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
271
272 /* check if this control ack belongs to packet uplink ack */
273 if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200274 LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200275 tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200276 if ((tbf->state_flags &
277 (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) {
278 tbf->state_flags &=
279 ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK);
280 LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink "
281 "ack\n");
282 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200283 tbf_free(tbf);
284 break;
285 }
286 if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200287 LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] DOWNLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200288 /* reset N3105 */
289 tbf->n3105 = 0;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200290 tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
Andreas Eversberg642c7d32012-07-23 17:58:55 +0200291 if (tbf->direction == GPRS_RLCMAC_UL_TBF)
292 tbf = tbf_by_tlli(tbf->tlli,
293 GPRS_RLCMAC_DL_TBF);
294 if (!tbf) {
295 LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL "
296 "TBF is gone\n");
297 break;
298 }
299 tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
Andreas Eversbergcbcd1242012-08-07 15:48:21 +0200300 /* stop pending assignment timer */
301 tbf_timer_stop(tbf);
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200302 if ((tbf->state_flags &
303 (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) {
304 tbf->state_flags &=
305 ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS);
306 LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink "
307 "assignment\n");
308 }
Andreas Eversberg642c7d32012-07-23 17:58:55 +0200309 tbf_assign_control_ts(tbf);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200310 break;
311 }
312 if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200313 LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] UPLINK ASSIGNED TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli);
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200314 /* reset N3105 */
315 tbf->n3105 = 0;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200316 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
Andreas Eversberg642c7d32012-07-23 17:58:55 +0200317 if (tbf->direction == GPRS_RLCMAC_DL_TBF)
318 tbf = tbf_by_tlli(tbf->tlli,
319 GPRS_RLCMAC_UL_TBF);
320 if (!tbf) {
321 LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL "
322 "TBF is gone\n");
323 break;
324 }
325 tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200326 if ((tbf->state_flags &
327 (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) {
328 tbf->state_flags &=
329 ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS);
330 LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink "
331 "assignment\n");
332 }
Andreas Eversberg642c7d32012-07-23 17:58:55 +0200333 tbf_assign_control_ts(tbf);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200334 break;
335 }
336 LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK "
337 "at no request\n");
338 break;
339 case MT_PACKET_DOWNLINK_ACK_NACK:
340 tfi = ul_control_block->u.Packet_Downlink_Ack_Nack.DOWNLINK_TFI;
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200341 tbf = tbf_by_poll_fn(fn, trx, ts);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200342 if (!tbf) {
343 LOGP(DRLCMAC, LOGL_NOTICE, "PACKET DOWNLINK ACK with "
Andreas Eversberg592e04a2012-07-15 06:25:37 +0200344 "unknown FN=%u TBF=%d (TRX %d TS %d)\n",
345 fn, tfi, trx, ts);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200346 break;
347 }
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200348 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK);
349 if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) {
350 tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK);
351 LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink ack\n");
352 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200353 /* reset N3105 */
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200354 tbf->n3105 = 0;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200355 /* stop timer T3191 */
356 tbf_timer_stop(tbf);
357 tlli = tbf->tlli;
Andreas Eversberg0e403092012-07-06 11:04:57 +0200358 LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u TLLI: 0x%08x Packet Downlink Ack/Nack\n", tbf->tfi, tbf->tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200359 tbf->poll_state = GPRS_RLCMAC_POLL_NONE;
360
Andreas Eversberg0f13c402012-07-16 11:59:23 +0200361 rc = gprs_rlcmac_downlink_ack(tbf,
Andreas Eversberge6228b32012-07-03 13:36:03 +0200362 ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.FINAL_ACK_INDICATION,
363 ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER,
364 ul_control_block->u.Packet_Downlink_Ack_Nack.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP);
Andreas Eversberg0f13c402012-07-16 11:59:23 +0200365 if (rc == 1) {
366 tbf_free(tbf);
367 break;
368 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200369 /* check for channel request */
370 if (ul_control_block->u.Packet_Downlink_Ack_Nack.Exist_Channel_Request_Description) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200371 LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack "
372 "message, so we provide one:\n");
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200373
374 alloc_ul_tbf(tbf->trx, tbf->first_ts, tbf->ms_class, tbf->tlli, tbf->ta, tbf);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200375 /* schedule uplink assignment */
376 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
377 }
378 break;
379 case MT_PACKET_RESOURCE_REQUEST:
380 if (ul_control_block->u.Packet_Resource_Request.ID.UnionType) {
381 tlli = ul_control_block->u.Packet_Resource_Request.ID.u.TLLI;
382 tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF);
383 if (!tbf) {
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200384 uint8_t ms_class = 0;
385 LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF "
386 "in packet ressource request of single "
387 "block, so we provide one:\n");
388 if (ul_control_block->u.Packet_Resource_Request.Exist_MS_Radio_Access_capability)
389 ms_class = get_ms_class_by_capability(&ul_control_block->u.Packet_Resource_Request.MS_Radio_Access_capability);
390 if (!ms_class)
391 LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n");
392 tbf = alloc_ul_tbf(trx, ts, ms_class, tlli, 0, NULL);
393#warning FIXME TA!!!
394 if (!tbf)
395 break;
396 /* set control ts to current MS's TS, until assignment complete */
397 LOGP(DRLCMAC, LOGL_DEBUG, "Change control TS to %d until assinment is complete.\n", ts);
398 tbf->control_ts = ts;
399 /* schedule uplink assignment */
400 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200401 break;
402 }
403 tfi = tbf->tfi;
404 } else {
405 if (ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.UnionType) {
406 tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.DOWNLINK_TFI;
Andreas Eversbergadb2f182012-08-07 17:06:08 +0200407 tbf = tbf_by_tfi(tfi, trx, GPRS_RLCMAC_DL_TBF);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200408 if (!tbf) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200409 LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TBF=%d\n", tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200410 break;
411 }
412 } else {
413 tfi = ul_control_block->u.Packet_Resource_Request.ID.u.Global_TFI.u.UPLINK_TFI;
Andreas Eversbergadb2f182012-08-07 17:06:08 +0200414 tbf = tbf_by_tfi(tfi, trx, GPRS_RLCMAC_UL_TBF);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200415 if (!tbf) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200416 LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TBF=%d\n", tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200417 break;
418 }
419 }
420 tlli = tbf->tlli;
421 }
Andreas Eversbergc8466f42012-07-15 19:34:53 +0200422 LOGP(DRLCMAC, LOGL_ERROR, "RX: [PCU <- BTS] %s TFI: %u TLLI: 0x%08x FIXME: Packet ressource request\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf->tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200423 break;
424 default:
Andreas Eversberg0e403092012-07-06 11:04:57 +0200425 LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] unknown control block received\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200426 }
Andreas Eversberg6681bb82012-07-25 08:48:44 +0200427 talloc_free(ul_control_block);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200428 return 1;
429}
430
Andreas Eversberge13fa2d2012-07-09 17:10:44 +0200431#ifdef DEBUG_DL_ASS_IDLE
432 char debug_imsi[16];
433#endif
Andreas Eversberge6228b32012-07-03 13:36:03 +0200434
435void tbf_timer_cb(void *_tbf)
436{
437 struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf;
438
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200439 LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d timer %u expired.\n",
440 (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi,
Andreas Eversberge6228b32012-07-03 13:36:03 +0200441 tbf->T);
442
443 tbf->num_T_exp++;
444
445 switch (tbf->T) {
446#ifdef DEBUG_DL_ASS_IDLE
447 case 1234:
Andreas Eversberg7f5352c2012-07-23 18:20:36 +0200448 gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200449 break;
450#endif
451 case 0: /* assignment */
Andreas Eversbergcbcd1242012-08-07 15:48:21 +0200452 if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) {
453 if (tbf->state == GPRS_RLCMAC_ASSIGN) {
454 LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to "
455 "PACCH assignment timeout.\n");
456 tbf_free(tbf);
457 } else
458 LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not "
459 "in assign state\n");
460 }
461 if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) {
462 /* change state to FLOW, so scheduler will start transmission */
463 if (tbf->state == GPRS_RLCMAC_ASSIGN) {
464 tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
465 tbf_assign_control_ts(tbf);
466 } else
467 LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not "
468 "in assign state\n");
469 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200470 break;
471 case 3169:
472 case 3191:
Andreas Eversberge6228b32012-07-03 13:36:03 +0200473 case 3195:
Andreas Eversberg0e403092012-07-06 11:04:57 +0200474 LOGP(DRLCMAC, LOGL_NOTICE, "TBF T%d timeout during "
475 "transsmission\n", tbf->T);
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200476 gprs_rlcmac_diag(tbf);
Andreas Eversberg0e403092012-07-06 11:04:57 +0200477 /* fall through */
478 case 3193:
Andreas Eversberge6228b32012-07-03 13:36:03 +0200479 LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n");
480 /* free TBF */
481 tbf_free(tbf);
482 break;
483 default:
484 LOGP(DRLCMAC, LOGL_ERROR, "Timer expired in unknown mode: %u\n",
485 tbf->T);
486 }
487}
488
489/*
490 * UL data block flow
491 */
492
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200493/* get TLLI from received UL data block */
494static int tlli_from_ul_data(uint8_t *data, uint8_t len, uint32_t *tlli)
495{
Andreas Eversberge6228b32012-07-03 13:36:03 +0200496 struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200497 struct rlc_li_field *li;
498 uint8_t e;
499
500 if (!rh->ti)
501 return -EINVAL;
502
503 data += 3;
504 len -= 3;
505 e = rh->e;
506 /* if E is not set (LI follows) */
507 while (!e) {
508 if (!len) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200509 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI extended, "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200510 "but no more data\n");
511 return -EINVAL;
512 }
513 /* get new E */
514 li = (struct rlc_li_field *)data;
515 if (li->e == 0) /* if LI==0, E is interpreted as '1' */
516 e = 1;
517 else
518 e = li->e;
519 data++;
520 len--;
521 }
522 if (len < 4) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200523 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TLLI out of frame "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200524 "border\n");
525 return -EINVAL;
526 }
527 *tlli = ntohl(*((uint32_t *)data));
528
529 return 0;
530}
531
532/* Store received block data in LLC message(s) and forward to SGSN if complete.
533 */
534static int gprs_rlcmac_assemble_llc(struct gprs_rlcmac_tbf *tbf, uint8_t *data,
535 uint8_t len)
536{
Andreas Eversberge6228b32012-07-03 13:36:03 +0200537 struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200538 uint8_t e, m;
539 struct rlc_li_field *li;
540 uint8_t frame_offset[16], offset = 0, chunk;
541 int i, frames = 0;
542
Andreas Eversberge6228b32012-07-03 13:36:03 +0200543 LOGP(DRLCMACUL, LOGL_DEBUG, "- Assembling frames: (len=%d)\n", len);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200544
545 data += 3;
546 len -= 3;
547 e = rh->e; /* if extended */
548 m = 1; /* more frames, that means: the first frame */
549
550 /* Parse frame offsets from length indicator(s), if any. */
551 while (1) {
552 if (frames == (int)sizeof(frame_offset)) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200553 LOGP(DRLCMACUL, LOGL_ERROR, "Too many frames in "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200554 "block\n");
555 return -EINVAL;
556 }
557 frame_offset[frames++] = offset;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200558 LOGP(DRLCMACUL, LOGL_DEBUG, "-- Frame %d starts at offset "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200559 "%d\n", frames, offset);
560 if (!len)
561 break;
562 /* M == 0 and E == 0 is not allowed in this version. */
563 if (!m && !e) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200564 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TBF=%d "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200565 "ignored, because M='0' and E='0'.\n",
566 tbf->tfi);
567 return 0;
568 }
569 /* no more frames in this segment */
570 if (e) {
571 break;
572 }
573 /* There is a new frame and an LI that delimits it. */
574 if (m) {
575 li = (struct rlc_li_field *)data;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200576 LOGP(DRLCMACUL, LOGL_DEBUG, "-- Delimiter len=%d\n",
577 li->li);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200578 /* Special case: LI == 0
579 * If the last segment would fit precisely into the
580 * rest of the RLC MAC block, there would be no way
581 * to delimit that this segment ends and is not
582 * continued in the next block.
583 * The special LI (0) is used to force the segment to
584 * extend into the next block, so it is delimited there.
585 * This LI must be skipped. Also it is the last LI.
586 */
587 if (li->li == 0) {
588 data++;
589 len--;
590 m = 1; /* M is ignored, we know there is more */
591 break; /* handle E as '1', so we break! */
592 }
593 e = li->e;
594 m = li->m;
595 offset += li->li;
596 data++;
597 len--;
598 continue;
599 }
600 }
601 if (!m) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200602 LOGP(DRLCMACUL, LOGL_DEBUG, "- Last frame carries spare "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200603 "data\n");
604 }
605
Andreas Eversberge6228b32012-07-03 13:36:03 +0200606 LOGP(DRLCMACUL, LOGL_DEBUG, "- Data length after length fields: %d\n",
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200607 len);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200608 /* TLLI */
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200609 if (rh->ti) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200610 if (len < 4) {
611 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TLLI out of "
612 "frame border\n");
613 return -EINVAL;
614 }
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200615 data += 4;
616 len -= 4;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200617 LOGP(DRLCMACUL, LOGL_DEBUG, "- Length after skipping TLLI: "
618 "%d\n", len);
619 }
620
621 /* PFI */
622 if (rh->pi) {
623 LOGP(DRLCMACUL, LOGL_ERROR, "ERROR: PFI not supported, "
624 "please disable in SYSTEM INFORMATION\n");
625 if (len < 1) {
626 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA PFI out of "
627 "frame border\n");
628 return -EINVAL;
629 }
630 data++;
631 len--;
632 LOGP(DRLCMACUL, LOGL_DEBUG, "- Length after skipping PFI: "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200633 "%d\n", len);
634 }
635
636 /* Now we have:
637 * - a list of frames offsets: frame_offset[]
638 * - number of frames: i
639 * - m == 0: Last frame carries spare data (end of TBF).
640 */
641
642 /* Check if last offset would exceed frame. */
643 if (offset > len) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200644 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TBF=%d ignored, "
645 "because LI delimits data that exceeds block size.\n",
646 tbf->tfi);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200647 return -EINVAL;
648 }
649
650 /* create LLC frames */
651 for (i = 0; i < frames; i++) {
652 /* last frame ? */
653 if (i == frames - 1) {
654 /* no more data in last frame */
655 if (!m)
656 break;
657 /* data until end of frame */
658 chunk = len - frame_offset[i];
659 } else {
660 /* data until next frame */
661 chunk = frame_offset[i + 1] - frame_offset[i];
662 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200663 LOGP(DRLCMACUL, LOGL_DEBUG, "-- Appending chunk (len=%d) to "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200664 "frame at %d.\n", chunk, tbf->llc_index);
665 if (tbf->llc_index + chunk > LLC_MAX_LEN) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200666 LOGP(DRLCMACUL, LOGL_NOTICE, "LLC frame exceeds "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200667 "maximum size.\n");
668 chunk = LLC_MAX_LEN - tbf->llc_index;
669 }
670 memcpy(tbf->llc_frame + tbf->llc_index, data + frame_offset[i],
671 chunk);
672 tbf->llc_index += chunk;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200673 /* not last frame. */
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200674 if (i != frames - 1) {
675 /* send frame to SGSN */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200676 LOGP(DRLCMACUL, LOGL_INFO, "Complete UL frame for "
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200677 "TBF=%d: len=%d\n", tbf->tfi, tbf->llc_index);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200678 gprs_rlcmac_tx_ul_ud(tbf);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200679 tbf->llc_index = 0; /* reset frame space */
680 /* also check if CV==0, because the frame may fill up the
681 * block precisely, then it is also complete. normally the
682 * frame would be extended into the next block with a 0-length
683 * delimiter added to this block. */
684 } else if (rh->cv == 0) {
685 /* send frame to SGSN */
686 LOGP(DRLCMACUL, LOGL_INFO, "Complete UL frame for "
Andreas Eversberg0e403092012-07-06 11:04:57 +0200687 "TBF=%d that fits precisely in last block: "
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200688 "len=%d\n", tbf->tfi, tbf->llc_index);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200689 gprs_rlcmac_tx_ul_ud(tbf);
690 tbf->llc_index = 0; /* reset frame space */
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200691 }
692 }
693
694 return 0;
695}
696
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200697struct msgb *gprs_rlcmac_send_uplink_ack(struct gprs_rlcmac_tbf *tbf,
698 uint32_t fn)
699{
700 int final = (tbf->state == GPRS_RLCMAC_FINISHED);
701 struct msgb *msg;
702
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200703 if (final) {
704 if (tbf->poll_state != GPRS_RLCMAC_POLL_NONE) {
705 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
706 "sheduled for TBF=%d, so we must wait for "
707 "final uplink ack...\n", tbf->tfi);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200708 return NULL;
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200709 }
710 if (sba_find(tbf->trx, tbf->control_ts, (fn + 13) % 2715648)) {
711 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
712 "scheduled for single block allocation...\n");
713 return NULL;
714 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200715 }
716
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200717 msg = msgb_alloc(23, "rlcmac_ul_ack");
718 if (!msg)
719 return NULL;
720 bitvec *ack_vec = bitvec_alloc(23);
721 if (!ack_vec) {
722 msgb_free(msg);
723 return NULL;
724 }
725 bitvec_unhex(ack_vec,
726 "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
Andreas Eversberg6681bb82012-07-25 08:48:44 +0200727 RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
Ivan Kluchnikovef7f28c2012-07-12 14:49:15 +0400728 write_packet_uplink_ack(mac_control_block, tbf, final);
729 encode_gsm_rlcmac_downlink(ack_vec, mac_control_block);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200730 bitvec_pack(ack_vec, msgb_put(msg, 23));
731 bitvec_free(ack_vec);
Andreas Eversberg6681bb82012-07-25 08:48:44 +0200732 talloc_free(mac_control_block);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200733
Andreas Eversbergee31b782012-07-15 16:27:01 +0200734 /* now we must set this flag, so we are allowed to assign downlink
735 * TBF on PACCH. it is only allowed when TLLI is aknowledged. */
Andreas Eversberg08e93cd2012-07-26 08:13:06 +0200736 tbf->dir.ul.contention_resolution_done = 1;
Andreas Eversbergee31b782012-07-15 16:27:01 +0200737
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200738 if (final) {
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200739 tbf->poll_state = GPRS_RLCMAC_POLL_SCHED;
740 tbf->poll_fn = (fn + 13) % 2715648;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200741 /* waiting for final acknowledge */
742 tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_WAIT_ACK;
Andreas Eversberg08e93cd2012-07-26 08:13:06 +0200743 tbf->dir.ul.final_ack_sent = 1;
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200744 } else
Andreas Eversberge6228b32012-07-03 13:36:03 +0200745 tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE;
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200746
747 return msg;
748}
749
750/* receive UL data block
751 *
752 * The blocks are defragmented and forwarded as LLC frames, if complete.
753 */
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200754int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
755 uint8_t *data, uint8_t len)
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200756{
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200757 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200758 struct gprs_rlcmac_tbf *tbf;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200759 struct rlc_ul_header *rh = (struct rlc_ul_header *)data;
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200760 uint16_t mod_sns, mod_sns_half, offset_v_q, offset_v_r, index;
761 int rc;
762
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200763 switch (len) {
764 case 54:
765 /* omitting spare bits */
766 len = 53;
767 break;
768 case 40:
769 /* omitting spare bits */
770 len = 39;
771 break;
772 case 34:
773 /* omitting spare bits */
774 len = 33;
775 break;
776 case 23:
777 break;
778 default:
779 LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid"
780 "length: %d)\n", len);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200781 return -EINVAL;
782 }
783
784 /* find TBF inst from given TFI */
Andreas Eversbergadb2f182012-08-07 17:06:08 +0200785 tbf = tbf_by_tfi(rh->tfi, trx, GPRS_RLCMAC_UL_TBF);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200786 if (!tbf) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200787 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA unknown TBF=%d\n",
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200788 rh->tfi);
789 return 0;
790 }
Andreas Eversberg14db19e2012-08-06 15:03:03 +0200791 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_UL_DATA);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200792
Andreas Eversberg0e403092012-07-06 11:04:57 +0200793 LOGP(DRLCMACUL, LOGL_DEBUG, "UL DATA TBF=%d received (V(Q)=%d .. "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200794 "V(R)=%d)\n", rh->tfi, tbf->dir.ul.v_q, tbf->dir.ul.v_r);
795
796 /* get TLLI */
797 if (!tbf->tlli_valid) {
Andreas Eversbergbc655862012-07-23 18:13:31 +0200798 struct gprs_rlcmac_tbf *dl_tbf;
799
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200800 /* no TLLI yet */
801 if (!rh->ti) {
Andreas Eversberg0e403092012-07-06 11:04:57 +0200802 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TBF=%d without "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200803 "TLLI, but no TLLI received yet\n", rh->tfi);
804 return 0;
805 }
806 rc = tlli_from_ul_data(data, len, &tbf->tlli);
807 if (rc) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200808 LOGP(DRLCMACUL, LOGL_NOTICE, "Failed to decode TLLI "
Andreas Eversberg0e403092012-07-06 11:04:57 +0200809 "of UL DATA TBF=%d.\n", rh->tfi);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200810 return 0;
811 }
812 tbf->tlli_valid = 1;
Andreas Eversberg0e403092012-07-06 11:04:57 +0200813 LOGP(DRLCMACUL, LOGL_INFO, "Decoded premier TLLI=0x%08x of "
814 "UL DATA TBF=%d.\n", tbf->tlli, rh->tfi);
Andreas Eversbergbc655862012-07-23 18:13:31 +0200815 if ((dl_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF))) {
816 LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
817 "TLLI=0x%08x while DL TBF=%d still exists. "
818 "Killing pending DL TBF\n", tbf->tlli,
819 dl_tbf->tfi);
820 tbf_free(dl_tbf);
821 }
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200822 /* already have TLLI, but we stille get another one */
823 } else if (rh->ti) {
824 uint32_t tlli;
825 rc = tlli_from_ul_data(data, len, &tlli);
826 if (rc) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200827 LOGP(DRLCMACUL, LOGL_NOTICE, "Failed to decode TLLI "
Andreas Eversberg0e403092012-07-06 11:04:57 +0200828 "of UL DATA TBF=%d.\n", rh->tfi);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200829 return 0;
830 }
831 if (tlli != tbf->tlli) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200832 LOGP(DRLCMACUL, LOGL_NOTICE, "TLLI mismatch on UL "
Andreas Eversberg0e403092012-07-06 11:04:57 +0200833 "DATA TBF=%d. (Ignoring due to contention "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200834 "resolution)\n", rh->tfi);
835 return 0;
836 }
837 }
838
839 mod_sns = tbf->sns - 1;
840 mod_sns_half = (tbf->sns >> 1) - 1;
841
842 /* restart T3169 */
Andreas Eversbergdfa563c2012-07-06 08:13:59 +0200843 tbf_timer_start(tbf, 3169, bts->t3169, 0);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200844
845 /* Increment RX-counter */
846 tbf->dir.ul.rx_counter++;
847
848 /* current block relative to lowest unreceived block */
849 offset_v_q = (rh->bsn - tbf->dir.ul.v_q) & mod_sns;
850 /* If out of window (may happen if blocks below V(Q) are received
851 * again. */
852 if (offset_v_q >= tbf->ws) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200853 LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d out of window "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200854 "%d..%d (it's normal)\n", rh->bsn, tbf->dir.ul.v_q,
855 (tbf->dir.ul.v_q + tbf->ws - 1) & mod_sns);
856 return 0;
857 }
858 /* Write block to buffer and set receive state array. */
859 index = rh->bsn & mod_sns_half; /* memory index of block */
860 memcpy(tbf->rlc_block[index], data, len); /* Copy block. */
861 tbf->rlc_block_len[index] = len;
862 tbf->dir.ul.v_n[index] = 'R'; /* Mark received block. */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200863 LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d storing in window (%d..%d)\n",
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200864 rh->bsn, tbf->dir.ul.v_q,
865 (tbf->dir.ul.v_q + tbf->ws - 1) & mod_sns);
866 /* Raise V(R) to highest received sequence number not received. */
867 offset_v_r = (rh->bsn + 1 - tbf->dir.ul.v_r) & mod_sns;
868 if (offset_v_r < (tbf->sns >> 1)) { /* Positive offset, so raise. */
869 while (offset_v_r--) {
870 if (offset_v_r) /* all except the received block */
871 tbf->dir.ul.v_n[tbf->dir.ul.v_r & mod_sns_half]
872 = 'N'; /* Mark block as not received */
873 tbf->dir.ul.v_r = (tbf->dir.ul.v_r + 1) & mod_sns;
874 /* Inc V(R). */
875 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200876 LOGP(DRLCMACUL, LOGL_DEBUG, "- Raising V(R) to %d\n",
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200877 tbf->dir.ul.v_r);
878 }
879
880 /* Raise V(Q) if possible, and retrieve LLC frames from blocks.
881 * This is looped until there is a gap (non received block) or
882 * the window is empty.*/
883 while (tbf->dir.ul.v_q != tbf->dir.ul.v_r && tbf->dir.ul.v_n[
884 (index = tbf->dir.ul.v_q & mod_sns_half)] == 'R') {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200885 LOGP(DRLCMACUL, LOGL_DEBUG, "- Taking block %d out, raising "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200886 "V(Q) to %d\n", tbf->dir.ul.v_q,
887 (tbf->dir.ul.v_q + 1) & mod_sns);
888 /* get LLC data from block */
889 gprs_rlcmac_assemble_llc(tbf, tbf->rlc_block[index],
890 tbf->rlc_block_len[index]);
891 /* raise V(Q), because block already received */
892 tbf->dir.ul.v_q = (tbf->dir.ul.v_q + 1) & mod_sns;
893 }
894
895 /* Check CV of last frame in buffer */
896 if (tbf->state == GPRS_RLCMAC_FLOW /* still in flow state */
897 && tbf->dir.ul.v_q == tbf->dir.ul.v_r) { /* if complete */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200898 struct rlc_ul_header *last_rh = (struct rlc_ul_header *)
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200899 tbf->rlc_block[(tbf->dir.ul.v_r - 1) & mod_sns_half];
Andreas Eversberge6228b32012-07-03 13:36:03 +0200900 LOGP(DRLCMACUL, LOGL_DEBUG, "- No gaps in received block, "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200901 "last block: BSN=%d CV=%d\n", last_rh->bsn,
902 last_rh->cv);
903 if (last_rh->cv == 0) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200904 LOGP(DRLCMACUL, LOGL_DEBUG, "- Finished with UL "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200905 "TBF\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200906 tbf_new_state(tbf, GPRS_RLCMAC_FINISHED);
907 /* Reset N3103 counter. */
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200908 tbf->dir.ul.n3103 = 0;
909 }
910 }
911
912 /* If TLLI is included or if we received half of the window, we send
913 * an ack/nack */
Andreas Eversberge6228b32012-07-03 13:36:03 +0200914 if (rh->si || rh->ti || tbf->state == GPRS_RLCMAC_FINISHED
Andreas Eversbergf54a89e2012-07-16 11:56:11 +0200915 || (tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200916 if (rh->si) {
Andreas Eversbergf54a89e2012-07-16 11:56:11 +0200917 LOGP(DRLCMACUL, LOGL_NOTICE, "- Scheduling Ack/Nack, "
Andreas Eversberge6228b32012-07-03 13:36:03 +0200918 "because MS is stalled.\n");
919 }
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200920 if (rh->ti) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200921 LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200922 "because TLLI is included.\n");
923 }
924 if (tbf->state == GPRS_RLCMAC_FINISHED) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200925 LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200926 "because last block has CV==0.\n");
927 }
Andreas Eversbergf54a89e2012-07-16 11:56:11 +0200928 if ((tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) {
Andreas Eversberge6228b32012-07-03 13:36:03 +0200929 LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, "
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200930 "because %d frames received.\n",
Andreas Eversbergf54a89e2012-07-16 11:56:11 +0200931 SEND_ACK_AFTER_FRAMES);
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200932 }
Andreas Eversberge6228b32012-07-03 13:36:03 +0200933 if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_NONE) {
934 /* trigger sending at next RTS */
935 tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_SEND_ACK;
936 } else {
937 /* already triggered */
938 LOGP(DRLCMACUL, LOGL_DEBUG, "- Sending Ack/Nack is "
939 "already triggered, don't schedule!\n");
940 }
Andreas Eversberg66690dd2012-06-27 15:44:31 +0200941 }
942
943 return 0;
944}
945
Andreas Eversberge6228b32012-07-03 13:36:03 +0200946struct msgb *gprs_rlcmac_send_packet_uplink_assignment(
947 struct gprs_rlcmac_tbf *tbf, uint32_t fn)
948{
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200949 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
Andreas Eversberge6228b32012-07-03 13:36:03 +0200950 struct msgb *msg;
951 struct gprs_rlcmac_tbf *new_tbf;
952
Andreas Eversberg802bb6e2012-08-06 11:15:05 +0200953#if POLLING_ASSIGNMENT_UL == 1
Andreas Eversberge6228b32012-07-03 13:36:03 +0200954 if (tbf->poll_state != GPRS_RLCMAC_POLL_NONE) {
955 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
956 "sheduled for TBF=%d, so we must wait for uplink "
957 "assignment...\n", tbf->tfi);
958 return NULL;
959 }
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200960 if (sba_find(tbf->trx, tbf->control_ts, (fn + 13) % 2715648)) {
961 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already scheduled for "
962 "single block allocation...\n");
963 return NULL;
964 }
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +0200965#endif
Andreas Eversberge6228b32012-07-03 13:36:03 +0200966
967 /* on down TBF we get the uplink TBF to be assigned. */
968 if (tbf->direction == GPRS_RLCMAC_DL_TBF)
969 new_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF);
970 else
971 new_tbf = tbf;
972
973 if (!new_tbf) {
974 LOGP(DRLCMACUL, LOGL_ERROR, "We have a schedule for uplink "
975 "assignment at downlink TBF=%d, but there is no uplink "
976 "TBF\n", tbf->tfi);
977 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
978 return NULL;
979 }
980
981 msg = msgb_alloc(23, "rlcmac_ul_ass");
982 if (!msg)
983 return NULL;
Andreas Eversberg0e403092012-07-06 11:04:57 +0200984 LOGP(DRLCMAC, LOGL_INFO, "TBF: START TFI: %u TLLI: 0x%08x Packet Uplink Assignment (PACCH)\n", new_tbf->tfi, new_tbf->tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200985 bitvec *ass_vec = bitvec_alloc(23);
986 if (!ass_vec) {
987 msgb_free(msg);
988 return NULL;
989 }
990 bitvec_unhex(ass_vec,
991 "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
992 write_packet_uplink_assignment(ass_vec, tbf->tfi,
Andreas Eversberg07e97cf2012-08-07 16:00:56 +0200993 (tbf->direction == GPRS_RLCMAC_DL_TBF), tbf->tlli,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +0200994 tbf->tlli_valid, new_tbf, POLLING_ASSIGNMENT_UL, bts->alpha,
995 bts->gamma);
Andreas Eversberge6228b32012-07-03 13:36:03 +0200996 bitvec_pack(ass_vec, msgb_put(msg, 23));
Andreas Eversberg6681bb82012-07-25 08:48:44 +0200997 RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
Andreas Eversberg0e403092012-07-06 11:04:57 +0200998 LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +0200999 decode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
Andreas Eversberg0e403092012-07-06 11:04:57 +02001000 LOGPC(DCSN1, LOGL_NOTICE, "\n");
1001 LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Uplink Assignment -------------------------\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +02001002 bitvec_free(ass_vec);
Andreas Eversberg6681bb82012-07-25 08:48:44 +02001003 talloc_free(mac_control_block);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001004
Andreas Eversberg802bb6e2012-08-06 11:15:05 +02001005#if POLLING_ASSIGNMENT_UL == 1
Andreas Eversberge6228b32012-07-03 13:36:03 +02001006 tbf->poll_state = GPRS_RLCMAC_POLL_SCHED;
1007 tbf->poll_fn = (fn + 13) % 2715648;
1008 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK;
1009#else
1010 tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE;
Andreas Eversberg642c7d32012-07-23 17:58:55 +02001011 tbf_new_state(new_tbf, GPRS_RLCMAC_FLOW);
1012 tbf_assign_control_ts(new_tbf);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001013#endif
1014
1015 return msg;
1016}
1017
1018int gprs_rlcmac_rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta)
1019{
Andreas Eversbergdfa563c2012-07-06 08:13:59 +02001020 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001021 struct gprs_rlcmac_tbf *tbf;
1022 uint8_t trx, ts;
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +02001023 int8_t tfi; /* must be signed */
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001024 uint8_t sb = 0;
1025 uint32_t sb_fn = 0;
1026 int rc;
1027 uint8_t plen;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001028
1029 LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, so we provide "
1030 "one:\n");
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001031 if ((ra & 0xf8) == 0x70) {
1032 LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block "
1033 "allocation\n");
1034 sb = 1;
1035 } else if (bts->force_two_phase) {
1036 LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single phase access, "
1037 "but we force two phase access\n");
1038 sb = 1;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001039 }
Andreas Eversberge6228b32012-07-03 13:36:03 +02001040 if (qta < 0)
1041 qta = 0;
1042 if (qta > 252)
1043 qta = 252;
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001044 if (sb) {
1045 rc = sba_alloc(&trx, &ts, &sb_fn, qta >> 2);
1046 if (rc < 0)
1047 return rc;
1048 LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] RACH qbit-ta=%d "
1049 "ra=0x%02x, Fn=%d (%d,%d,%d)\n", qta, ra, Fn,
1050 (Fn / (26 * 51)) % 32, Fn % 51, Fn % 26);
1051 LOGP(DRLCMAC, LOGL_INFO, "TX: Immediate Assignment Uplink "
1052 "(AGCH)\n");
1053 } else {
1054 // Create new TBF
1055 tfi = tfi_alloc(GPRS_RLCMAC_UL_TBF, &trx, &ts, -1, -1);
1056 if (tfi < 0) {
1057 LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n");
1058 /* FIXME: send reject */
1059 return -EBUSY;
1060 }
1061 /* set class to 0, since we don't know the multislot class yet */
1062 tbf = tbf_alloc(NULL, GPRS_RLCMAC_UL_TBF, tfi, trx, ts, 0, 1);
1063 if (!tbf) {
1064 LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n");
1065 /* FIXME: send reject */
1066 return -EBUSY;
1067 }
1068 tbf->ta = qta >> 2;
1069 tbf_new_state(tbf, GPRS_RLCMAC_FLOW);
1070 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH);
1071 tbf_timer_start(tbf, 3169, bts->t3169, 0);
1072 LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] START TFI: %u\n",
1073 tbf->tfi);
1074 LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] TFI: %u RACH "
1075 "qbit-ta=%d ra=0x%02x, Fn=%d (%d,%d,%d)\n", tbf->tfi,
1076 qta, ra, Fn, (Fn / (26 * 51)) % 32, Fn % 51, Fn % 26);
1077 LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u Immediate "
1078 "Assignment Uplink (AGCH)\n", tbf->tfi);
1079 }
Andreas Eversberg7b045012012-07-05 07:38:49 +02001080 bitvec *immediate_assignment = bitvec_alloc(22) /* without plen */;
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001081 bitvec_unhex(immediate_assignment,
1082 "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
1083 if (sb)
1084 plen = write_immediate_assignment(immediate_assignment, 0, ra,
1085 Fn, qta >> 2, bts->trx[trx].arfcn, ts,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001086 bts->trx[trx].pdch[ts].tsc, 0, 0, 0, 0, sb_fn, 1,
1087 bts->alpha, bts->gamma);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001088 else
1089 plen = write_immediate_assignment(immediate_assignment, 0, ra,
1090 Fn, tbf->ta, tbf->arfcn, tbf->first_ts, tbf->tsc,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001091 tbf->tfi, tbf->dir.ul.usf[tbf->first_ts], 0, 0, 0, 0,
1092 bts->alpha, bts->gamma);
Andreas Eversberg7b045012012-07-05 07:38:49 +02001093 pcu_l1if_tx_agch(immediate_assignment, plen);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001094 bitvec_free(immediate_assignment);
1095
1096 return 0;
1097}
1098
1099
1100/*
1101 * DL data block flow
1102 */
1103
Andreas Eversberg24131bf2012-07-21 11:09:58 +02001104static struct msgb *llc_dequeue(struct gprs_rlcmac_tbf *tbf)
1105{
1106 struct msgb *msg;
1107 struct timeval *tv, tv_now;
1108 uint32_t octets = 0, frames = 0;
1109
1110 gettimeofday(&tv_now, NULL);
1111
1112 while ((msg = msgb_dequeue(&tbf->llc_queue))) {
1113 tv = (struct timeval *)msg->data;
1114 msgb_pull(msg, sizeof(*tv));
1115 if (tv->tv_sec /* not infinite */
1116 && (tv_now.tv_sec > tv->tv_sec /* and secs expired */
1117 || (tv_now.tv_sec == tv->tv_sec /* .. or if secs equal .. */
1118 && tv_now.tv_usec > tv->tv_usec))) { /* .. usecs expired */
1119 LOGP(DRLCMACDL, LOGL_NOTICE, "Discarding LLC PDU of "
1120 "DL TBF=%d, because lifetime limit reached\n",
1121 tbf->tfi);
1122 frames++;
1123 octets += msg->len;
1124 msgb_free(msg);
1125 continue;
1126 }
1127 break;
1128 }
1129
1130 if (frames) {
1131 if (frames > 0xff)
1132 frames = 0xff;
1133 if (octets > 0xffffff)
1134 octets = 0xffffff;
1135 bssgp_tx_llc_discarded(bctx, tbf->tlli, frames, octets);
1136 }
1137
1138 return msg;
1139}
1140
Andreas Eversbergb3ded4c2012-07-24 10:47:24 +02001141static int gprs_rlcmac_debug_bw(struct gprs_rlcmac_tbf *tbf, uint16_t octets)
1142{
1143 struct timeval now_tv, *bw_tv = &tbf->bw_tv;
1144 uint32_t elapsed;
1145
1146 tbf->bw_octets += octets;
1147
1148 gettimeofday(&now_tv, NULL);
1149 elapsed = ((now_tv.tv_sec - bw_tv->tv_sec) << 7)
1150 + ((now_tv.tv_usec - bw_tv->tv_usec) << 7) / 1000000;
1151 if (elapsed < 128)
1152 return 0;
1153
1154 LOGP(DRLCMACBW, LOGL_DEBUG, "DL Bandwitdh of TLLI=0x%08x: %d KBits/s\n",
1155 tbf->tlli, tbf->bw_octets / elapsed);
1156
1157 /* reset bandwidth values timestamp */
1158 memcpy(bw_tv, &now_tv, sizeof(struct timeval));
1159 tbf->bw_octets = 0;
1160
1161 return 0;
1162}
Andreas Eversberg24131bf2012-07-21 11:09:58 +02001163
Andreas Eversberge6228b32012-07-03 13:36:03 +02001164/* send DL data block
1165 *
1166 * The messages are fragmented and forwarded as data blocks.
1167 */
1168struct msgb *gprs_rlcmac_send_data_block_acknowledged(
Andreas Eversberg592e04a2012-07-15 06:25:37 +02001169 struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts)
Andreas Eversberge6228b32012-07-03 13:36:03 +02001170{
1171 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
1172 struct rlc_dl_header *rh;
1173 struct rlc_li_field *li;
1174 uint8_t block_length; /* total length of block, including spare bits */
1175 uint8_t block_data; /* usable data of block, w/o spare bits, inc. MAC */
1176 struct msgb *msg, *dl_msg;
1177 uint8_t bsn;
1178 uint16_t mod_sns = tbf->sns - 1;
1179 uint16_t mod_sns_half = (tbf->sns >> 1) - 1;
1180 uint16_t index;
1181 uint8_t *delimiter, *data, *e_pointer;
1182 uint8_t len;
1183 uint16_t space, chunk;
1184
Andreas Eversberg0e403092012-07-06 11:04:57 +02001185 LOGP(DRLCMACDL, LOGL_DEBUG, "DL DATA TBF=%d downlink (V(A)==%d .. "
Andreas Eversberge6228b32012-07-03 13:36:03 +02001186 "V(S)==%d)\n", tbf->tfi, tbf->dir.dl.v_a, tbf->dir.dl.v_s);
1187
1188do_resend:
1189 /* check if there is a block with negative acknowledgement */
1190 for (bsn = tbf->dir.dl.v_a; bsn != tbf->dir.dl.v_s;
1191 bsn = (bsn + 1) & mod_sns) {
1192 index = (bsn & mod_sns_half);
1193 if (tbf->dir.dl.v_b[index] == 'N'
1194 || tbf->dir.dl.v_b[index] == 'X') {
1195 LOGP(DRLCMACDL, LOGL_DEBUG, "- Resending BSN %d\n",
1196 bsn);
1197 /* re-send block with negative aknowlegement */
1198 tbf->dir.dl.v_b[index] = 'U'; /* unacked */
1199 goto tx_block;
1200 }
1201 }
1202
1203 /* if the window has stalled, or transfer is complete,
1204 * send an unacknowledged block */
1205 if (tbf->state == GPRS_RLCMAC_FINISHED
1206 || ((tbf->dir.dl.v_s - tbf->dir.dl.v_a) & mod_sns) == tbf->ws) {
1207 int resend = 0;
1208
1209 if (tbf->state == GPRS_RLCMAC_FINISHED)
1210 LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, "
1211 "because all blocks have been transmitted.\n",
1212 tbf->dir.dl.v_a);
1213 else
Andreas Eversberg4b470ff2012-07-16 12:02:40 +02001214 LOGP(DRLCMACDL, LOGL_NOTICE, "- Restarting at BSN %d, "
Andreas Eversberge6228b32012-07-03 13:36:03 +02001215 "because all window is stalled.\n",
1216 tbf->dir.dl.v_a);
1217 /* If V(S) == V(A) and finished state, we would have received
1218 * acknowledgement of all transmitted block. In this case we
1219 * would have transmitted the final block, and received ack
1220 * from MS. But in this case we did not receive the final ack
1221 * indication from MS. This should never happen if MS works
1222 * correctly. */
1223 if (tbf->dir.dl.v_s == tbf->dir.dl.v_a) {
Andreas Eversberg6664a902012-07-15 06:52:19 +02001224 LOGP(DRLCMACDL, LOGL_ERROR, "- MS acked all block, "
1225 "but we still transmitting!\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +02001226 /* we just send final block again */
1227 index = ((tbf->dir.dl.v_s - 1) & mod_sns_half);
1228 goto tx_block;
1229 }
1230
1231 /* cycle through all unacked blocks */
1232 for (bsn = tbf->dir.dl.v_a; bsn != tbf->dir.dl.v_s;
1233 bsn = (bsn + 1) & mod_sns) {
1234 index = (bsn & mod_sns_half);
1235 if (tbf->dir.dl.v_b[index] == 'U') {
1236 /* mark to be re-send */
1237 tbf->dir.dl.v_b[index] = 'X';
1238 resend++;
1239 }
1240 }
1241 /* At this point there should be at leasst one unacked block
1242 * to be resent. If not, this is an software error. */
1243 if (resend == 0) {
1244 LOGP(DRLCMACDL, LOGL_ERROR, "Software error: "
1245 "There are no unacknowledged blocks, but V(A) "
1246 " != V(S). PLEASE FIX!\n");
1247 /* we just send final block again */
1248 index = ((tbf->dir.dl.v_s - 1) & mod_sns_half);
1249 goto tx_block;
1250 }
1251 goto do_resend;
1252 }
1253
1254 LOGP(DRLCMACDL, LOGL_DEBUG, "- Sending new block at BSN %d\n",
1255 tbf->dir.dl.v_s);
1256
1257 /* now we still have untransmitted LLC data, so we fill mac block */
1258 index = tbf->dir.dl.v_s & mod_sns_half;
1259 data = tbf->rlc_block[index];
Andreas Eversbergb3c6f6c2012-07-06 07:40:08 +02001260 switch (bts->initial_cs) {
Andreas Eversberge6228b32012-07-03 13:36:03 +02001261 case 2: /* CS-2 */
1262 block_length = 34;
1263 block_data = 33;
1264 break;
1265 case 3: /* CS-3 */
1266 block_length = 40;
1267 block_data = 39;
1268 break;
1269 case 4: /* CS-4 */
1270 block_length = 54;
1271 block_data = 53;
1272 break;
1273 default: /* CS-1 */
1274 block_length = 23;
1275 block_data = 23;
1276 }
1277 memset(data, 0x2b, block_data); /* spare bits will be left 0 */
1278 rh = (struct rlc_dl_header *)data;
1279 rh->pt = 0; /* Data Block */
1280 rh->rrbp = rh->s_p = 0; /* Polling, set later, if required */
1281 rh->usf = 7; /* will be set at scheduler */
1282 rh->pr = 0; /* FIXME: power reduction */
1283 rh->tfi = tbf->tfi; /* TFI */
1284 rh->fbi = 0; /* Final Block Indicator, set late, if true */
1285 rh->bsn = tbf->dir.dl.v_s; /* Block Sequence Number */
1286 rh->e = 0; /* Extension bit, maybe set later */
1287 e_pointer = data + 2; /* points to E of current chunk */
1288 data += 3;
1289 delimiter = data; /* where next length header would be stored */
1290 space = block_data - 3;
1291 while (1) {
1292 chunk = tbf->llc_length - tbf->llc_index;
1293 /* if chunk will exceed block limit */
1294 if (chunk > space) {
1295 LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d "
1296 "larger than space (%d) left in block: copy "
1297 "only remaining space, and we are done\n",
1298 chunk, space);
1299 /* block is filled, so there is no extension */
1300 *e_pointer |= 0x01;
1301 /* fill only space */
1302 memcpy(data, tbf->llc_frame + tbf->llc_index, space);
1303 /* incement index */
1304 tbf->llc_index += space;
1305 /* return data block as message */
1306 break;
1307 }
1308 /* if FINAL chunk would fit precisely in space left */
1309 if (chunk == space && llist_empty(&tbf->llc_queue)) {
1310 LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d "
1311 "would exactly fit into space (%d): because "
1312 "this is a final block, we don't add length "
1313 "header, and we are done\n", chunk, space);
Andreas Eversberg0e403092012-07-06 11:04:57 +02001314 LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for "
1315 "TBF=%d that fits precisely in last block: "
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +02001316 "len=%d\n", tbf->tfi, tbf->llc_length);
Andreas Eversbergb3ded4c2012-07-24 10:47:24 +02001317 gprs_rlcmac_debug_bw(tbf, tbf->llc_length);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001318 /* block is filled, so there is no extension */
1319 *e_pointer |= 0x01;
1320 /* fill space */
1321 memcpy(data, tbf->llc_frame + tbf->llc_index, space);
1322 /* reset LLC frame */
1323 tbf->llc_index = tbf->llc_length = 0;
1324 /* final block */
1325 rh->fbi = 1; /* we indicate final block */
1326 tbf_new_state(tbf, GPRS_RLCMAC_FINISHED);
1327 /* return data block as message */
1328 break;
1329 }
1330 /* if chunk would fit exactly in space left */
1331 if (chunk == space) {
1332 LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d "
1333 "would exactly fit into space (%d): add length "
1334 "header with LI=0, to make frame extend to "
1335 "next block, and we are done\n", chunk, space);
1336 /* make space for delimiter */
1337 if (delimiter != data)
1338 memcpy(delimiter + 1, delimiter,
1339 data - delimiter);
1340 data++;
1341 space--;
1342 /* add LI with 0 length */
1343 li = (struct rlc_li_field *)delimiter;
1344 li->e = 1; /* not more extension */
1345 li->m = 0; /* shall be set to 0, in case of li = 0 */
1346 li->li = 0; /* chunk fills the complete space */
1347 // no need to set e_pointer nor increase delimiter
1348 /* fill only space, which is 1 octet less than chunk */
1349 memcpy(data, tbf->llc_frame + tbf->llc_index, space);
1350 /* incement index */
1351 tbf->llc_index += space;
1352 /* return data block as message */
1353 break;
1354 }
1355 LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d is less "
1356 "than remaining space (%d): add length header to "
1357 "to delimit LLC frame\n", chunk, space);
1358 /* the LLC frame chunk ends in this block */
1359 /* make space for delimiter */
1360 if (delimiter != data)
1361 memcpy(delimiter + 1, delimiter, data - delimiter);
1362 data++;
1363 space--;
1364 /* add LI to delimit frame */
1365 li = (struct rlc_li_field *)delimiter;
1366 li->e = 0; /* Extension bit, maybe set later */
1367 li->m = 0; /* will be set later, if there is more LLC data */
1368 li->li = chunk; /* length of chunk */
1369 e_pointer = delimiter; /* points to E of current delimiter */
1370 delimiter++;
1371 /* copy (rest of) LLC frame to space */
1372 memcpy(data, tbf->llc_frame + tbf->llc_index, chunk);
1373 data += chunk;
1374 space -= chunk;
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +02001375 LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for TBF=%d: "
1376 "len=%d\n", tbf->tfi, tbf->llc_length);
Andreas Eversbergb3ded4c2012-07-24 10:47:24 +02001377 gprs_rlcmac_debug_bw(tbf, tbf->llc_length);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001378 /* reset LLC frame */
1379 tbf->llc_index = tbf->llc_length = 0;
1380 /* dequeue next LLC frame, if any */
Andreas Eversberg24131bf2012-07-21 11:09:58 +02001381 msg = llc_dequeue(tbf);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001382 if (msg) {
Andreas Eversberg0e403092012-07-06 11:04:57 +02001383 LOGP(DRLCMACDL, LOGL_INFO, "- Dequeue next LLC for "
1384 "TBF=%d (len=%d)\n", tbf->tfi, msg->len);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001385 memcpy(tbf->llc_frame, msg->data, msg->len);
1386 tbf->llc_length = msg->len;
1387 msgb_free(msg);
1388 }
1389 /* if we have more data and we have space left */
1390 if (space > 0 && tbf->llc_length) {
1391 li->m = 1; /* we indicate more frames to follow */
1392 continue;
1393 }
1394 /* if we don't have more LLC frames */
1395 if (!tbf->llc_length) {
Andreas Eversberg0e403092012-07-06 11:04:57 +02001396 LOGP(DRLCMACDL, LOGL_DEBUG, "-- Final block, so we "
Andreas Eversberge6228b32012-07-03 13:36:03 +02001397 "done.\n");
1398 li->e = 1; /* we cannot extend */
1399 rh->fbi = 1; /* we indicate final block */
Andreas Eversbergf54a89e2012-07-16 11:56:11 +02001400 tbf->dir.dl.tx_counter = POLL_ACK_AFTER_FRAMES + 1;
1401 /* + 1 indicates: first final ack */
Andreas Eversberge6228b32012-07-03 13:36:03 +02001402 tbf_new_state(tbf, GPRS_RLCMAC_FINISHED);
1403 break;
1404 }
1405 /* we have no space left */
Andreas Eversberg0e403092012-07-06 11:04:57 +02001406 LOGP(DRLCMACDL, LOGL_DEBUG, "-- No space left, so we are "
Andreas Eversberge6228b32012-07-03 13:36:03 +02001407 "done.\n");
1408 li->e = 1; /* we cannot extend */
1409 break;
1410 }
1411 LOGP(DRLCMACDL, LOGL_DEBUG, "data block: %s\n",
1412 osmo_hexdump(tbf->rlc_block[index], block_length));
1413 tbf->rlc_block_len[index] = block_length;
1414 /* raise send state and set ack state array */
1415 tbf->dir.dl.v_b[index] = 'U'; /* unacked */
1416 tbf->dir.dl.v_s = (tbf->dir.dl.v_s + 1) & mod_sns; /* inc send state */
1417
1418tx_block:
1419 /* from this point on, new block is sent or old block is resent */
1420
1421 /* get data and header from current block */
1422 data = tbf->rlc_block[index];
1423 len = tbf->rlc_block_len[index];
1424 rh = (struct rlc_dl_header *)data;
1425
Andreas Eversberge6228b32012-07-03 13:36:03 +02001426 /* Clear Polling, if still set in history buffer */
1427 rh->s_p = 0;
1428
Andreas Eversbergf54a89e2012-07-16 11:56:11 +02001429 /* poll after POLL_ACK_AFTER_FRAMES frames, or when final block is tx.
1430 */
1431 if (tbf->dir.dl.tx_counter >= POLL_ACK_AFTER_FRAMES) {
1432 if (tbf->dir.dl.tx_counter > POLL_ACK_AFTER_FRAMES) {
1433 /* if rx_counter is POLL_ACK_AFTER_FRAMES + 1, this
Andreas Eversberg5e043da2012-07-15 06:51:30 +02001434 * indicates: poll caused by final ack. */
Andreas Eversberge6228b32012-07-03 13:36:03 +02001435 LOGP(DRLCMACDL, LOGL_DEBUG, "- Scheduling Ack/Nack "
1436 "polling, because final block sent.\n");
Andreas Eversberg5e043da2012-07-15 06:51:30 +02001437 } else {
Andreas Eversberge6228b32012-07-03 13:36:03 +02001438 LOGP(DRLCMACDL, LOGL_DEBUG, "- Scheduling Ack/Nack "
1439 "polling, because %d blocks sent.\n",
Andreas Eversbergf54a89e2012-07-16 11:56:11 +02001440 POLL_ACK_AFTER_FRAMES);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001441 }
Andreas Eversberg5e043da2012-07-15 06:51:30 +02001442 tbf->dir.dl.tx_counter = 0;
1443 /* scheduling not possible, because: */
Andreas Eversberge6228b32012-07-03 13:36:03 +02001444 if (tbf->poll_state != GPRS_RLCMAC_POLL_NONE)
Andreas Eversberg5e043da2012-07-15 06:51:30 +02001445 LOGP(DRLCMAC, LOGL_DEBUG, "Polling is already "
Andreas Eversberge6228b32012-07-03 13:36:03 +02001446 "sheduled for TBF=%d, so we must wait for "
1447 "requesting downlink ack\n", tbf->tfi);
Andreas Eversberg5e043da2012-07-15 06:51:30 +02001448 else if (tbf->control_ts != ts)
1449 LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be "
1450 "sheduled in this TS %d, waiting for "
1451 "TS %d\n", ts, tbf->control_ts);
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001452 else if (sba_find(tbf->trx, ts, (fn + 13) % 2715648))
1453 LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be "
1454 "sheduled, because single block alllocation "
1455 "already exists\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +02001456 else {
Andreas Eversbergee31b782012-07-15 16:27:01 +02001457 LOGP(DRLCMAC, LOGL_DEBUG, "Polling sheduled in this "
1458 "TS %d\n", ts);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001459 /* start timer whenever we send the final block */
1460 if (rh->fbi == 1)
Andreas Eversbergdfa563c2012-07-06 08:13:59 +02001461 tbf_timer_start(tbf, 3191, bts->t3191, 0);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001462
1463 /* schedule polling */
1464 tbf->poll_state = GPRS_RLCMAC_POLL_SCHED;
1465 tbf->poll_fn = (fn + 13) % 2715648;
1466
1467 /* set polling in header */
1468 rh->rrbp = 0; /* N+13 */
1469 rh->s_p = 1; /* Polling */
Andreas Eversberg5e043da2012-07-15 06:51:30 +02001470
1471 /* Increment TX-counter */
1472 tbf->dir.dl.tx_counter++;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001473 }
Andreas Eversberg5e043da2012-07-15 06:51:30 +02001474 } else {
1475 /* Increment TX-counter */
1476 tbf->dir.dl.tx_counter++;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001477 }
1478
1479 /* return data block as message */
1480 dl_msg = msgb_alloc(len, "rlcmac_dl_data");
1481 if (!dl_msg)
1482 return NULL;
1483 memcpy(msgb_put(dl_msg, len), data, len);
1484
1485 return dl_msg;
1486}
1487
1488int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final,
1489 uint8_t ssn, uint8_t *rbb)
1490{
1491 char show_rbb[65], show_v_b[RLC_MAX_SNS + 1];
1492 uint16_t mod_sns = tbf->sns - 1;
1493 uint16_t mod_sns_half = (tbf->sns >> 1) - 1;
1494 int i; /* must be signed */
1495 int16_t dist; /* must be signed */
1496 uint8_t bit;
1497 uint16_t bsn;
1498 struct msgb *msg;
1499
Andreas Eversberg0e403092012-07-06 11:04:57 +02001500 LOGP(DRLCMACDL, LOGL_DEBUG, "TBF=%d downlink acknowledge\n",
Andreas Eversberge6228b32012-07-03 13:36:03 +02001501 tbf->tfi);
1502
1503 if (!final) {
1504 /* show received array in debug (bit 64..1) */
1505 for (i = 63; i >= 0; i--) {
1506 bit = (rbb[i >> 3] >> (7 - (i&7))) & 1;
1507 show_rbb[i] = (bit) ? '1' : 'o';
1508 }
1509 show_rbb[64] = '\0';
1510 LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\""
Andreas Eversberg4b470ff2012-07-16 12:02:40 +02001511 "(BSN=%d) 1=ACK o=NACK\n", (ssn - 64) & mod_sns,
1512 show_rbb, (ssn - 1) & mod_sns);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001513
1514 /* apply received array to receive state (SSN-64..SSN-1) */
1515 /* calculate distance of ssn from V(S) */
1516 dist = (tbf->dir.dl.v_s - ssn) & mod_sns;
1517 /* check if distance is less than distance V(A)..V(S) */
1518 if (dist < ((tbf->dir.dl.v_s - tbf->dir.dl.v_a) & mod_sns)) {
1519 /* SSN - 1 is in range V(A)..V(S)-1 */
1520 for (i = 63, bsn = (ssn - 1) & mod_sns;
1521 i >= 0 && bsn != ((tbf->dir.dl.v_a - 1) & mod_sns);
1522 i--, bsn = (bsn - 1) & mod_sns) {
1523 bit = (rbb[i >> 3] >> (7 - (i&7))) & 1;
1524 if (bit) {
1525 LOGP(DRLCMACDL, LOGL_DEBUG, "- got "
1526 "ack for BSN=%d\n", bsn);
1527 tbf->dir.dl.v_b[bsn & mod_sns_half]
1528 = 'A';
1529 } else {
1530 LOGP(DRLCMACDL, LOGL_DEBUG, "- got "
1531 "NACK for BSN=%d\n", bsn);
1532 tbf->dir.dl.v_b[bsn & mod_sns_half]
1533 = 'N';
1534 }
1535 }
1536 } else {
Andreas Eversberg0f13c402012-07-16 11:59:23 +02001537 /* this might happpen, if the downlink assignment
1538 * was not received by ms and the ack refers
1539 * to previous TBF
1540 * FIXME: we should implement polling for
1541 * control ack!*/
1542 LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of "
1543 "V(A)..V(S) range (DL TBF=%d) Free TFB!\n",
1544 tbf->tfi);
1545 return 1; /* indicate to free TBF */
Andreas Eversberge6228b32012-07-03 13:36:03 +02001546 }
1547
1548 /* raise V(A), if possible */
1549 for (i = 0, bsn = tbf->dir.dl.v_a; bsn != tbf->dir.dl.v_s;
1550 i++, bsn = (bsn + 1) & mod_sns) {
1551 if (tbf->dir.dl.v_b[bsn & mod_sns_half] == 'A') {
1552 tbf->dir.dl.v_b[bsn & mod_sns_half] = 'I';
1553 /* mark invalid */
1554 tbf->dir.dl.v_a = (tbf->dir.dl.v_a + 1)
1555 & mod_sns;
1556 } else
1557 break;
1558 }
1559
1560 /* show receive state array in debug (V(A)..V(S)-1) */
1561 for (i = 0, bsn = tbf->dir.dl.v_a; bsn != tbf->dir.dl.v_s;
1562 i++, bsn = (bsn + 1) & mod_sns) {
1563 show_v_b[i] = tbf->dir.dl.v_b[bsn & mod_sns_half];
1564 if (show_v_b[i] == 0)
1565 show_v_b[i] = ' ';
1566 }
1567 show_v_b[i] = '\0';
1568 LOGP(DRLCMACDL, LOGL_DEBUG, "- V(B): (V(A)=%d)\"%s\""
1569 "(V(S)-1=%d) A=Acked N=Nacked U=Unacked "
1570 "X=Resend-Unacked\n", tbf->dir.dl.v_a, show_v_b,
1571 (tbf->dir.dl.v_s - 1) & mod_sns);
1572
Andreas Eversberg6664a902012-07-15 06:52:19 +02001573 if (tbf->state == GPRS_RLCMAC_FINISHED
1574 && tbf->dir.dl.v_s == tbf->dir.dl.v_a) {
1575 LOGP(DRLCMACDL, LOGL_NOTICE, "Received final block, "
Andreas Eversberg4b470ff2012-07-16 12:02:40 +02001576 "but without final ack inidcation\n");
Andreas Eversberg6664a902012-07-15 06:52:19 +02001577 } else
1578 return 0;
Andreas Eversberg4b470ff2012-07-16 12:02:40 +02001579 } else
1580 LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n");
Andreas Eversberge6228b32012-07-03 13:36:03 +02001581
1582 /* check for LLC PDU in the LLC Queue */
Andreas Eversberg24131bf2012-07-21 11:09:58 +02001583 msg = llc_dequeue(tbf);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001584 if (!msg) {
1585 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
1586
1587 /* no message, start T3193, change state to RELEASE */
1588 LOGP(DRLCMACDL, LOGL_DEBUG, "- No new message, so we "
1589 "release.\n");
Andreas Eversbergb3c6f6c2012-07-06 07:40:08 +02001590 /* start T3193 */
Andreas Eversbergdfa563c2012-07-06 08:13:59 +02001591 tbf_timer_start(tbf, 3193, bts->t3193_msec / 1000,
Andreas Eversbergdf4d20e2012-09-24 13:49:38 +02001592 (bts->t3193_msec % 1000) * 1000);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001593 tbf_new_state(tbf, GPRS_RLCMAC_WAIT_RELEASE);
1594
1595 return 0;
1596 }
1597 memcpy(tbf->llc_frame, msg->data, msg->len);
1598 tbf->llc_length = msg->len;
1599 msgb_free(msg);
1600
1601 /* we have a message, so we trigger downlink assignment, and there
1602 * set the state to ASSIGN. also we set old_downlink, because we
1603 * re-use this tbf. */
1604 LOGP(DRLCMAC, LOGL_DEBUG, "Trigger dowlink assignment on PACCH, "
1605 "because another LLC PDU has arrived in between\n");
1606 memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); /* reset RLC states */
Andreas Eversberg14db19e2012-08-06 15:03:03 +02001607 tbf->state_flags = 0;
Andreas Eversberg592e04a2012-07-15 06:25:37 +02001608 tbf_update(tbf);
Andreas Eversberg7f5352c2012-07-23 18:20:36 +02001609 gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001610
1611 return 0;
1612}
1613
1614
1615struct msgb *gprs_rlcmac_send_packet_downlink_assignment(
1616 struct gprs_rlcmac_tbf *tbf, uint32_t fn)
1617{
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001618 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001619 struct msgb *msg;
1620 struct gprs_rlcmac_tbf *new_tbf;
Andreas Eversberg802bb6e2012-08-06 11:15:05 +02001621 int poll_ass_dl = POLLING_ASSIGNMENT_DL;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001622
Andreas Eversberg802bb6e2012-08-06 11:15:05 +02001623 if (poll_ass_dl && tbf->direction == GPRS_RLCMAC_DL_TBF
1624 && tbf->control_ts != tbf->first_common_ts) {
1625 LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink "
1626 "assigment, because MS cannot reply.\n");
1627 poll_ass_dl = 0;
Andreas Eversberge6228b32012-07-03 13:36:03 +02001628 }
Andreas Eversberg802bb6e2012-08-06 11:15:05 +02001629 if (poll_ass_dl) {
1630 if (tbf->poll_state != GPRS_RLCMAC_POLL_NONE) {
1631 LOGP(DRLCMAC, LOGL_DEBUG, "Polling is already sheduled "
1632 "for TBF=%d, so we must wait for downlink "
1633 "assignment...\n", tbf->tfi);
1634 return NULL;
1635 }
Andreas Eversberg07e97cf2012-08-07 16:00:56 +02001636 if (sba_find(tbf->trx, tbf->control_ts, (fn + 13) % 2715648)) {
1637 LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already "
1638 "scheduled for single block allocation...\n");
1639 return NULL;
1640 }
Andreas Eversberg802bb6e2012-08-06 11:15:05 +02001641 }
Andreas Eversberge6228b32012-07-03 13:36:03 +02001642
1643 /* on uplink TBF we get the downlink TBF to be assigned. */
Andreas Eversbergee31b782012-07-15 16:27:01 +02001644 if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
1645 /* be sure to check first, if contention resolution is done,
1646 * otherwise we cannot send the assignment yet */
Andreas Eversberg08e93cd2012-07-26 08:13:06 +02001647 if (!tbf->dir.ul.contention_resolution_done) {
Andreas Eversberg7f5352c2012-07-23 18:20:36 +02001648 LOGP(DRLCMAC, LOGL_DEBUG, "Cannot assign DL TBF now, "
Andreas Eversbergee31b782012-07-15 16:27:01 +02001649 "because contention resolution is not "
1650 "finished.\n");
1651 return NULL;
1652 }
Andreas Eversberge6228b32012-07-03 13:36:03 +02001653 new_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF);
Andreas Eversbergee31b782012-07-15 16:27:01 +02001654 } else
Andreas Eversberge6228b32012-07-03 13:36:03 +02001655 new_tbf = tbf;
1656 if (!new_tbf) {
1657 LOGP(DRLCMACDL, LOGL_ERROR, "We have a schedule for downlink "
1658 "assignment at uplink TBF=%d, but there is no downlink "
1659 "TBF\n", tbf->tfi);
1660 tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
1661 return NULL;
1662 }
1663
1664 msg = msgb_alloc(23, "rlcmac_dl_ass");
1665 if (!msg)
1666 return NULL;
1667 bitvec *ass_vec = bitvec_alloc(23);
1668 if (!ass_vec) {
1669 msgb_free(msg);
1670 return NULL;
1671 }
1672 bitvec_unhex(ass_vec,
1673 "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
Andreas Eversberg0e403092012-07-06 11:04:57 +02001674 LOGP(DRLCMAC, LOGL_INFO, "TBF: START TFI: %u TLLI: 0x%08x Packet Downlink Assignment (PACCH)\n", new_tbf->tfi, new_tbf->tlli);
Andreas Eversberg6681bb82012-07-25 08:48:44 +02001675 RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
Ivan Kluchnikovef7f28c2012-07-12 14:49:15 +04001676 write_packet_downlink_assignment(mac_control_block, tbf->tfi,
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +02001677 (tbf->direction == GPRS_RLCMAC_DL_TBF), new_tbf,
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001678 poll_ass_dl, bts->alpha, bts->gamma);
Andreas Eversberg0e403092012-07-06 11:04:57 +02001679 LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n");
Ivan Kluchnikovef7f28c2012-07-12 14:49:15 +04001680 encode_gsm_rlcmac_downlink(ass_vec, mac_control_block);
Andreas Eversberg0e403092012-07-06 11:04:57 +02001681 LOGPC(DCSN1, LOGL_NOTICE, "\n");
1682 LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Downlink Assignment -------------------------\n");
Ivan Kluchnikovef7f28c2012-07-12 14:49:15 +04001683 bitvec_pack(ass_vec, msgb_put(msg, 23));
Andreas Eversberge6228b32012-07-03 13:36:03 +02001684 bitvec_free(ass_vec);
Andreas Eversberg6681bb82012-07-25 08:48:44 +02001685 talloc_free(mac_control_block);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001686
Andreas Eversberg802bb6e2012-08-06 11:15:05 +02001687 if (poll_ass_dl) {
1688 tbf->poll_state = GPRS_RLCMAC_POLL_SCHED;
1689 tbf->poll_fn = (fn + 13) % 2715648;
1690 tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK;
1691 } else {
1692 tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE;
1693 tbf_new_state(new_tbf, GPRS_RLCMAC_FLOW);
1694 tbf_assign_control_ts(new_tbf);
Andreas Eversbergcbcd1242012-08-07 15:48:21 +02001695 /* stop pending assignment timer */
1696 tbf_timer_stop(new_tbf);
1697
Andreas Eversberg802bb6e2012-08-06 11:15:05 +02001698 }
Andreas Eversberge6228b32012-07-03 13:36:03 +02001699
1700 return msg;
1701}
1702
Andreas Eversberge13fa2d2012-07-09 17:10:44 +02001703static void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf, uint8_t poll,
1704 char *imsi)
Andreas Eversberge6228b32012-07-03 13:36:03 +02001705{
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001706 struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts;
1707 int plen;
1708
Andreas Eversberge13fa2d2012-07-09 17:10:44 +02001709 LOGP(DRLCMAC, LOGL_INFO, "TX: START TFI: %u TLLI: 0x%08x Immediate Assignment Downlink (PCH)\n", tbf->tfi, tbf->tlli);
Andreas Eversberg7b045012012-07-05 07:38:49 +02001710 bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */
1711 bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
Andreas Eversberge6228b32012-07-03 13:36:03 +02001712 /* use request reference that has maximum distance to current time,
1713 * so the assignment will not conflict with possible RACH requests. */
Andreas Eversbergaafcbbb2012-09-27 09:20:45 +02001714 plen = write_immediate_assignment(immediate_assignment, 1, 125,
1715 (tbf->pdch[tbf->first_ts]->last_rts_fn + 21216) % 2715648, tbf->ta,
1716 tbf->arfcn, tbf->first_ts, tbf->tsc, tbf->tfi, 0, tbf->tlli, poll,
1717 tbf->poll_fn, 0, bts->alpha, bts->gamma);
Andreas Eversberge13fa2d2012-07-09 17:10:44 +02001718 pcu_l1if_tx_pch(immediate_assignment, plen, imsi);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001719 bitvec_free(immediate_assignment);
1720}
1721
1722/* depending on the current TBF, we assign on PACCH or AGCH */
Andreas Eversberg7f5352c2012-07-23 18:20:36 +02001723void gprs_rlcmac_trigger_downlink_assignment(struct gprs_rlcmac_tbf *tbf,
1724 struct gprs_rlcmac_tbf *old_tbf, char *imsi)
Andreas Eversberge6228b32012-07-03 13:36:03 +02001725{
Andreas Eversberge6228b32012-07-03 13:36:03 +02001726#ifdef DEBUG_DL_ASS_IDLE
Andreas Eversberge13fa2d2012-07-09 17:10:44 +02001727 strncpy(debug_imsi, imsi);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001728 LOGP(DRLCMAC, LOGL_ERROR, "**** DEBUGGING DOWNLINK ASSIGNMENT ****\n");
1729#endif
1730
1731 /* stop pending timer */
1732 tbf_timer_stop(tbf);
1733
1734 /* check for downlink tbf: */
Andreas Eversberg7f5352c2012-07-23 18:20:36 +02001735 if (old_tbf) {
Andreas Eversberge6228b32012-07-03 13:36:03 +02001736#ifdef DEBUG_DL_ASS_IDLE
1737 LOGP(DRLCMAC, LOGL_ERROR, "We must wait for current TBF to be "
1738 "released.\n");
1739 /* wait one second until assignment */
1740 tbf_timer_start(tbf, 1234, 1,0);
1741#else
Andreas Eversberg0e403092012-07-06 11:04:57 +02001742 LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment on "
Andreas Eversbergb0c7ea72012-07-13 14:46:03 +02001743 "PACCH, because %s TBF=%d exists for TLLI=0x%08x\n",
Andreas Eversberg7f5352c2012-07-23 18:20:36 +02001744 (old_tbf->direction == GPRS_RLCMAC_UL_TBF)
1745 ? "UL" : "DL", old_tbf->tfi, old_tbf->tlli);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001746 old_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
1747 /* use TA from old TBF */
1748 tbf->ta = old_tbf->ta;
1749 /* change state */
1750 tbf_new_state(tbf, GPRS_RLCMAC_ASSIGN);
Andreas Eversberg14db19e2012-08-06 15:03:03 +02001751 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH);
Andreas Eversbergcbcd1242012-08-07 15:48:21 +02001752 /* start timer */
1753 tbf_timer_start(tbf, 0, Tassign_pacch);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001754#endif
1755 } else {
Andreas Eversberge13fa2d2012-07-09 17:10:44 +02001756 LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment for TBF=%d on PCH, no TBF exist (IMSI=%s)\n", tbf->tfi, imsi);
1757 if (!imsi || strlen(imsi) < 3) {
1758 LOGP(DRLCMAC, LOGL_ERROR, "No valid IMSI!\n");
1759 return;
1760 }
Andreas Eversberge6228b32012-07-03 13:36:03 +02001761 /* change state */
1762 tbf_new_state(tbf, GPRS_RLCMAC_ASSIGN);
Andreas Eversberg14db19e2012-08-06 15:03:03 +02001763 tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH);
Andreas Eversberg7438df72012-07-23 18:04:49 +02001764 /* send immediate assignment */
1765 gprs_rlcmac_downlink_assignment(tbf, 0, imsi);
1766 /* send immediate assignment */
1767 gprs_rlcmac_downlink_assignment(tbf, 0, imsi);
Andreas Eversberge6228b32012-07-03 13:36:03 +02001768 /* start timer */
1769 tbf_timer_start(tbf, 0, Tassign_agch);
1770 }
1771 }
1772