blob: fc0282e069544ce5efa841864c4cec17af4190bf [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
Max881064e2016-12-14 14:51:40 +0100183static inline int append_uarfcn(struct bitvec *bv, const uint16_t *u,
Max26679e02016-04-20 15:57:13 +0200184 const uint16_t *sc, size_t length)
185{
Max881064e2016-12-14 14:51:40 +0100186 int f0_inc, i, w[RANGE_ENC_MAX_ARFCNS] = { 0 }, a[length];
Max26679e02016-04-20 15:57:13 +0200187 uint8_t chan_list[16] = {0};
188
189 /* 3G Neighbour Cell Description */
190 bitvec_set_bit(bv, 1);
191 /* No Index_Start_3G */
192 bitvec_set_bit(bv, 0);
193 /* No Absolute_Index_Start_EMR */
194 bitvec_set_bit(bv, 0);
195
196 /* UTRAN FDD Description */
197 bitvec_set_bit(bv, 1);
198 /* No Bandwidth_FDD */
199 bitvec_set_bit(bv, 0);
200
201 memset(w, 0, sizeof(w));
202 for (i = 0; i < length; i++)
203 a[i] = sc[i];
204
205 /* Note: we do not support repeating Neighbour Cells ATM */
206 /* Repeated UTRAN FDD Neighbour Cells */
207 bitvec_set_bit(bv, 1);
208
209 /* FDD-ARFCN */
210 bitvec_set_bit(bv, 0);
211 /* Note: we do not support multiple UARFCN values ATM: */
212 bitvec_set_uint(bv, u[0], 14);
213
Max881064e2016-12-14 14:51:40 +0100214 f0_inc = range_encode(ARFCN_RANGE_1024, a, length, w, 0, chan_list);
215 if (f0_inc < 0)
216 return f0_inc;
Max26679e02016-04-20 15:57:13 +0200217
218 /* FDD_Indic0: parameter value '0000000000' is not a member of the set */
219 bitvec_set_bit(bv, f0_inc);
220 /* NR_OF_FDD_CELLS */
221 bitvec_set_uint(bv, length, 5);
222
223 i = bv->cur_bit;
224 bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
225 bv->cur_bit = i + range1024_p(length);
226
227 /* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
228 bitvec_set_bit(bv, 0);
229
230 /* UTRAN TDD Description */
231 bitvec_set_bit(bv, 0);
Max881064e2016-12-14 14:51:40 +0100232
233 return 0;
Max26679e02016-04-20 15:57:13 +0200234}
235
Max59a1bf32016-04-15 16:04:46 +0200236/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
237int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e,
Max26679e02016-04-20 15:57:13 +0200238 const uint16_t *u, const uint16_t *sc, size_t u_len)
Max59a1bf32016-04-15 16:04:46 +0200239{
Max881064e2016-12-14 14:51:40 +0100240 int rc;
Max26679e02016-04-20 15:57:13 +0200241 unsigned sz;
Max59a1bf32016-04-15 16:04:46 +0200242 struct bitvec bv;
243 bv.data = data;
244 bv.data_len = 20;
245 bitvec_zero(&bv);
246
247 /* BA_IND */
248 bitvec_set_bit(&bv, 1);
249 /* 3G_BA_IND */
250 bitvec_set_bit(&bv, 1);
251 /* MP_CHANGE_MARK */
252 bitvec_set_bit(&bv, 0);
253
254 /* we do not support multiple si2quater messages at the moment: */
255 /* SI2quater_INDEX */
256 bitvec_set_uint(&bv, 0, 4);
257 /* SI2quater_COUNT */
258 bitvec_set_uint(&bv, 0, 4);
259
260 /* No Measurement_Parameters Description */
261 bitvec_set_bit(&bv, 0);
262 /* No GPRS_Real Time Difference Description */
263 bitvec_set_bit(&bv, 0);
264 /* No GPRS_BSIC Description */
265 bitvec_set_bit(&bv, 0);
266 /* No GPRS_REPORT PRIORITY Description */
267 bitvec_set_bit(&bv, 0);
268 /* No GPRS_MEASUREMENT_Parameters Description */
269 bitvec_set_bit(&bv, 0);
270 /* No NC Measurement Parameters */
271 bitvec_set_bit(&bv, 0);
272 /* No extension (length) */
273 bitvec_set_bit(&bv, 0);
274
Max26679e02016-04-20 15:57:13 +0200275 if (u_len) {
276 sz = uarfcn_size(u, sc, u_len);
277 /* Even if we do not append EARFCN we still need to set 3 bits */
278 if (sz + bv.cur_bit + 3 > SI2Q_MAX_LEN) {
279 LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
280 "add UARFCNs bits, current %u + required %u + "
281 "reminder %u > max %u\n", bv.cur_bit, sz, 3,
282 SI2Q_MAX_LEN);
283 return -ENOMEM;
284 }
Max881064e2016-12-14 14:51:40 +0100285 rc = append_uarfcn(&bv, u, sc, u_len);
286 if (rc < 0) {
287 LOGP(DRR, LOGL_ERROR, "SI2quater: failed to append %zu "
288 "UARFCNs due to range encoding failure: %s\n",
289 u_len, strerror(-rc));
290 return rc;
291 }
Max59a1bf32016-04-15 16:04:46 +0200292 } else { /* No 3G Neighbour Cell Description */
293 bitvec_set_bit(&bv, 0);
294 }
295
296 /* No 3G Measurement Parameters Description */
297 bitvec_set_bit(&bv, 0);
298 /* No GPRS_3G_MEASUREMENT Parameters Descr. */
299 bitvec_set_bit(&bv, 0);
300
Max26679e02016-04-20 15:57:13 +0200301 if (e) {
302 sz = earfcn_size(e);
303 if (sz + bv.cur_bit > SI2Q_MAX_LEN) {
304 LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
305 "add EARFCNs bits, current %u + required %u > max "
306 "%u\n", bv.cur_bit, sz, SI2Q_MAX_LEN);
Max59a1bf32016-04-15 16:04:46 +0200307 return -ENOMEM;
Max26679e02016-04-20 15:57:13 +0200308 }
Max59a1bf32016-04-15 16:04:46 +0200309 append_earfcn(&bv, e);
310 } else {
311 /* No Additions in Rel-5: */
312 bitvec_set_bit(&bv, L);
313 }
314
315 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
316 return bv.data_len;
317}
318
Harald Weltea43f7892009-12-01 18:04:30 +0530319/* Append selection parameters to bitvec */
320static void append_selection_params(struct bitvec *bv,
321 const struct gsm48_si_selection_params *sp)
322{
323 if (sp->present) {
324 bitvec_set_bit(bv, H);
325 bitvec_set_bit(bv, sp->cbq);
326 bitvec_set_uint(bv, sp->cell_resel_off, 6);
327 bitvec_set_uint(bv, sp->temp_offs, 3);
328 bitvec_set_uint(bv, sp->penalty_time, 5);
329 } else
330 bitvec_set_bit(bv, L);
331}
332
333/* Append power offset to bitvec */
334static void append_power_offset(struct bitvec *bv,
335 const struct gsm48_si_power_offset *po)
336{
337 if (po->present) {
338 bitvec_set_bit(bv, H);
339 bitvec_set_uint(bv, po->power_offset, 2);
340 } else
341 bitvec_set_bit(bv, L);
342}
343
344/* Append GPRS indicator to bitvec */
345static void append_gprs_ind(struct bitvec *bv,
346 const struct gsm48_si3_gprs_ind *gi)
347{
348 if (gi->present) {
349 bitvec_set_bit(bv, H);
350 bitvec_set_uint(bv, gi->ra_colour, 3);
351 /* 0 == SI13 in BCCH Norm, 1 == SI13 sent on BCCH Ext */
352 bitvec_set_bit(bv, gi->si13_position);
353 } else
354 bitvec_set_bit(bv, L);
355}
356
357
358/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200359int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3)
Harald Weltea43f7892009-12-01 18:04:30 +0530360{
361 struct bitvec bv;
362
363 memset(&bv, 0, sizeof(bv));
364 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100365 bv.data_len = 4;
Harald Weltea43f7892009-12-01 18:04:30 +0530366
367 /* Optional Selection Parameters */
368 append_selection_params(&bv, &si3->selection_params);
369
370 /* Optional Power Offset */
371 append_power_offset(&bv, &si3->power_offset);
372
373 /* Do we have a SI2ter on the BCCH? */
374 if (si3->si2ter_indicator)
375 bitvec_set_bit(&bv, H);
376 else
377 bitvec_set_bit(&bv, L);
378
379 /* Early Classmark Sending Control */
380 if (si3->early_cm_ctrl)
381 bitvec_set_bit(&bv, H);
382 else
383 bitvec_set_bit(&bv, L);
384
385 /* Do we have a SI Type 9 on the BCCH? */
386 if (si3->scheduling.present) {
387 bitvec_set_bit(&bv, H);
388 bitvec_set_uint(&bv, si3->scheduling.where, 3);
389 } else
390 bitvec_set_bit(&bv, L);
391
392 /* GPRS Indicator */
393 append_gprs_ind(&bv, &si3->gprs_ind);
394
Maxf3f35052016-04-15 16:04:44 +0200395 /* 3G Early Classmark Sending Restriction controlled by
396 * early_cm_ctrl above */
397 bitvec_set_bit(&bv, H);
398
399 if (si3->si2quater_indicator) {
400 bitvec_set_bit(&bv, H); /* indicator struct present */
401 bitvec_set_uint(&bv, 0, 1); /* message is sent on BCCH Norm */
402 }
403
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100404 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
405 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530406}
407
408static int append_lsa_params(struct bitvec *bv,
409 const struct gsm48_lsa_params *lsa_params)
410{
411 /* FIXME */
Holger Hans Peter Freytherae80f922010-04-10 00:05:16 +0200412 return -1;
Harald Weltea43f7892009-12-01 18:04:30 +0530413}
414
415/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100416int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len)
Harald Weltea43f7892009-12-01 18:04:30 +0530417{
418 struct bitvec bv;
419
420 memset(&bv, 0, sizeof(bv));
421 bv.data = data;
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100422 bv.data_len = len;
Harald Weltea43f7892009-12-01 18:04:30 +0530423
424 /* SI4 Rest Octets O */
425 append_selection_params(&bv, &si4->selection_params);
426 append_power_offset(&bv, &si4->power_offset);
427 append_gprs_ind(&bv, &si4->gprs_ind);
428
429 if (0 /* FIXME */) {
430 /* H and SI4 Rest Octets S */
431 bitvec_set_bit(&bv, H);
432
433 /* LSA Parameters */
434 if (si4->lsa_params.present) {
435 bitvec_set_bit(&bv, H);
436 append_lsa_params(&bv, &si4->lsa_params);
437 } else
438 bitvec_set_bit(&bv, L);
439
440 /* Cell Identity */
441 if (1) {
442 bitvec_set_bit(&bv, H);
443 bitvec_set_uint(&bv, si4->cell_id, 16);
444 } else
445 bitvec_set_bit(&bv, L);
446
447 /* LSA ID Information */
448 if (0) {
449 bitvec_set_bit(&bv, H);
450 /* FIXME */
451 } else
452 bitvec_set_bit(&bv, L);
453 } else {
454 /* L and break indicator */
455 bitvec_set_bit(&bv, L);
456 bitvec_set_bit(&bv, si4->break_ind ? H : L);
457 }
458
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100459 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530460}
461
Holger Hans Peter Freyther82dd9832016-05-17 23:20:03 +0200462
463/* GSM 04.18 ETSI TS 101 503 V8.27.0 (2006-05)
464
465<SI6 rest octets> ::=
466{L | H <PCH and NCH info>}
467{L | H <VBS/VGCS options : bit(2)>}
468{ < DTM_support : bit == L > I < DTM_support : bit == H >
469< RAC : bit (8) >
470< MAX_LAPDm : bit (3) > }
471< Band indicator >
472{ L | H < GPRS_MS_TXPWR_MAX_CCH : bit (5) > }
473<implicit spare >;
474*/
475int rest_octets_si6(uint8_t *data, bool is1800_net)
476{
477 struct bitvec bv;
478
479 memset(&bv, 0, sizeof(bv));
480 bv.data = data;
481 bv.data_len = 1;
482
483 /* no PCH/NCH info */
484 bitvec_set_bit(&bv, L);
485 /* no VBS/VGCS options */
486 bitvec_set_bit(&bv, L);
487 /* no DTM_support */
488 bitvec_set_bit(&bv, L);
489 /* band indicator */
490 if (is1800_net)
491 bitvec_set_bit(&bv, L);
492 else
493 bitvec_set_bit(&bv, H);
494 /* no GPRS_MS_TXPWR_MAX_CCH */
495 bitvec_set_bit(&bv, L);
496
497 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
498 return bv.data_len;
499}
500
Harald Weltea43f7892009-12-01 18:04:30 +0530501/* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a:
502 < GPRS Mobile Allocation IE > ::=
503 < HSN : bit (6) >
504 { 0 | 1 < RFL number list : < RFL number list struct > > }
505 { 0 < MA_LENGTH : bit (6) >
506 < MA_BITMAP: bit (val(MA_LENGTH) + 1) >
507 | 1 { 0 | 1 <ARFCN index list : < ARFCN index list struct > > } } ;
508
509 < RFL number list struct > :: =
510 < RFL_NUMBER : bit (4) >
511 { 0 | 1 < RFL number list struct > } ;
512 < ARFCN index list struct > ::=
513 < ARFCN_INDEX : bit(6) >
514 { 0 | 1 < ARFCN index list struct > } ;
515 */
516static int append_gprs_mobile_alloc(struct bitvec *bv)
517{
518 /* Hopping Sequence Number */
519 bitvec_set_uint(bv, 0, 6);
520
521 if (0) {
522 /* We want to use a RFL number list */
523 bitvec_set_bit(bv, 1);
524 /* FIXME: RFL number list */
525 } else
526 bitvec_set_bit(bv, 0);
527
528 if (0) {
529 /* We want to use a MA_BITMAP */
530 bitvec_set_bit(bv, 0);
531 /* FIXME: MA_LENGTH, MA_BITMAP, ... */
532 } else {
533 bitvec_set_bit(bv, 1);
534 if (0) {
535 /* We want to provide an ARFCN index list */
536 bitvec_set_bit(bv, 1);
537 /* FIXME */
538 } else
539 bitvec_set_bit(bv, 0);
540 }
541 return 0;
542}
543
544static int encode_t3192(unsigned int t3192)
545{
546 if (t3192 == 0)
547 return 3;
548 else if (t3192 <= 80)
549 return 4;
550 else if (t3192 <= 120)
551 return 5;
552 else if (t3192 <= 160)
553 return 6;
554 else if (t3192 <= 200)
555 return 7;
556 else if (t3192 <= 500)
557 return 0;
558 else if (t3192 <= 1000)
559 return 1;
560 else if (t3192 <= 1500)
561 return 2;
562 else
563 return -EINVAL;
564}
565
566static int encode_drx_timer(unsigned int drx)
567{
568 if (drx == 0)
569 return 0;
570 else if (drx == 1)
571 return 1;
572 else if (drx == 2)
573 return 2;
574 else if (drx <= 4)
575 return 3;
576 else if (drx <= 8)
577 return 4;
578 else if (drx <= 16)
579 return 5;
580 else if (drx <= 32)
581 return 6;
582 else if (drx <= 64)
583 return 7;
584 else
585 return -EINVAL;
586}
587
588/* GPRS Cell Options as per TS 04.60 Chapter 12.24
589 < GPRS Cell Options IE > ::=
590 < NMO : bit(2) >
591 < T3168 : bit(3) >
592 < T3192 : bit(3) >
593 < DRX_TIMER_MAX: bit(3) >
594 < ACCESS_BURST_TYPE: bit >
595 < CONTROL_ACK_TYPE : bit >
596 < BS_CV_MAX: bit(4) >
597 { 0 | 1 < PAN_DEC : bit(3) >
598 < PAN_INC : bit(3) >
599 < PAN_MAX : bit(3) >
600 { 0 | 1 < Extension Length : bit(6) >
601 < bit (val(Extension Length) + 1
602 & { < Extension Information > ! { bit ** = <no string> } } ;
603 < Extension Information > ::=
604 { 0 | 1 < EGPRS_PACKET_CHANNEL_REQUEST : bit >
605 < BEP_PERIOD : bit(4) > }
606 < PFC_FEATURE_MODE : bit >
607 < DTM_SUPPORT : bit >
608 <BSS_PAGING_COORDINATION: bit >
609 <spare bit > ** ;
610 */
Harald Weltea4e2d042009-12-20 17:08:22 +0100611static int append_gprs_cell_opt(struct bitvec *bv,
612 const struct gprs_cell_options *gco)
Harald Weltea43f7892009-12-01 18:04:30 +0530613{
614 int t3192, drx_timer_max;
615
616 t3192 = encode_t3192(gco->t3192);
617 if (t3192 < 0)
618 return t3192;
619
620 drx_timer_max = encode_drx_timer(gco->drx_timer_max);
621 if (drx_timer_max < 0)
622 return drx_timer_max;
623
624 bitvec_set_uint(bv, gco->nmo, 2);
625 bitvec_set_uint(bv, gco->t3168 / 500, 3);
626 bitvec_set_uint(bv, t3192, 3);
627 bitvec_set_uint(bv, drx_timer_max, 3);
628 /* ACCESS_BURST_TYPE: Hard-code 8bit */
629 bitvec_set_bit(bv, 0);
Max292ec582016-07-28 11:55:37 +0200630 /* CONTROL_ACK_TYPE: */
631 bitvec_set_bit(bv, gco->ctrl_ack_type_use_block);
Harald Weltea43f7892009-12-01 18:04:30 +0530632 bitvec_set_uint(bv, gco->bs_cv_max, 4);
633
Harald Weltea4b16652010-05-31 12:54:23 +0200634 if (0) {
635 /* hard-code no PAN_{DEC,INC,MAX} */
636 bitvec_set_bit(bv, 0);
637 } else {
638 /* copied from ip.access BSC protocol trace */
639 bitvec_set_bit(bv, 1);
640 bitvec_set_uint(bv, 1, 3); /* DEC */
641 bitvec_set_uint(bv, 1, 3); /* INC */
642 bitvec_set_uint(bv, 15, 3); /* MAX */
643 }
Harald Weltea43f7892009-12-01 18:04:30 +0530644
Harald Welteda0586a2010-04-18 14:49:05 +0200645 if (!gco->ext_info_present) {
646 /* no extension information */
647 bitvec_set_bit(bv, 0);
648 } else {
649 /* extension information */
650 bitvec_set_bit(bv, 1);
651 if (!gco->ext_info.egprs_supported) {
652 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200653 bitvec_set_uint(bv, (1 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200654 /* EGPRS supported in the cell */
655 bitvec_set_bit(bv, 0);
656 } else {
657 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200658 bitvec_set_uint(bv, (1 + 5 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200659 /* EGPRS supported in the cell */
660 bitvec_set_bit(bv, 1);
bhargava350533c2016-07-21 11:14:34 +0530661
Harald Welteda0586a2010-04-18 14:49:05 +0200662 /* 1bit EGPRS PACKET CHANNEL REQUEST */
bhargava350533c2016-07-21 11:14:34 +0530663 if (gco->supports_egprs_11bit_rach == 0) {
664 bitvec_set_bit(bv,
665 gco->ext_info.use_egprs_p_ch_req);
666 } else {
667 bitvec_set_bit(bv, 0);
668 }
669
Harald Welteda0586a2010-04-18 14:49:05 +0200670 /* 4bit BEP PERIOD */
671 bitvec_set_uint(bv, gco->ext_info.bep_period, 4);
672 }
673 bitvec_set_bit(bv, gco->ext_info.pfc_supported);
674 bitvec_set_bit(bv, gco->ext_info.dtm_supported);
675 bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination);
676 }
Harald Weltea43f7892009-12-01 18:04:30 +0530677
678 return 0;
679}
680
681static void append_gprs_pwr_ctrl_pars(struct bitvec *bv,
Harald Weltea4e2d042009-12-20 17:08:22 +0100682 const struct gprs_power_ctrl_pars *pcp)
Harald Weltea43f7892009-12-01 18:04:30 +0530683{
684 bitvec_set_uint(bv, pcp->alpha, 4);
685 bitvec_set_uint(bv, pcp->t_avg_w, 5);
686 bitvec_set_uint(bv, pcp->t_avg_t, 5);
687 bitvec_set_uint(bv, pcp->pc_meas_chan, 1);
688 bitvec_set_uint(bv, pcp->n_avg_i, 4);
689}
690
Harald Welte5fda9082010-04-18 22:41:01 +0200691/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200692int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13)
Harald Weltea43f7892009-12-01 18:04:30 +0530693{
694 struct bitvec bv;
695
696 memset(&bv, 0, sizeof(bv));
697 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100698 bv.data_len = 20;
Harald Weltea43f7892009-12-01 18:04:30 +0530699
700 if (0) {
701 /* No rest octets */
702 bitvec_set_bit(&bv, L);
703 } else {
704 bitvec_set_bit(&bv, H);
705 bitvec_set_uint(&bv, si13->bcch_change_mark, 3);
706 bitvec_set_uint(&bv, si13->si_change_field, 4);
Harald Welte97a282b2010-03-14 15:37:43 +0800707 if (1) {
Harald Weltea43f7892009-12-01 18:04:30 +0530708 bitvec_set_bit(&bv, 0);
709 } else {
710 bitvec_set_bit(&bv, 1);
711 bitvec_set_uint(&bv, si13->bcch_change_mark, 2);
712 append_gprs_mobile_alloc(&bv);
713 }
714 if (!si13->pbcch_present) {
715 /* PBCCH not present in cell */
716 bitvec_set_bit(&bv, 0);
717 bitvec_set_uint(&bv, si13->no_pbcch.rac, 8);
718 bitvec_set_bit(&bv, si13->no_pbcch.spgc_ccch_sup);
719 bitvec_set_uint(&bv, si13->no_pbcch.prio_acc_thr, 3);
720 bitvec_set_uint(&bv, si13->no_pbcch.net_ctrl_ord, 2);
721 append_gprs_cell_opt(&bv, &si13->cell_opts);
722 append_gprs_pwr_ctrl_pars(&bv, &si13->pwr_ctrl_pars);
723 } else {
724 /* PBCCH present in cell */
725 bitvec_set_bit(&bv, 1);
726 bitvec_set_uint(&bv, si13->pbcch.psi1_rep_per, 4);
727 /* PBCCH Descripiton */
728 bitvec_set_uint(&bv, si13->pbcch.pb, 4);
729 bitvec_set_uint(&bv, si13->pbcch.tsc, 3);
730 bitvec_set_uint(&bv, si13->pbcch.tn, 3);
731 switch (si13->pbcch.carrier_type) {
732 case PBCCH_BCCH:
733 bitvec_set_bit(&bv, 0);
734 bitvec_set_bit(&bv, 0);
735 break;
736 case PBCCH_ARFCN:
737 bitvec_set_bit(&bv, 0);
738 bitvec_set_bit(&bv, 1);
739 bitvec_set_uint(&bv, si13->pbcch.arfcn, 10);
740 break;
741 case PBCCH_MAIO:
742 bitvec_set_bit(&bv, 1);
743 bitvec_set_uint(&bv, si13->pbcch.maio, 6);
744 break;
745 }
746 }
Harald Welte5fda9082010-04-18 22:41:01 +0200747 /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */
748 bitvec_set_bit(&bv, H); /* added Release 99 */
749 /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS
750 * was only added in this Release */
751 bitvec_set_bit(&bv, 1);
Harald Weltea43f7892009-12-01 18:04:30 +0530752 }
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100753 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
754 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530755}