blob: 7865be00a803976097143665ced6eda05169e7e3 [file] [log] [blame]
Holger Hans Peter Freytherd11290b2013-10-26 17:32:04 +02001/* decoding
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#include <decoding.h>
21#include <rlc.h>
22#include <gprs_debug.h>
23
Jacob Erlbeck4abc6862015-12-08 15:14:05 +010024extern "C" {
25#include <osmocom/core/utils.h>
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +010026#include <osmocom/core/bitcomp.h>
Jacob Erlbeck4abc6862015-12-08 15:14:05 +010027}
28
Holger Hans Peter Freytherd11290b2013-10-26 17:32:04 +020029#include <arpa/inet.h>
30
31#include <errno.h>
32#include <string.h>
33
Jacob Erlbeck4abc6862015-12-08 15:14:05 +010034#define LENGTH_TO_END 255
Alexander Couzensb82bd922016-05-30 17:30:10 +020035/*!
Jacob Erlbeck4abc6862015-12-08 15:14:05 +010036 * \returns num extensions fields (num frames == offset) on success,
37 * -errno otherwise.
38 */
39static int parse_extensions_egprs(const uint8_t *data, unsigned int data_len,
40 unsigned int *offs,
41 bool is_last_block,
42 Decoding::RlcData *chunks, unsigned int chunks_size)
43{
44 const struct rlc_li_field_egprs *li;
45 uint8_t e;
46 unsigned int num_chunks = 0;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +010047
48 e = 0;
49 while (!e) {
50 if (*offs > data_len) {
51 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI extended, "
52 "but no more data\n");
53 return -EINVAL;
54 }
55
56 /* get new E */
57 li = (struct rlc_li_field_egprs *)&data[*offs];
58 e = li->e;
59 *offs += 1;
60
61 if (!chunks)
62 continue;
63
64 if (num_chunks == chunks_size) {
65 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI extended, "
66 "but no more chunks possible\n");
67 return -ENOSPC;
68 }
69 if (li->li == 0 && num_chunks == 0 && li->e == 0) {
70 /* TS 44.060, table 10.4.14a.1, row 2a */
71 chunks[num_chunks].length = 0;
72 chunks[num_chunks].is_complete = true;
73 } else if (li->li == 0 && num_chunks == 0 && li->e == 1) {
74 /* TS 44.060, table 10.4.14a.1, row 4 */
Jacob Erlbeck4abc6862015-12-08 15:14:05 +010075 chunks[num_chunks].length = LENGTH_TO_END;
76 chunks[num_chunks].is_complete = is_last_block;
77 } else if (li->li == 127 && li->e == 1) {
78 /* TS 44.060, table 10.4.14a.1, row 3 & 5 */
79 /* only filling bytes left */
80 break;
81 } else if (li->li > 0) {
82 /* TS 44.060, table 10.4.14a.1, row 1 & 2b */
83 chunks[num_chunks].length = li->li;
84 chunks[num_chunks].is_complete = true;
85 } else {
86 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI contains "
87 "invalid extension octet: LI=%d, E=%d, count=%d\n",
88 li->li, li->e, num_chunks);
89 return -EINVAL;
90 }
91
92 num_chunks += 1;
93
94 if (e == 1) {
95 /* There is space after the last chunk, add a final one */
96 if (num_chunks == chunks_size) {
97 LOGP(DRLCMACUL, LOGL_NOTICE,
98 "UL DATA LI possibly extended, "
99 "but no more chunks possible\n");
100 return -ENOSPC;
101 }
102
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100103 chunks[num_chunks].length = LENGTH_TO_END;
104 chunks[num_chunks].is_complete = is_last_block;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100105 num_chunks += 1;
106 }
107 }
108
109 return num_chunks;
110}
111
112static int parse_extensions_gprs(const uint8_t *data, unsigned int data_len,
113 unsigned int *offs,
114 bool is_last_block,
115 Decoding::RlcData *chunks, unsigned int chunks_size)
116{
117 const struct rlc_li_field *li;
118 uint8_t m, e;
119 unsigned int num_chunks = 0;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100120
121 e = 0;
122 while (!e) {
123 if (*offs > data_len) {
124 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI extended, "
125 "but no more data\n");
126 return -EINVAL;
127 }
128
129 /* get new E */
130 li = (const struct rlc_li_field *)&data[*offs];
131 e = li->e;
132 m = li->m;
133 *offs += 1;
134
135 if (li->li == 0) {
136 /* TS 44.060, 10.4.14, par 6 */
137 e = 1;
138 m = 0;
139 }
140
141 /* TS 44.060, table 10.4.13.1 */
142 if (m == 0 && e == 0) {
143 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA "
144 "ignored, because M='0' and E='0'.\n");
145 return 0;
146 }
147
148 if (!chunks)
149 continue;
150
151 if (num_chunks == chunks_size) {
152 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI extended, "
153 "but no more chunks possible\n");
154 return -ENOSPC;
155 }
156
157 if (li->li == 0)
158 /* e is 1 here */
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100159 chunks[num_chunks].length = LENGTH_TO_END;
160 else
161 chunks[num_chunks].length = li->li;
162
163 chunks[num_chunks].is_complete = li->li || is_last_block;
164
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100165 num_chunks += 1;
166
167 if (e == 1 && m == 1) {
168 if (num_chunks == chunks_size) {
169 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA LI extended, "
170 "but no more chunks possible\n");
171 return -ENOSPC;
172 }
173 /* TS 44.060, 10.4.13.1, row 4 */
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100174 chunks[num_chunks].length = LENGTH_TO_END;
175 chunks[num_chunks].is_complete = is_last_block;
176 num_chunks += 1;
177 }
178 }
179
180 return num_chunks;
181}
182
183int Decoding::rlc_data_from_ul_data(
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100184 const struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs,
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100185 const uint8_t *data, RlcData *chunks, unsigned int chunks_size,
186 uint32_t *tlli)
187{
188 uint8_t e;
189 unsigned int data_len = rdbi->data_len;
Jacob Erlbeckead5e472016-01-08 10:14:50 +0100190 int num_chunks = 0, i;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100191 unsigned int offs = 0;
192 bool is_last_block = (rdbi->cv == 0);
193
194 if (!chunks)
195 chunks_size = 0;
196
197 e = rdbi->e;
198 if (e) {
199 if (chunks_size > 0) {
Alexander Couzensb82bd922016-05-30 17:30:10 +0200200 /* Block without LI means it only contains data of one LLC PDU */
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100201 chunks[num_chunks].offset = offs;
202 chunks[num_chunks].length = LENGTH_TO_END;
203 chunks[num_chunks].is_complete = is_last_block;
204 num_chunks += 1;
205 } else if (chunks) {
206 LOGP(DRLCMACUL, LOGL_NOTICE, "No extension, "
207 "but no more chunks possible\n");
208 return -ENOSPC;
209 }
210 } else if (cs.isEgprs()) {
211 /* if E is not set (LI follows), EGPRS */
212 num_chunks = parse_extensions_egprs(data, data_len, &offs,
213 is_last_block,
214 chunks, chunks_size);
215 } else {
216 /* if E is not set (LI follows), GPRS */
217 num_chunks = parse_extensions_gprs(data, data_len, &offs,
218 is_last_block,
219 chunks, chunks_size);
220 }
221
Jacob Erlbeckead5e472016-01-08 10:14:50 +0100222 if (num_chunks < 0)
223 return num_chunks;
224
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100225 /* TLLI */
226 if (rdbi->ti) {
227 uint32_t tlli_enc;
228 if (offs + 4 > data_len) {
229 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TLLI out of block "
230 "border\n");
231 return -EINVAL;
232 }
233
234 memcpy(&tlli_enc, data + offs, sizeof(tlli_enc));
235 if (cs.isGprs())
236 /* The TLLI is encoded in big endian for GPRS (see
237 * TS 44.060, figure 10.2.2.1, note) */
238 *tlli = be32toh(tlli_enc);
239 else
240 /* The TLLI is encoded in little endian for EGPRS (see
241 * TS 44.060, figure 10.3a.2.1, note 2) */
242 *tlli = le32toh(tlli_enc);
243
244 offs += sizeof(tlli_enc);
245 } else {
246 *tlli = 0;
247 }
248
249 /* PFI */
250 if (rdbi->pi) {
251 LOGP(DRLCMACUL, LOGL_ERROR, "ERROR: PFI not supported, "
252 "please disable in SYSTEM INFORMATION\n");
253 return -ENOTSUP;
254
255 /* TODO: Skip all extensions with E=0 (see TS 44.060, 10.4.11 */
256 }
257
Jacob Erlbeckead5e472016-01-08 10:14:50 +0100258 if (chunks_size == 0)
259 return num_chunks;
260
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100261 /* LLC */
262 for (i = 0; i < num_chunks; i++) {
263 chunks[i].offset = offs;
264 if (chunks[i].length == LENGTH_TO_END) {
265 if (offs == data_len) {
266 /* There is no place for an additional chunk,
267 * so drop it (this may happen with EGPRS since
268 * there is no M flag. */
269 num_chunks -= 1;
Alexander Couzensd302e4f2016-05-30 17:31:09 +0200270 break;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100271 }
272 chunks[i].length = data_len - offs;
273 }
274 offs += chunks[i].length;
275 if (offs > data_len) {
276 LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA out of block "
277 "border, chunk idx: %d, size: %d\n",
278 i, chunks[i].length);
279 return -EINVAL;
280 }
281 }
282
283 return num_chunks;
284}
Holger Hans Peter Freytherd11290b2013-10-26 17:32:04 +0200285
Holger Hans Peter Freytherfcbc7022013-10-26 17:38:37 +0200286uint8_t Decoding::get_ms_class_by_capability(MS_Radio_Access_capability_t *cap)
287{
288 int i;
289
290 for (i = 0; i < cap->Count_MS_RA_capability_value; i++) {
291 if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability)
292 continue;
293 if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_GPRS_multislot_class)
294 continue;
295 return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.GPRS_multislot_class;
296 }
297
298 return 0;
299}
300
Jacob Erlbeckc3c58042015-09-28 17:55:32 +0200301uint8_t Decoding::get_egprs_ms_class_by_capability(MS_Radio_Access_capability_t *cap)
302{
303 int i;
304
305 for (i = 0; i < cap->Count_MS_RA_capability_value; i++) {
306 if (!cap->MS_RA_capability_value[i].u.Content.Exist_Multislot_capability)
307 continue;
308 if (!cap->MS_RA_capability_value[i].u.Content.Multislot_capability.Exist_EGPRS_multislot_class)
309 continue;
310 return cap->MS_RA_capability_value[i].u.Content.Multislot_capability.EGPRS_multislot_class;
311 }
312
313 return 0;
314}
315
Holger Hans Peter Freytherdf6b4f52013-11-24 17:05:48 +0100316/**
317 * show_rbb needs to be an array with 65 elements
Daniel Willmann5e94cd42013-12-11 20:11:16 +0100318 * The index of the array is the bit position in the rbb
319 * (show_rbb[63] relates to BSN ssn-1)
Holger Hans Peter Freytherdf6b4f52013-11-24 17:05:48 +0100320 */
321void Decoding::extract_rbb(const uint8_t *rbb, char *show_rbb)
322{
Daniel Willmann5e94cd42013-12-11 20:11:16 +0100323 for (int i = 0; i < 64; i++) {
Holger Hans Peter Freytherdf6b4f52013-11-24 17:05:48 +0100324 uint8_t bit;
325
Daniel Willmann5e94cd42013-12-11 20:11:16 +0100326 bit = !!(rbb[i/8] & (1<<(7-i%8)));
Daniel Willmann6f7cb2c2013-12-11 14:25:20 +0100327 show_rbb[i] = bit ? 'R' : 'I';
Holger Hans Peter Freytherdf6b4f52013-11-24 17:05:48 +0100328 }
329
330 show_rbb[64] = '\0';
331}
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100332
Jacob Erlbeckf2f24b02016-02-05 13:16:24 +0100333void Decoding::extract_rbb(const struct bitvec *rbb, char *show_rbb)
334{
335 unsigned int i;
336 for (i = 0; i < rbb->cur_bit; i++) {
337 uint8_t bit;
338 bit = bitvec_get_bit_pos(rbb, i);
339 show_rbb[i] = bit == 1 ? 'R' : 'I';
340 }
341
342 show_rbb[i] = '\0';
343}
344
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100345int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100346 const uint8_t *data, GprsCodingScheme cs)
347{
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100348 unsigned int cur_bit = 0;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100349 switch(cs.headerTypeData()) {
Bhargava Abhyankare44383b2016-03-22 18:42:30 +0530350 case GprsCodingScheme::HEADER_GPRS_DATA :
351 cur_bit = rlc_parse_ul_data_header_gprs(rlc, data, cs);
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100352 break;
Bhargava Abhyankare44383b2016-03-22 18:42:30 +0530353 case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_3 :
354 cur_bit = rlc_parse_ul_data_header_egprs_type_3(rlc, data, cs);
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100355 break;
Aravind Sirsikar550a5412016-06-14 18:59:18 +0530356 case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_2 :
357 cur_bit = rlc_parse_ul_data_header_egprs_type_2(rlc, data, cs);
358 break;
359 case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1 :
Aravind Sirsikar99ab0a82016-06-15 17:46:41 +0530360 cur_bit = rlc_parse_ul_data_header_egprs_type_1(rlc, data, cs);
361 break;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100362 default:
363 LOGP(DRLCMACDL, LOGL_ERROR,
364 "Decoding of uplink %s data blocks not yet supported.\n",
365 cs.name());
366 return -ENOTSUP;
367 };
368
369 return cur_bit;
370}
371
Bhargava Abhyankare44383b2016-03-22 18:42:30 +0530372int Decoding::rlc_parse_ul_data_header_egprs_type_3(
373 struct gprs_rlc_data_info *rlc,
374 const uint8_t *data,
375 const GprsCodingScheme &cs)
376{
377 int punct, punct2, with_padding, cps;
378 unsigned int e_ti_header, offs, cur_bit = 0;
379 const struct gprs_rlc_ul_header_egprs_3 *egprs3;
380
381 egprs3 = static_cast < struct gprs_rlc_ul_header_egprs_3 * >
382 ((void *)data);
383
384 cps = (egprs3->cps_a << 0) | (egprs3->cps_b << 2);
385 gprs_rlc_mcs_cps_decode(cps, cs, &punct, &punct2, &with_padding);
386 gprs_rlc_data_info_init_ul(rlc, cs, with_padding);
387
388 rlc->r = egprs3->r;
389 rlc->si = egprs3->si;
390 rlc->tfi = (egprs3->tfi_a << 0) | (egprs3->tfi_b << 2);
391 rlc->cps = cps;
392 rlc->rsb = egprs3->rsb;
393
394 rlc->num_data_blocks = 1;
395 rlc->block_info[0].cv = egprs3->cv;
396 rlc->block_info[0].pi = egprs3->pi;
397 rlc->block_info[0].spb = egprs3->spb;
398 rlc->block_info[0].bsn =
399 (egprs3->bsn1_a << 0) | (egprs3->bsn1_b << 5);
400
401 cur_bit += rlc->data_offs_bits[0] - 2;
402 offs = rlc->data_offs_bits[0] / 8;
403 OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 1);
404 e_ti_header = (data[offs-1] + (data[offs] << 8)) >> 7;
405 rlc->block_info[0].e = !!(e_ti_header & 0x01);
406 rlc->block_info[0].ti = !!(e_ti_header & 0x02);
407 cur_bit += 2;
408 /* skip data area */
409 cur_bit += cs.maxDataBlockBytes() * 8;
410
411 return cur_bit;
412}
413
Aravind Sirsikar550a5412016-06-14 18:59:18 +0530414int Decoding::rlc_parse_ul_data_header_egprs_type_2(
415 struct gprs_rlc_data_info *rlc,
416 const uint8_t *data,
417 const GprsCodingScheme &cs)
418{
419 const struct gprs_rlc_ul_header_egprs_2 *egprs2;
420 unsigned int e_ti_header, offs, cur_bit = 0;
421 int punct, punct2, with_padding, cps;
422
423 egprs2 = static_cast < struct gprs_rlc_ul_header_egprs_2 * >
424 ((void *)data);
425
426 cps = (egprs2->cps_a << 0) | (egprs2->cps_b << 2);
427 gprs_rlc_mcs_cps_decode(cps, cs, &punct, &punct2, &with_padding);
428 gprs_rlc_data_info_init_ul(rlc, cs, with_padding);
429
430 rlc->r = egprs2->r;
431 rlc->si = egprs2->si;
432 rlc->tfi = (egprs2->tfi_a << 0) | (egprs2->tfi_b << 2);
433 rlc->cps = cps;
434 rlc->rsb = egprs2->rsb;
435
436 rlc->num_data_blocks = 1;
437 rlc->block_info[0].cv = egprs2->cv;
438 rlc->block_info[0].pi = egprs2->pi;
439 rlc->block_info[0].bsn =
440 (egprs2->bsn1_a << 0) | (egprs2->bsn1_b << 5);
441
442 cur_bit += rlc->data_offs_bits[0] - 2;
443
444 offs = rlc->data_offs_bits[0] / 8;
445 OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 7);
446
447 e_ti_header = (data[offs] & 0x60) >> 5;
448 rlc->block_info[0].e = !!(e_ti_header & 0x01);
449 rlc->block_info[0].ti = !!(e_ti_header & 0x02);
450 cur_bit += 2;
451
452 /* skip data area */
453 cur_bit += cs.maxDataBlockBytes() * 8;
454
455 return cur_bit;
456}
457
Aravind Sirsikar99ab0a82016-06-15 17:46:41 +0530458int Decoding::rlc_parse_ul_data_header_egprs_type_1(
459 struct gprs_rlc_data_info *rlc,
460 const uint8_t *data, const GprsCodingScheme &cs)
461{
462 struct gprs_rlc_ul_header_egprs_1 *egprs1;
463 unsigned int e_ti_header, cur_bit = 0, offs;
464 int punct, punct2, with_padding;
465
466 egprs1 = static_cast < struct gprs_rlc_ul_header_egprs_1 * >
467 ((void *)data);
468 gprs_rlc_mcs_cps_decode(egprs1->cps, cs, &punct, &punct2,
469 &with_padding);
470 gprs_rlc_data_info_init_ul(rlc, cs, with_padding);
471
472 rlc->r = egprs1->r;
473 rlc->si = egprs1->si;
474 rlc->tfi = (egprs1->tfi_a << 0) | (egprs1->tfi_b << 2);
475 rlc->cps = egprs1->cps;
476 rlc->rsb = egprs1->rsb;
477 rlc->num_data_blocks = 2;
478 rlc->block_info[0].cv = egprs1->cv;
479 rlc->block_info[0].pi = egprs1->pi;
480 rlc->block_info[0].bsn =
481 (egprs1->bsn1_a << 0) | (egprs1->bsn1_b << 5);
482
483 cur_bit += rlc->data_offs_bits[0] - 2;
484 offs = rlc->data_offs_bits[0] / 8;
485 OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 0);
486
487 e_ti_header = data[offs - 1] >> 6;
488 rlc->block_info[0].e = (e_ti_header & 0x01);
489 rlc->block_info[0].ti = !!(e_ti_header & 0x02);
490 cur_bit += 2;
491
492 rlc->block_info[1].cv = egprs1->cv;
493 rlc->block_info[1].pi = egprs1->pi;
494 rlc->block_info[1].bsn = rlc->block_info[0].bsn +
495 ((egprs1->bsn2_a << 0) | (egprs1->bsn2_b << 2));
496 rlc->block_info[1].bsn = rlc->block_info[1].bsn & (RLC_EGPRS_SNS - 1);
497
498 if ((rlc->block_info[1].bsn != rlc->block_info[0].bsn) &&
499 (rlc->block_info[0].cv == 0))
500 rlc->block_info[0].cv = 1;
501
502 cur_bit = rlc->data_offs_bits[1] - 2;
503
504 offs = rlc->data_offs_bits[1] / 8;
505 OSMO_ASSERT(rlc->data_offs_bits[1] % 8 == 2);
506
507 e_ti_header = (data[offs] & (0x03));
508 rlc->block_info[1].e = (e_ti_header & 0x01);
509 rlc->block_info[1].ti = !!(e_ti_header & 0x02);
510 cur_bit += 2;
511 /* skip data area */
512 cur_bit += cs.maxDataBlockBytes() * 8;
513
514 return cur_bit;
515}
516
Bhargava Abhyankare44383b2016-03-22 18:42:30 +0530517int Decoding::rlc_parse_ul_data_header_gprs(struct gprs_rlc_data_info *rlc,
518 const uint8_t *data, const GprsCodingScheme &cs)
519{
520 const struct rlc_ul_header *gprs;
521 unsigned int cur_bit = 0;
522
523 gprs = static_cast < struct rlc_ul_header * >
524 ((void *)data);
525
526 gprs_rlc_data_info_init_ul(rlc, cs, false);
527
528 rlc->r = gprs->r;
529 rlc->si = gprs->si;
530 rlc->tfi = gprs->tfi;
531 rlc->cps = 0;
532 rlc->rsb = 0;
533 rlc->num_data_blocks = 1;
534 rlc->block_info[0].cv = gprs->cv;
535 rlc->block_info[0].pi = gprs->pi;
536 rlc->block_info[0].bsn = gprs->bsn;
537 rlc->block_info[0].e = gprs->e;
538 rlc->block_info[0].ti = gprs->ti;
539 rlc->block_info[0].spb = 0;
540 cur_bit += rlc->data_offs_bits[0];
541 /* skip data area */
542 cur_bit += cs.maxDataBlockBytes() * 8;
543
544 return cur_bit;
545}
546
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100547/**
548 * \brief Copy LSB bitstream RLC data block to byte aligned buffer.
549 *
550 * Note that the bitstream is encoded in LSB first order, so the two octets
551 * 654321xx xxxxxx87 contain the octet 87654321 starting at bit position 3
552 * (LSB has bit position 1). This is a different order than the one used by
553 * CSN.1.
554 *
555 * \param data_block_idx The block index, 0..1 for header type 1, 0 otherwise
556 * \param src A pointer to the start of the RLC block (incl. the header)
557 * \param buffer A data area of a least the size of the RLC block
558 * \returns the number of bytes copied
559 */
560unsigned int Decoding::rlc_copy_to_aligned_buffer(
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100561 const struct gprs_rlc_data_info *rlc,
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100562 unsigned int data_block_idx,
563 const uint8_t *src, uint8_t *buffer)
564{
565 unsigned int hdr_bytes;
566 unsigned int extra_bits;
567 unsigned int i;
568
569 uint8_t c, last_c;
570 uint8_t *dst;
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100571 const struct gprs_rlc_data_block_info *rdbi;
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100572
573 OSMO_ASSERT(data_block_idx < rlc->num_data_blocks);
574 rdbi = &rlc->block_info[data_block_idx];
575
576 hdr_bytes = rlc->data_offs_bits[data_block_idx] >> 3;
577 extra_bits = (rlc->data_offs_bits[data_block_idx] & 7);
578
579 if (extra_bits == 0) {
580 /* It is aligned already */
581 memmove(buffer, src + hdr_bytes, rdbi->data_len);
582 return rdbi->data_len;
583 }
584
585 dst = buffer;
586 src = src + hdr_bytes;
587 last_c = *(src++);
588
589 for (i = 0; i < rdbi->data_len; i++) {
590 c = src[i];
591 *(dst++) = (last_c >> extra_bits) | (c << (8 - extra_bits));
592 last_c = c;
593 }
594
595 return rdbi->data_len;
596}
597
598/**
599 * \brief Get a pointer to byte aligned RLC data.
600 *
601 * Since the RLC data may not be byte aligned to the RLC block data such that a
602 * single RLC data byte is spread over two RLC block bytes, this function
603 * eventually uses the provided buffer as data storage.
604 *
605 * \param src A pointer to the start of the RLC block (incl. the header)
606 * \param buffer A data area of a least the size of the RLC block
607 * \returns A pointer to the RLC data start within src if it is aligned, and
608 * buffer otherwise.
609 */
610const uint8_t *Decoding::rlc_get_data_aligned(
Jacob Erlbeckf2ba4cb2016-01-07 18:59:28 +0100611 const struct gprs_rlc_data_info *rlc,
Jacob Erlbeck4abc6862015-12-08 15:14:05 +0100612 unsigned int data_block_idx,
613 const uint8_t *src, uint8_t *buffer)
614{
615 unsigned int hdr_bytes;
616 unsigned int extra_bits;
617
618 OSMO_ASSERT(data_block_idx < ARRAY_SIZE(rlc->data_offs_bits));
619
620 hdr_bytes = rlc->data_offs_bits[data_block_idx] >> 3;
621 extra_bits = (rlc->data_offs_bits[data_block_idx] & 7);
622
623 if (extra_bits == 0)
624 /* It is aligned already, return a pointer that refers to the
625 * original data. */
626 return src + hdr_bytes;
627
628 Decoding::rlc_copy_to_aligned_buffer(rlc, data_block_idx, src, buffer);
629 return buffer;
630}
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100631
632static int handle_final_ack(bitvec *bits, int *bsn_begin, int *bsn_end,
633 gprs_rlc_dl_window *window)
634{
635 int num_blocks, i;
636
637 num_blocks = window->mod_sns(window->v_s() - window->v_a());
638 for (i = 0; i < num_blocks; i++)
639 bitvec_set_bit(bits, ONE);
640
641 *bsn_begin = window->v_a();
642 *bsn_end = window->mod_sns(*bsn_begin + num_blocks);
643 return num_blocks;
644}
645
646int Decoding::decode_egprs_acknack_bits(const EGPRS_AckNack_Desc_t *desc,
647 bitvec *bits, int *bsn_begin, int *bsn_end, gprs_rlc_dl_window *window)
648{
649 int urbb_len = desc->URBB_LENGTH;
650 int crbb_len = 0;
651 int num_blocks = 0;
652 struct bitvec urbb;
653 int i;
654 bool have_bitmap;
655 int implicitly_acked_blocks;
656 int ssn = desc->STARTING_SEQUENCE_NUMBER;
Jacob Erlbeck2bef4db2016-01-20 14:33:11 +0100657 int rc;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100658
659 if (desc->FINAL_ACK_INDICATION)
660 return handle_final_ack(bits, bsn_begin, bsn_end, window);
661
662 if (desc->Exist_CRBB)
663 crbb_len = desc->CRBB_LENGTH;
664
665 have_bitmap = (urbb_len + crbb_len) > 0;
666
667 /*
668 * bow & bitmap present:
669 * V(A)-> [ 11111...11111 0 SSN-> BBBBB...BBBBB ] (SSN+Nbits) .... V(S)
670 * bow & not bitmap present:
671 * V(A)-> [ 11111...11111 ] . SSN .... V(S)
672 * not bow & bitmap present:
673 * V(A)-> ... [ 0 SSN-> BBBBB...BBBBB ](SSN+N) .... V(S)
674 * not bow & not bitmap present:
675 * V(A)-> ... [] . SSN .... V(S)
676 */
677
678 if (desc->BEGINNING_OF_WINDOW) {
679 implicitly_acked_blocks = window->mod_sns(ssn - 1 - window->v_a());
680
681 for (i = 0; i < implicitly_acked_blocks; i++)
682 bitvec_set_bit(bits, ONE);
683
684 num_blocks += implicitly_acked_blocks;
685 }
686
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100687 if (!have_bitmap)
688 goto aborted;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100689
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100690 /* next bit refers to V(Q) and thus is always zero (and not
691 * transmitted) */
692 bitvec_set_bit(bits, ZERO);
693 num_blocks += 1;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100694
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100695 if (crbb_len > 0) {
696 int old_len = bits->cur_bit;
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100697 struct bitvec crbb;
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100698
699 crbb.data = (uint8_t *)desc->CRBB;
700 crbb.data_len = sizeof(desc->CRBB);
701 crbb.cur_bit = desc->CRBB_LENGTH;
702
703 rc = osmo_t4_decode(&crbb, desc->CRBB_STARTING_COLOR_CODE,
704 bits);
705
706 if (rc < 0) {
707 LOGP(DRLCMACUL, LOGL_NOTICE,
708 "Failed to decode CRBB: "
709 "length %d, data '%s'\n",
710 desc->CRBB_LENGTH,
711 osmo_hexdump(crbb.data, crbb.data_len));
712 /* We don't know the SSN offset for the URBB,
713 * return what we have so far and assume the
714 * bitmap has stopped here */
715 goto aborted;
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100716 }
717
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100718 LOGP(DRLCMACDL, LOGL_DEBUG,
719 "CRBB len: %d, decoded len: %d, cc: %d, crbb: '%s'\n",
720 desc->CRBB_LENGTH, bits->cur_bit - old_len,
721 desc->CRBB_STARTING_COLOR_CODE,
722 osmo_hexdump(
723 desc->CRBB, (desc->CRBB_LENGTH + 7)/8)
724 );
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100725
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100726 num_blocks += (bits->cur_bit - old_len);
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100727 }
728
Jacob Erlbeck3fdcb2b2016-01-18 16:51:59 +0100729 urbb.cur_bit = 0;
730 urbb.data = (uint8_t *)desc->URBB;
731 urbb.data_len = sizeof(desc->URBB);
732
733 for (i = urbb_len; i > 0; i--) {
734 /*
735 * Set bit at the appropriate position (see 3GPP TS
736 * 44.060 12.3.1)
737 */
738 int is_ack = bitvec_get_bit_pos(&urbb, i-1);
739 bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO);
740 }
741 num_blocks += urbb_len;
742
743aborted:
Jacob Erlbeckae9c5752016-01-13 13:55:44 +0100744 *bsn_begin = window->v_a();
745 *bsn_end = window->mod_sns(*bsn_begin + num_blocks);
746
747 return num_blocks;
748}
Jacob Erlbeck192bf332016-02-05 13:10:29 +0100749
750int Decoding::decode_gprs_acknack_bits(const Ack_Nack_Description_t *desc,
751 bitvec *bits, int *bsn_begin, int *bsn_end, gprs_rlc_dl_window *window)
752{
753 int urbb_len = RLC_GPRS_WS;
754 int num_blocks;
755 struct bitvec urbb;
756
757 if (desc->FINAL_ACK_INDICATION)
758 return handle_final_ack(bits, bsn_begin, bsn_end, window);
759
760 *bsn_begin = window->v_a();
761 *bsn_end = desc->STARTING_SEQUENCE_NUMBER;
762
763 num_blocks = window->mod_sns(*bsn_end - *bsn_begin);
764
765 if (num_blocks < 0 || num_blocks > urbb_len) {
766 *bsn_end = *bsn_begin;
767 LOGP(DRLCMACUL, LOGL_NOTICE,
768 "Invalid GPRS Ack/Nack window %d:%d (length %d)\n",
769 *bsn_begin, *bsn_end, num_blocks);
770 return -EINVAL;
771 }
772
773 urbb.cur_bit = 0;
774 urbb.data = (uint8_t *)desc->RECEIVED_BLOCK_BITMAP;
775 urbb.data_len = sizeof(desc->RECEIVED_BLOCK_BITMAP);
776
777 /*
778 * TS 44.060, 12.3:
779 * BSN = (SSN - bit_number) modulo 128, for bit_number = 1 to 64.
780 * The BSN values represented range from (SSN - 1) mod 128 to (SSN - 64) mod 128.
781 *
782 * We are only interested in the range from V(A) to SSN-1 which is
783 * num_blocks large. The RBB is laid out as
784 * [SSN-1] [SSN-2] ... [V(A)] ... [SSN-64]
785 * so we want to start with [V(A)] and go backwards until we reach
786 * [SSN-1] to get the needed BSNs in an increasing order. Note that
787 * the bit numbers are counted from the end of the buffer.
788 */
789 for (int i = num_blocks; i > 0; i--) {
790 int is_ack = bitvec_get_bit_pos(&urbb, urbb_len - i);
791 bitvec_set_bit(bits, is_ack == 1 ? ONE : ZERO);
792 }
793
794 return num_blocks;
795}