blob: ed6c573d57fe2bdc953df7eac42222a67c4d6f3e [file] [log] [blame]
Harald Weltea43f7892009-12-01 18:04:30 +05301/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface,
2 * rest octet handling according to
3 * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
4
5/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
6 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Weltea43f7892009-12-01 18:04:30 +053012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Weltea43f7892009-12-01 18:04:30 +053018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Weltea43f7892009-12-01 18:04:30 +053021 *
22 */
23
24#include <string.h>
25#include <stdlib.h>
26#include <errno.h>
Max59a1bf32016-04-15 16:04:46 +020027#include <stdbool.h>
Harald Weltea43f7892009-12-01 18:04:30 +053028
Max59a1bf32016-04-15 16:04:46 +020029#include <openbsc/debug.h>
Harald Weltea43f7892009-12-01 18:04:30 +053030#include <openbsc/gsm_data.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010031#include <osmocom/core/bitvec.h>
Maxe01f5052016-04-23 18:00:18 +020032#include <osmocom/gsm/bitvec_gsm.h>
Harald Weltea43f7892009-12-01 18:04:30 +053033#include <openbsc/rest_octets.h>
Max59a1bf32016-04-15 16:04:46 +020034#include <openbsc/arfcn_range_encode.h>
Max26679e02016-04-20 15:57:13 +020035#include <openbsc/system_information.h>
Harald Weltea43f7892009-12-01 18:04:30 +053036
37/* generate SI1 rest octets */
Holger Hans Peter Freytherf876c392013-03-06 12:02:33 +010038int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net)
Harald Weltea43f7892009-12-01 18:04:30 +053039{
40 struct bitvec bv;
41
42 memset(&bv, 0, sizeof(bv));
43 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +010044 bv.data_len = 1;
Harald Weltea43f7892009-12-01 18:04:30 +053045
46 if (nch_pos) {
47 bitvec_set_bit(&bv, H);
48 bitvec_set_uint(&bv, *nch_pos, 5);
49 } else
50 bitvec_set_bit(&bv, L);
51
Holger Hans Peter Freytherf876c392013-03-06 12:02:33 +010052 if (is1800_net)
53 bitvec_set_bit(&bv, L);
54 else
55 bitvec_set_bit(&bv, H);
56
57 bitvec_spare_padding(&bv, 6);
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +010058 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +053059}
60
Max59a1bf32016-04-15 16:04:46 +020061/* Append Repeated E-UTRAN Neighbour Cell to bitvec:
62 * see 3GPP TS 44.018 Table 10.5.2.33b.1
63 */
64static inline void append_eutran_neib_cell(struct bitvec *bv,
65 const struct osmo_earfcn_si2q *e)
66{
67 unsigned i;
68 for (i = 0; i < e->length; i++) {
69 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
70 bitvec_set_bit(bv, 1); /* EARFCN: */
71 bitvec_set_uint(bv, e->arfcn[i], 16);
72
73 if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
74 bitvec_set_bit(bv, 0);
75 else {
76 /* Measurement Bandwidth: 9.1.54 */
77 bitvec_set_bit(bv, 1);
78 bitvec_set_uint(bv, e->meas_bw[i], 3);
79 }
80 }
81 }
82
83 /* stop bit - end of EARFCN + Measurement Bandwidth sequence */
84 bitvec_set_bit(bv, 0);
85
86 if (e->prio_valid) {
87 /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
88 bitvec_set_bit(bv, 1);
89 bitvec_set_uint(bv, e->prio, 3);
90 } else
91 bitvec_set_bit(bv, 0);
92
93 /* THRESH_E-UTRAN_high */
94 bitvec_set_uint(bv, e->thresh_hi, 5);
95
96 if (e->thresh_lo_valid) {
97 /* THRESH_E-UTRAN_low: */
98 bitvec_set_bit(bv, 1);
99 bitvec_set_uint(bv, e->thresh_lo, 5);
100 } else
101 bitvec_set_bit(bv, 0);
102
103 if (e->qrxlm_valid) {
104 /* E-UTRAN_QRXLEVMIN: */
105 bitvec_set_bit(bv, 1);
106 bitvec_set_uint(bv, e->qrxlm, 5);
107 } else
108 bitvec_set_bit(bv, 0);
109}
110
Max59a1bf32016-04-15 16:04:46 +0200111static inline void append_earfcn(struct bitvec *bv,
112 const struct osmo_earfcn_si2q *e)
113{
114 /* Additions in Rel-5: */
115 bitvec_set_bit(bv, H);
116 /* No 3G Additional Measurement Param. Descr. */
117 bitvec_set_bit(bv, 0);
118 /* No 3G ADDITIONAL MEASUREMENT Param. Descr. 2 */
119 bitvec_set_bit(bv, 0);
120 /* Additions in Rel-6: */
121 bitvec_set_bit(bv, H);
122 /* 3G_CCN_ACTIVE */
123 bitvec_set_bit(bv, 0);
124 /* Additions in Rel-7: */
125 bitvec_set_bit(bv, H);
126 /* No 700_REPORTING_OFFSET */
127 bitvec_set_bit(bv, 0);
128 /* No 810_REPORTING_OFFSET */
129 bitvec_set_bit(bv, 0);
130 /* Additions in Rel-8: */
131 bitvec_set_bit(bv, H);
132
133 /* Priority and E-UTRAN Parameters Description */
134 bitvec_set_bit(bv, 1);
135
136 /* No Serving Cell Priority Parameters Descr. */
137 bitvec_set_bit(bv, 0);
138 /* No 3G Priority Parameters Description */
139 bitvec_set_bit(bv, 0);
140 /* E-UTRAN Parameters Description */
141 bitvec_set_bit(bv, 1);
142
143 /* E-UTRAN_CCN_ACTIVE */
144 bitvec_set_bit(bv, 0);
145 /* E-UTRAN_Start: 9.1.54 */
146 bitvec_set_bit(bv, 1);
147 /* E-UTRAN_Stop: 9.1.54 */
148 bitvec_set_bit(bv, 1);
149
150 /* No E-UTRAN Measurement Parameters Descr. */
151 bitvec_set_bit(bv, 0);
152 /* No GPRS E-UTRAN Measurement Param. Descr. */
153 bitvec_set_bit(bv, 0);
154
155 /* Note: each of next 3 "repeated" structures might be repeated any
156 (0, 1, 2...) times - we only support 1 and 0 */
157
158 /* Repeated E-UTRAN Neighbour Cells */
159 bitvec_set_bit(bv, 1);
160
161 /* Note: we don't support different EARFCN arrays each with different
162 priority, threshold etc. */
163 append_eutran_neib_cell(bv, e);
164
165 /* stop bit - end of Repeated E-UTRAN Neighbour Cells sequence: */
166 bitvec_set_bit(bv, 0);
167
168 /* Note: following 2 repeated structs are not supported ATM */
169 /* stop bit - end of Repeated E-UTRAN Not Allowed Cells sequence: */
170 bitvec_set_bit(bv, 0);
171 /* stop bit - end of Repeated E-UTRAN PCID to TA mapping sequence: */
172 bitvec_set_bit(bv, 0);
173
174 /* Priority and E-UTRAN Parameters Description ends here */
175 /* No 3G CSG Description */
176 bitvec_set_bit(bv, 0);
177 /* No E-UTRAN CSG Description */
178 bitvec_set_bit(bv, 0);
179 /* No Additions in Rel-9: */
180 bitvec_set_bit(bv, L);
181}
182
Maxe610e702016-12-19 13:41:48 +0100183/* Append single FDD UARFCN */
184static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc,
185 size_t length)
186{
187 int f0, w[RANGE_ENC_MAX_ARFCNS] = { 0 };
188 uint8_t chan_list[16] = {0};
189 /* Repeated UTRAN FDD Neighbour Cells */
190 bitvec_set_bit(bv, 1);
191
192 /* FDD-ARFCN */
193 bitvec_set_bit(bv, 0);
194 bitvec_set_uint(bv, u, 14);
195
196 f0 = range_encode(ARFCN_RANGE_1024, sc, length, w, 0, chan_list);
197 if (f0 < 0)
198 return f0;
199
200 /* FDD_Indic0: parameter value '0000000000' is a member of the set? */
201 bitvec_set_bit(bv, f0);
202 /* NR_OF_FDD_CELLS */
203 bitvec_set_uint(bv, length, 5);
204
205 f0 = bv->cur_bit;
206 bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
207 bv->cur_bit = f0 + range1024_p(length);
208 return 0;
209}
210
211/* Append multiple FDD UARFCNs */
212static inline int append_uarfcns(struct bitvec *bv, const uint16_t *u,
Max26679e02016-04-20 15:57:13 +0200213 const uint16_t *sc, size_t length)
214{
Maxe610e702016-12-19 13:41:48 +0100215 int i, j, k, rc, st = 0, a[length];
216 uint16_t cu = u[0]; /* caller ensures that length is positive */
Max26679e02016-04-20 15:57:13 +0200217
218 /* 3G Neighbour Cell Description */
219 bitvec_set_bit(bv, 1);
220 /* No Index_Start_3G */
221 bitvec_set_bit(bv, 0);
222 /* No Absolute_Index_Start_EMR */
223 bitvec_set_bit(bv, 0);
224
225 /* UTRAN FDD Description */
226 bitvec_set_bit(bv, 1);
227 /* No Bandwidth_FDD */
228 bitvec_set_bit(bv, 0);
229
Maxe610e702016-12-19 13:41:48 +0100230 for (i = 0; i < length; i++) {
231 for (j = st, k = 0; j < i; j++)
232 a[k++] = sc[j]; /* copy corresponding SCs */
233 if (u[i] != cu) { /* we've reached new UARFCN */
234 rc = append_utran_fdd(bv, cu, a, k);
235 if (rc < 0)
236 return rc;
237 cu = u[i];
238 st = i; /* update start position */
239 }
240 }
Max26679e02016-04-20 15:57:13 +0200241
Maxe610e702016-12-19 13:41:48 +0100242 /* add last UARFCN not covered by previous cycle */
243 for (i = st, k = 0; i < length; i++)
244 a[k++] = sc[i];
245 rc = append_utran_fdd(bv, cu, a, k);
246 if (rc < 0)
247 return rc;
Max26679e02016-04-20 15:57:13 +0200248
249 /* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
250 bitvec_set_bit(bv, 0);
251
252 /* UTRAN TDD Description */
253 bitvec_set_bit(bv, 0);
Max881064e2016-12-14 14:51:40 +0100254
255 return 0;
Max26679e02016-04-20 15:57:13 +0200256}
257
Max59a1bf32016-04-15 16:04:46 +0200258/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
259int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e,
Max26679e02016-04-20 15:57:13 +0200260 const uint16_t *u, const uint16_t *sc, size_t u_len)
Max59a1bf32016-04-15 16:04:46 +0200261{
Max881064e2016-12-14 14:51:40 +0100262 int rc;
Max26679e02016-04-20 15:57:13 +0200263 unsigned sz;
Max59a1bf32016-04-15 16:04:46 +0200264 struct bitvec bv;
265 bv.data = data;
266 bv.data_len = 20;
267 bitvec_zero(&bv);
268
269 /* BA_IND */
270 bitvec_set_bit(&bv, 1);
271 /* 3G_BA_IND */
272 bitvec_set_bit(&bv, 1);
273 /* MP_CHANGE_MARK */
274 bitvec_set_bit(&bv, 0);
275
276 /* we do not support multiple si2quater messages at the moment: */
277 /* SI2quater_INDEX */
278 bitvec_set_uint(&bv, 0, 4);
279 /* SI2quater_COUNT */
280 bitvec_set_uint(&bv, 0, 4);
281
282 /* No Measurement_Parameters Description */
283 bitvec_set_bit(&bv, 0);
284 /* No GPRS_Real Time Difference Description */
285 bitvec_set_bit(&bv, 0);
286 /* No GPRS_BSIC Description */
287 bitvec_set_bit(&bv, 0);
288 /* No GPRS_REPORT PRIORITY Description */
289 bitvec_set_bit(&bv, 0);
290 /* No GPRS_MEASUREMENT_Parameters Description */
291 bitvec_set_bit(&bv, 0);
292 /* No NC Measurement Parameters */
293 bitvec_set_bit(&bv, 0);
294 /* No extension (length) */
295 bitvec_set_bit(&bv, 0);
296
Max26679e02016-04-20 15:57:13 +0200297 if (u_len) {
298 sz = uarfcn_size(u, sc, u_len);
299 /* Even if we do not append EARFCN we still need to set 3 bits */
300 if (sz + bv.cur_bit + 3 > SI2Q_MAX_LEN) {
301 LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
302 "add UARFCNs bits, current %u + required %u + "
303 "reminder %u > max %u\n", bv.cur_bit, sz, 3,
304 SI2Q_MAX_LEN);
305 return -ENOMEM;
306 }
Maxe610e702016-12-19 13:41:48 +0100307
308 rc = append_uarfcns(&bv, u, sc, u_len);
Max881064e2016-12-14 14:51:40 +0100309 if (rc < 0) {
310 LOGP(DRR, LOGL_ERROR, "SI2quater: failed to append %zu "
311 "UARFCNs due to range encoding failure: %s\n",
312 u_len, strerror(-rc));
313 return rc;
314 }
Max59a1bf32016-04-15 16:04:46 +0200315 } else { /* No 3G Neighbour Cell Description */
316 bitvec_set_bit(&bv, 0);
317 }
318
319 /* No 3G Measurement Parameters Description */
320 bitvec_set_bit(&bv, 0);
321 /* No GPRS_3G_MEASUREMENT Parameters Descr. */
322 bitvec_set_bit(&bv, 0);
323
Max26679e02016-04-20 15:57:13 +0200324 if (e) {
325 sz = earfcn_size(e);
326 if (sz + bv.cur_bit > SI2Q_MAX_LEN) {
327 LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
328 "add EARFCNs bits, current %u + required %u > max "
329 "%u\n", bv.cur_bit, sz, SI2Q_MAX_LEN);
Max59a1bf32016-04-15 16:04:46 +0200330 return -ENOMEM;
Max26679e02016-04-20 15:57:13 +0200331 }
Max59a1bf32016-04-15 16:04:46 +0200332 append_earfcn(&bv, e);
333 } else {
334 /* No Additions in Rel-5: */
335 bitvec_set_bit(&bv, L);
336 }
337
338 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
339 return bv.data_len;
340}
341
Harald Weltea43f7892009-12-01 18:04:30 +0530342/* Append selection parameters to bitvec */
343static void append_selection_params(struct bitvec *bv,
344 const struct gsm48_si_selection_params *sp)
345{
346 if (sp->present) {
347 bitvec_set_bit(bv, H);
348 bitvec_set_bit(bv, sp->cbq);
349 bitvec_set_uint(bv, sp->cell_resel_off, 6);
350 bitvec_set_uint(bv, sp->temp_offs, 3);
351 bitvec_set_uint(bv, sp->penalty_time, 5);
352 } else
353 bitvec_set_bit(bv, L);
354}
355
356/* Append power offset to bitvec */
357static void append_power_offset(struct bitvec *bv,
358 const struct gsm48_si_power_offset *po)
359{
360 if (po->present) {
361 bitvec_set_bit(bv, H);
362 bitvec_set_uint(bv, po->power_offset, 2);
363 } else
364 bitvec_set_bit(bv, L);
365}
366
367/* Append GPRS indicator to bitvec */
368static void append_gprs_ind(struct bitvec *bv,
369 const struct gsm48_si3_gprs_ind *gi)
370{
371 if (gi->present) {
372 bitvec_set_bit(bv, H);
373 bitvec_set_uint(bv, gi->ra_colour, 3);
374 /* 0 == SI13 in BCCH Norm, 1 == SI13 sent on BCCH Ext */
375 bitvec_set_bit(bv, gi->si13_position);
376 } else
377 bitvec_set_bit(bv, L);
378}
379
380
381/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200382int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3)
Harald Weltea43f7892009-12-01 18:04:30 +0530383{
384 struct bitvec bv;
385
386 memset(&bv, 0, sizeof(bv));
387 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100388 bv.data_len = 4;
Harald Weltea43f7892009-12-01 18:04:30 +0530389
390 /* Optional Selection Parameters */
391 append_selection_params(&bv, &si3->selection_params);
392
393 /* Optional Power Offset */
394 append_power_offset(&bv, &si3->power_offset);
395
396 /* Do we have a SI2ter on the BCCH? */
397 if (si3->si2ter_indicator)
398 bitvec_set_bit(&bv, H);
399 else
400 bitvec_set_bit(&bv, L);
401
402 /* Early Classmark Sending Control */
403 if (si3->early_cm_ctrl)
404 bitvec_set_bit(&bv, H);
405 else
406 bitvec_set_bit(&bv, L);
407
408 /* Do we have a SI Type 9 on the BCCH? */
409 if (si3->scheduling.present) {
410 bitvec_set_bit(&bv, H);
411 bitvec_set_uint(&bv, si3->scheduling.where, 3);
412 } else
413 bitvec_set_bit(&bv, L);
414
415 /* GPRS Indicator */
416 append_gprs_ind(&bv, &si3->gprs_ind);
417
Maxf3f35052016-04-15 16:04:44 +0200418 /* 3G Early Classmark Sending Restriction controlled by
419 * early_cm_ctrl above */
420 bitvec_set_bit(&bv, H);
421
422 if (si3->si2quater_indicator) {
423 bitvec_set_bit(&bv, H); /* indicator struct present */
424 bitvec_set_uint(&bv, 0, 1); /* message is sent on BCCH Norm */
425 }
426
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100427 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
428 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530429}
430
431static int append_lsa_params(struct bitvec *bv,
432 const struct gsm48_lsa_params *lsa_params)
433{
434 /* FIXME */
Holger Hans Peter Freytherae80f922010-04-10 00:05:16 +0200435 return -1;
Harald Weltea43f7892009-12-01 18:04:30 +0530436}
437
438/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100439int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len)
Harald Weltea43f7892009-12-01 18:04:30 +0530440{
441 struct bitvec bv;
442
443 memset(&bv, 0, sizeof(bv));
444 bv.data = data;
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100445 bv.data_len = len;
Harald Weltea43f7892009-12-01 18:04:30 +0530446
447 /* SI4 Rest Octets O */
448 append_selection_params(&bv, &si4->selection_params);
449 append_power_offset(&bv, &si4->power_offset);
450 append_gprs_ind(&bv, &si4->gprs_ind);
451
452 if (0 /* FIXME */) {
453 /* H and SI4 Rest Octets S */
454 bitvec_set_bit(&bv, H);
455
456 /* LSA Parameters */
457 if (si4->lsa_params.present) {
458 bitvec_set_bit(&bv, H);
459 append_lsa_params(&bv, &si4->lsa_params);
460 } else
461 bitvec_set_bit(&bv, L);
462
463 /* Cell Identity */
464 if (1) {
465 bitvec_set_bit(&bv, H);
466 bitvec_set_uint(&bv, si4->cell_id, 16);
467 } else
468 bitvec_set_bit(&bv, L);
469
470 /* LSA ID Information */
471 if (0) {
472 bitvec_set_bit(&bv, H);
473 /* FIXME */
474 } else
475 bitvec_set_bit(&bv, L);
476 } else {
477 /* L and break indicator */
478 bitvec_set_bit(&bv, L);
479 bitvec_set_bit(&bv, si4->break_ind ? H : L);
480 }
481
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100482 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530483}
484
Holger Hans Peter Freyther82dd9832016-05-17 23:20:03 +0200485
486/* GSM 04.18 ETSI TS 101 503 V8.27.0 (2006-05)
487
488<SI6 rest octets> ::=
489{L | H <PCH and NCH info>}
490{L | H <VBS/VGCS options : bit(2)>}
491{ < DTM_support : bit == L > I < DTM_support : bit == H >
492< RAC : bit (8) >
493< MAX_LAPDm : bit (3) > }
494< Band indicator >
495{ L | H < GPRS_MS_TXPWR_MAX_CCH : bit (5) > }
496<implicit spare >;
497*/
498int rest_octets_si6(uint8_t *data, bool is1800_net)
499{
500 struct bitvec bv;
501
502 memset(&bv, 0, sizeof(bv));
503 bv.data = data;
504 bv.data_len = 1;
505
506 /* no PCH/NCH info */
507 bitvec_set_bit(&bv, L);
508 /* no VBS/VGCS options */
509 bitvec_set_bit(&bv, L);
510 /* no DTM_support */
511 bitvec_set_bit(&bv, L);
512 /* band indicator */
513 if (is1800_net)
514 bitvec_set_bit(&bv, L);
515 else
516 bitvec_set_bit(&bv, H);
517 /* no GPRS_MS_TXPWR_MAX_CCH */
518 bitvec_set_bit(&bv, L);
519
520 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
521 return bv.data_len;
522}
523
Harald Weltea43f7892009-12-01 18:04:30 +0530524/* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a:
525 < GPRS Mobile Allocation IE > ::=
526 < HSN : bit (6) >
527 { 0 | 1 < RFL number list : < RFL number list struct > > }
528 { 0 < MA_LENGTH : bit (6) >
529 < MA_BITMAP: bit (val(MA_LENGTH) + 1) >
530 | 1 { 0 | 1 <ARFCN index list : < ARFCN index list struct > > } } ;
531
532 < RFL number list struct > :: =
533 < RFL_NUMBER : bit (4) >
534 { 0 | 1 < RFL number list struct > } ;
535 < ARFCN index list struct > ::=
536 < ARFCN_INDEX : bit(6) >
537 { 0 | 1 < ARFCN index list struct > } ;
538 */
539static int append_gprs_mobile_alloc(struct bitvec *bv)
540{
541 /* Hopping Sequence Number */
542 bitvec_set_uint(bv, 0, 6);
543
544 if (0) {
545 /* We want to use a RFL number list */
546 bitvec_set_bit(bv, 1);
547 /* FIXME: RFL number list */
548 } else
549 bitvec_set_bit(bv, 0);
550
551 if (0) {
552 /* We want to use a MA_BITMAP */
553 bitvec_set_bit(bv, 0);
554 /* FIXME: MA_LENGTH, MA_BITMAP, ... */
555 } else {
556 bitvec_set_bit(bv, 1);
557 if (0) {
558 /* We want to provide an ARFCN index list */
559 bitvec_set_bit(bv, 1);
560 /* FIXME */
561 } else
562 bitvec_set_bit(bv, 0);
563 }
564 return 0;
565}
566
567static int encode_t3192(unsigned int t3192)
568{
Philipp Maier3d6cb332016-12-20 14:23:45 +0100569 /* See also 3GPP TS 44.060
570 Table 12.24.2: GPRS Cell Options information element details */
Harald Weltea43f7892009-12-01 18:04:30 +0530571 if (t3192 == 0)
572 return 3;
573 else if (t3192 <= 80)
574 return 4;
575 else if (t3192 <= 120)
576 return 5;
577 else if (t3192 <= 160)
578 return 6;
579 else if (t3192 <= 200)
580 return 7;
581 else if (t3192 <= 500)
582 return 0;
583 else if (t3192 <= 1000)
584 return 1;
585 else if (t3192 <= 1500)
586 return 2;
587 else
588 return -EINVAL;
589}
590
591static int encode_drx_timer(unsigned int drx)
592{
593 if (drx == 0)
594 return 0;
595 else if (drx == 1)
596 return 1;
597 else if (drx == 2)
598 return 2;
599 else if (drx <= 4)
600 return 3;
601 else if (drx <= 8)
602 return 4;
603 else if (drx <= 16)
604 return 5;
605 else if (drx <= 32)
606 return 6;
607 else if (drx <= 64)
608 return 7;
609 else
610 return -EINVAL;
611}
612
613/* GPRS Cell Options as per TS 04.60 Chapter 12.24
614 < GPRS Cell Options IE > ::=
615 < NMO : bit(2) >
616 < T3168 : bit(3) >
617 < T3192 : bit(3) >
618 < DRX_TIMER_MAX: bit(3) >
619 < ACCESS_BURST_TYPE: bit >
620 < CONTROL_ACK_TYPE : bit >
621 < BS_CV_MAX: bit(4) >
622 { 0 | 1 < PAN_DEC : bit(3) >
623 < PAN_INC : bit(3) >
624 < PAN_MAX : bit(3) >
625 { 0 | 1 < Extension Length : bit(6) >
626 < bit (val(Extension Length) + 1
627 & { < Extension Information > ! { bit ** = <no string> } } ;
628 < Extension Information > ::=
629 { 0 | 1 < EGPRS_PACKET_CHANNEL_REQUEST : bit >
630 < BEP_PERIOD : bit(4) > }
631 < PFC_FEATURE_MODE : bit >
632 < DTM_SUPPORT : bit >
633 <BSS_PAGING_COORDINATION: bit >
634 <spare bit > ** ;
635 */
Harald Weltea4e2d042009-12-20 17:08:22 +0100636static int append_gprs_cell_opt(struct bitvec *bv,
637 const struct gprs_cell_options *gco)
Harald Weltea43f7892009-12-01 18:04:30 +0530638{
639 int t3192, drx_timer_max;
640
641 t3192 = encode_t3192(gco->t3192);
642 if (t3192 < 0)
643 return t3192;
644
645 drx_timer_max = encode_drx_timer(gco->drx_timer_max);
646 if (drx_timer_max < 0)
647 return drx_timer_max;
648
649 bitvec_set_uint(bv, gco->nmo, 2);
Philipp Maier3d6cb332016-12-20 14:23:45 +0100650
651 /* See also 3GPP TS 44.060
652 Table 12.24.2: GPRS Cell Options information element details */
653 bitvec_set_uint(bv, gco->t3168 / 500 - 1, 3);
654
Harald Weltea43f7892009-12-01 18:04:30 +0530655 bitvec_set_uint(bv, t3192, 3);
656 bitvec_set_uint(bv, drx_timer_max, 3);
657 /* ACCESS_BURST_TYPE: Hard-code 8bit */
658 bitvec_set_bit(bv, 0);
Max292ec582016-07-28 11:55:37 +0200659 /* CONTROL_ACK_TYPE: */
660 bitvec_set_bit(bv, gco->ctrl_ack_type_use_block);
Harald Weltea43f7892009-12-01 18:04:30 +0530661 bitvec_set_uint(bv, gco->bs_cv_max, 4);
662
Harald Weltea4b16652010-05-31 12:54:23 +0200663 if (0) {
664 /* hard-code no PAN_{DEC,INC,MAX} */
665 bitvec_set_bit(bv, 0);
666 } else {
667 /* copied from ip.access BSC protocol trace */
668 bitvec_set_bit(bv, 1);
669 bitvec_set_uint(bv, 1, 3); /* DEC */
670 bitvec_set_uint(bv, 1, 3); /* INC */
671 bitvec_set_uint(bv, 15, 3); /* MAX */
672 }
Harald Weltea43f7892009-12-01 18:04:30 +0530673
Harald Welteda0586a2010-04-18 14:49:05 +0200674 if (!gco->ext_info_present) {
675 /* no extension information */
676 bitvec_set_bit(bv, 0);
677 } else {
678 /* extension information */
679 bitvec_set_bit(bv, 1);
680 if (!gco->ext_info.egprs_supported) {
681 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200682 bitvec_set_uint(bv, (1 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200683 /* EGPRS supported in the cell */
684 bitvec_set_bit(bv, 0);
685 } else {
686 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200687 bitvec_set_uint(bv, (1 + 5 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200688 /* EGPRS supported in the cell */
689 bitvec_set_bit(bv, 1);
bhargava350533c2016-07-21 11:14:34 +0530690
Harald Welteda0586a2010-04-18 14:49:05 +0200691 /* 1bit EGPRS PACKET CHANNEL REQUEST */
bhargava350533c2016-07-21 11:14:34 +0530692 if (gco->supports_egprs_11bit_rach == 0) {
693 bitvec_set_bit(bv,
694 gco->ext_info.use_egprs_p_ch_req);
695 } else {
696 bitvec_set_bit(bv, 0);
697 }
698
Harald Welteda0586a2010-04-18 14:49:05 +0200699 /* 4bit BEP PERIOD */
700 bitvec_set_uint(bv, gco->ext_info.bep_period, 4);
701 }
702 bitvec_set_bit(bv, gco->ext_info.pfc_supported);
703 bitvec_set_bit(bv, gco->ext_info.dtm_supported);
704 bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination);
705 }
Harald Weltea43f7892009-12-01 18:04:30 +0530706
707 return 0;
708}
709
710static void append_gprs_pwr_ctrl_pars(struct bitvec *bv,
Harald Weltea4e2d042009-12-20 17:08:22 +0100711 const struct gprs_power_ctrl_pars *pcp)
Harald Weltea43f7892009-12-01 18:04:30 +0530712{
713 bitvec_set_uint(bv, pcp->alpha, 4);
714 bitvec_set_uint(bv, pcp->t_avg_w, 5);
715 bitvec_set_uint(bv, pcp->t_avg_t, 5);
716 bitvec_set_uint(bv, pcp->pc_meas_chan, 1);
717 bitvec_set_uint(bv, pcp->n_avg_i, 4);
718}
719
Harald Welte5fda9082010-04-18 22:41:01 +0200720/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200721int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13)
Harald Weltea43f7892009-12-01 18:04:30 +0530722{
723 struct bitvec bv;
724
725 memset(&bv, 0, sizeof(bv));
726 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100727 bv.data_len = 20;
Harald Weltea43f7892009-12-01 18:04:30 +0530728
729 if (0) {
730 /* No rest octets */
731 bitvec_set_bit(&bv, L);
732 } else {
733 bitvec_set_bit(&bv, H);
734 bitvec_set_uint(&bv, si13->bcch_change_mark, 3);
735 bitvec_set_uint(&bv, si13->si_change_field, 4);
Harald Welte97a282b2010-03-14 15:37:43 +0800736 if (1) {
Harald Weltea43f7892009-12-01 18:04:30 +0530737 bitvec_set_bit(&bv, 0);
738 } else {
739 bitvec_set_bit(&bv, 1);
740 bitvec_set_uint(&bv, si13->bcch_change_mark, 2);
741 append_gprs_mobile_alloc(&bv);
742 }
743 if (!si13->pbcch_present) {
744 /* PBCCH not present in cell */
745 bitvec_set_bit(&bv, 0);
746 bitvec_set_uint(&bv, si13->no_pbcch.rac, 8);
747 bitvec_set_bit(&bv, si13->no_pbcch.spgc_ccch_sup);
748 bitvec_set_uint(&bv, si13->no_pbcch.prio_acc_thr, 3);
749 bitvec_set_uint(&bv, si13->no_pbcch.net_ctrl_ord, 2);
750 append_gprs_cell_opt(&bv, &si13->cell_opts);
751 append_gprs_pwr_ctrl_pars(&bv, &si13->pwr_ctrl_pars);
752 } else {
753 /* PBCCH present in cell */
754 bitvec_set_bit(&bv, 1);
755 bitvec_set_uint(&bv, si13->pbcch.psi1_rep_per, 4);
756 /* PBCCH Descripiton */
757 bitvec_set_uint(&bv, si13->pbcch.pb, 4);
758 bitvec_set_uint(&bv, si13->pbcch.tsc, 3);
759 bitvec_set_uint(&bv, si13->pbcch.tn, 3);
760 switch (si13->pbcch.carrier_type) {
761 case PBCCH_BCCH:
762 bitvec_set_bit(&bv, 0);
763 bitvec_set_bit(&bv, 0);
764 break;
765 case PBCCH_ARFCN:
766 bitvec_set_bit(&bv, 0);
767 bitvec_set_bit(&bv, 1);
768 bitvec_set_uint(&bv, si13->pbcch.arfcn, 10);
769 break;
770 case PBCCH_MAIO:
771 bitvec_set_bit(&bv, 1);
772 bitvec_set_uint(&bv, si13->pbcch.maio, 6);
773 break;
774 }
775 }
Harald Welte5fda9082010-04-18 22:41:01 +0200776 /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */
777 bitvec_set_bit(&bv, H); /* added Release 99 */
778 /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS
779 * was only added in this Release */
780 bitvec_set_bit(&bv, 1);
Harald Weltea43f7892009-12-01 18:04:30 +0530781 }
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100782 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
783 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530784}