blob: b59430bccd7c045ed62df30abca96d8f35f251b8 [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>
Harald Weltea43f7892009-12-01 18:04:30 +053032#include <openbsc/rest_octets.h>
Max59a1bf32016-04-15 16:04:46 +020033#include <openbsc/arfcn_range_encode.h>
Max26679e02016-04-20 15:57:13 +020034#include <openbsc/system_information.h>
Harald Weltea43f7892009-12-01 18:04:30 +053035
36/* generate SI1 rest octets */
Holger Hans Peter Freytherf876c392013-03-06 12:02:33 +010037int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net)
Harald Weltea43f7892009-12-01 18:04:30 +053038{
39 struct bitvec bv;
40
41 memset(&bv, 0, sizeof(bv));
42 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +010043 bv.data_len = 1;
Harald Weltea43f7892009-12-01 18:04:30 +053044
45 if (nch_pos) {
46 bitvec_set_bit(&bv, H);
47 bitvec_set_uint(&bv, *nch_pos, 5);
48 } else
49 bitvec_set_bit(&bv, L);
50
Holger Hans Peter Freytherf876c392013-03-06 12:02:33 +010051 if (is1800_net)
52 bitvec_set_bit(&bv, L);
53 else
54 bitvec_set_bit(&bv, H);
55
56 bitvec_spare_padding(&bv, 6);
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +010057 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +053058}
59
Max59a1bf32016-04-15 16:04:46 +020060/* Append Repeated E-UTRAN Neighbour Cell to bitvec:
61 * see 3GPP TS 44.018 Table 10.5.2.33b.1
62 */
63static inline void append_eutran_neib_cell(struct bitvec *bv,
64 const struct osmo_earfcn_si2q *e)
65{
66 unsigned i;
67 for (i = 0; i < e->length; i++) {
68 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
69 bitvec_set_bit(bv, 1); /* EARFCN: */
70 bitvec_set_uint(bv, e->arfcn[i], 16);
71
72 if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
73 bitvec_set_bit(bv, 0);
74 else {
75 /* Measurement Bandwidth: 9.1.54 */
76 bitvec_set_bit(bv, 1);
77 bitvec_set_uint(bv, e->meas_bw[i], 3);
78 }
79 }
80 }
81
82 /* stop bit - end of EARFCN + Measurement Bandwidth sequence */
83 bitvec_set_bit(bv, 0);
84
85 if (e->prio_valid) {
86 /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
87 bitvec_set_bit(bv, 1);
88 bitvec_set_uint(bv, e->prio, 3);
89 } else
90 bitvec_set_bit(bv, 0);
91
92 /* THRESH_E-UTRAN_high */
93 bitvec_set_uint(bv, e->thresh_hi, 5);
94
95 if (e->thresh_lo_valid) {
96 /* THRESH_E-UTRAN_low: */
97 bitvec_set_bit(bv, 1);
98 bitvec_set_uint(bv, e->thresh_lo, 5);
99 } else
100 bitvec_set_bit(bv, 0);
101
102 if (e->qrxlm_valid) {
103 /* E-UTRAN_QRXLEVMIN: */
104 bitvec_set_bit(bv, 1);
105 bitvec_set_uint(bv, e->qrxlm, 5);
106 } else
107 bitvec_set_bit(bv, 0);
108}
109
Max59a1bf32016-04-15 16:04:46 +0200110static inline void append_earfcn(struct bitvec *bv,
111 const struct osmo_earfcn_si2q *e)
112{
113 /* Additions in Rel-5: */
114 bitvec_set_bit(bv, H);
115 /* No 3G Additional Measurement Param. Descr. */
116 bitvec_set_bit(bv, 0);
117 /* No 3G ADDITIONAL MEASUREMENT Param. Descr. 2 */
118 bitvec_set_bit(bv, 0);
119 /* Additions in Rel-6: */
120 bitvec_set_bit(bv, H);
121 /* 3G_CCN_ACTIVE */
122 bitvec_set_bit(bv, 0);
123 /* Additions in Rel-7: */
124 bitvec_set_bit(bv, H);
125 /* No 700_REPORTING_OFFSET */
126 bitvec_set_bit(bv, 0);
127 /* No 810_REPORTING_OFFSET */
128 bitvec_set_bit(bv, 0);
129 /* Additions in Rel-8: */
130 bitvec_set_bit(bv, H);
131
132 /* Priority and E-UTRAN Parameters Description */
133 bitvec_set_bit(bv, 1);
134
135 /* No Serving Cell Priority Parameters Descr. */
136 bitvec_set_bit(bv, 0);
137 /* No 3G Priority Parameters Description */
138 bitvec_set_bit(bv, 0);
139 /* E-UTRAN Parameters Description */
140 bitvec_set_bit(bv, 1);
141
142 /* E-UTRAN_CCN_ACTIVE */
143 bitvec_set_bit(bv, 0);
144 /* E-UTRAN_Start: 9.1.54 */
145 bitvec_set_bit(bv, 1);
146 /* E-UTRAN_Stop: 9.1.54 */
147 bitvec_set_bit(bv, 1);
148
149 /* No E-UTRAN Measurement Parameters Descr. */
150 bitvec_set_bit(bv, 0);
151 /* No GPRS E-UTRAN Measurement Param. Descr. */
152 bitvec_set_bit(bv, 0);
153
154 /* Note: each of next 3 "repeated" structures might be repeated any
155 (0, 1, 2...) times - we only support 1 and 0 */
156
157 /* Repeated E-UTRAN Neighbour Cells */
158 bitvec_set_bit(bv, 1);
159
160 /* Note: we don't support different EARFCN arrays each with different
161 priority, threshold etc. */
162 append_eutran_neib_cell(bv, e);
163
164 /* stop bit - end of Repeated E-UTRAN Neighbour Cells sequence: */
165 bitvec_set_bit(bv, 0);
166
167 /* Note: following 2 repeated structs are not supported ATM */
168 /* stop bit - end of Repeated E-UTRAN Not Allowed Cells sequence: */
169 bitvec_set_bit(bv, 0);
170 /* stop bit - end of Repeated E-UTRAN PCID to TA mapping sequence: */
171 bitvec_set_bit(bv, 0);
172
173 /* Priority and E-UTRAN Parameters Description ends here */
174 /* No 3G CSG Description */
175 bitvec_set_bit(bv, 0);
176 /* No E-UTRAN CSG Description */
177 bitvec_set_bit(bv, 0);
178 /* No Additions in Rel-9: */
179 bitvec_set_bit(bv, L);
180}
181
Max26679e02016-04-20 15:57:13 +0200182static inline void append_uarfcn(struct bitvec *bv, const uint16_t *u,
183 const uint16_t *sc, size_t length)
184{
185 int f0_inc, i, arfcns_used, w[RANGE_ENC_MAX_ARFCNS], a[length];
186 uint8_t chan_list[16] = {0};
187
188 /* 3G Neighbour Cell Description */
189 bitvec_set_bit(bv, 1);
190 /* No Index_Start_3G */
191 bitvec_set_bit(bv, 0);
192 /* No Absolute_Index_Start_EMR */
193 bitvec_set_bit(bv, 0);
194
195 /* UTRAN FDD Description */
196 bitvec_set_bit(bv, 1);
197 /* No Bandwidth_FDD */
198 bitvec_set_bit(bv, 0);
199
200 memset(w, 0, sizeof(w));
201 for (i = 0; i < length; i++)
202 a[i] = sc[i];
203
204 /* Note: we do not support repeating Neighbour Cells ATM */
205 /* Repeated UTRAN FDD Neighbour Cells */
206 bitvec_set_bit(bv, 1);
207
208 /* FDD-ARFCN */
209 bitvec_set_bit(bv, 0);
210 /* Note: we do not support multiple UARFCN values ATM: */
211 bitvec_set_uint(bv, u[0], 14);
212
213 arfcns_used = range_enc_filter_arfcns(a, length, 0, &f0_inc);
214 range_enc_arfcns(ARFCN_RANGE_1024, a, arfcns_used, w, 0);
215 range_enc_range1024(chan_list, 0, f0_inc, w);
216
217 /* FDD_Indic0: parameter value '0000000000' is not a member of the set */
218 bitvec_set_bit(bv, f0_inc);
219 /* NR_OF_FDD_CELLS */
220 bitvec_set_uint(bv, length, 5);
221
222 i = bv->cur_bit;
223 bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
224 bv->cur_bit = i + range1024_p(length);
225
226 /* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
227 bitvec_set_bit(bv, 0);
228
229 /* UTRAN TDD Description */
230 bitvec_set_bit(bv, 0);
231}
232
Max59a1bf32016-04-15 16:04:46 +0200233/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
234int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e,
Max26679e02016-04-20 15:57:13 +0200235 const uint16_t *u, const uint16_t *sc, size_t u_len)
Max59a1bf32016-04-15 16:04:46 +0200236{
Max26679e02016-04-20 15:57:13 +0200237 unsigned sz;
Max59a1bf32016-04-15 16:04:46 +0200238 struct bitvec bv;
239 bv.data = data;
240 bv.data_len = 20;
241 bitvec_zero(&bv);
242
243 /* BA_IND */
244 bitvec_set_bit(&bv, 1);
245 /* 3G_BA_IND */
246 bitvec_set_bit(&bv, 1);
247 /* MP_CHANGE_MARK */
248 bitvec_set_bit(&bv, 0);
249
250 /* we do not support multiple si2quater messages at the moment: */
251 /* SI2quater_INDEX */
252 bitvec_set_uint(&bv, 0, 4);
253 /* SI2quater_COUNT */
254 bitvec_set_uint(&bv, 0, 4);
255
256 /* No Measurement_Parameters Description */
257 bitvec_set_bit(&bv, 0);
258 /* No GPRS_Real Time Difference Description */
259 bitvec_set_bit(&bv, 0);
260 /* No GPRS_BSIC Description */
261 bitvec_set_bit(&bv, 0);
262 /* No GPRS_REPORT PRIORITY Description */
263 bitvec_set_bit(&bv, 0);
264 /* No GPRS_MEASUREMENT_Parameters Description */
265 bitvec_set_bit(&bv, 0);
266 /* No NC Measurement Parameters */
267 bitvec_set_bit(&bv, 0);
268 /* No extension (length) */
269 bitvec_set_bit(&bv, 0);
270
Max26679e02016-04-20 15:57:13 +0200271 if (u_len) {
272 sz = uarfcn_size(u, sc, u_len);
273 /* Even if we do not append EARFCN we still need to set 3 bits */
274 if (sz + bv.cur_bit + 3 > SI2Q_MAX_LEN) {
275 LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
276 "add UARFCNs bits, current %u + required %u + "
277 "reminder %u > max %u\n", bv.cur_bit, sz, 3,
278 SI2Q_MAX_LEN);
279 return -ENOMEM;
280 }
281 append_uarfcn(&bv, u, sc, u_len);
Max59a1bf32016-04-15 16:04:46 +0200282 } else { /* No 3G Neighbour Cell Description */
283 bitvec_set_bit(&bv, 0);
284 }
285
286 /* No 3G Measurement Parameters Description */
287 bitvec_set_bit(&bv, 0);
288 /* No GPRS_3G_MEASUREMENT Parameters Descr. */
289 bitvec_set_bit(&bv, 0);
290
Max26679e02016-04-20 15:57:13 +0200291 if (e) {
292 sz = earfcn_size(e);
293 if (sz + bv.cur_bit > SI2Q_MAX_LEN) {
294 LOGP(DRR, LOGL_ERROR, "SI2quater: not enough memory to "
295 "add EARFCNs bits, current %u + required %u > max "
296 "%u\n", bv.cur_bit, sz, SI2Q_MAX_LEN);
Max59a1bf32016-04-15 16:04:46 +0200297 return -ENOMEM;
Max26679e02016-04-20 15:57:13 +0200298 }
Max59a1bf32016-04-15 16:04:46 +0200299 append_earfcn(&bv, e);
300 } else {
301 /* No Additions in Rel-5: */
302 bitvec_set_bit(&bv, L);
303 }
304
305 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
306 return bv.data_len;
307}
308
Harald Weltea43f7892009-12-01 18:04:30 +0530309/* Append selection parameters to bitvec */
310static void append_selection_params(struct bitvec *bv,
311 const struct gsm48_si_selection_params *sp)
312{
313 if (sp->present) {
314 bitvec_set_bit(bv, H);
315 bitvec_set_bit(bv, sp->cbq);
316 bitvec_set_uint(bv, sp->cell_resel_off, 6);
317 bitvec_set_uint(bv, sp->temp_offs, 3);
318 bitvec_set_uint(bv, sp->penalty_time, 5);
319 } else
320 bitvec_set_bit(bv, L);
321}
322
323/* Append power offset to bitvec */
324static void append_power_offset(struct bitvec *bv,
325 const struct gsm48_si_power_offset *po)
326{
327 if (po->present) {
328 bitvec_set_bit(bv, H);
329 bitvec_set_uint(bv, po->power_offset, 2);
330 } else
331 bitvec_set_bit(bv, L);
332}
333
334/* Append GPRS indicator to bitvec */
335static void append_gprs_ind(struct bitvec *bv,
336 const struct gsm48_si3_gprs_ind *gi)
337{
338 if (gi->present) {
339 bitvec_set_bit(bv, H);
340 bitvec_set_uint(bv, gi->ra_colour, 3);
341 /* 0 == SI13 in BCCH Norm, 1 == SI13 sent on BCCH Ext */
342 bitvec_set_bit(bv, gi->si13_position);
343 } else
344 bitvec_set_bit(bv, L);
345}
346
347
348/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200349int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3)
Harald Weltea43f7892009-12-01 18:04:30 +0530350{
351 struct bitvec bv;
352
353 memset(&bv, 0, sizeof(bv));
354 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100355 bv.data_len = 4;
Harald Weltea43f7892009-12-01 18:04:30 +0530356
357 /* Optional Selection Parameters */
358 append_selection_params(&bv, &si3->selection_params);
359
360 /* Optional Power Offset */
361 append_power_offset(&bv, &si3->power_offset);
362
363 /* Do we have a SI2ter on the BCCH? */
364 if (si3->si2ter_indicator)
365 bitvec_set_bit(&bv, H);
366 else
367 bitvec_set_bit(&bv, L);
368
369 /* Early Classmark Sending Control */
370 if (si3->early_cm_ctrl)
371 bitvec_set_bit(&bv, H);
372 else
373 bitvec_set_bit(&bv, L);
374
375 /* Do we have a SI Type 9 on the BCCH? */
376 if (si3->scheduling.present) {
377 bitvec_set_bit(&bv, H);
378 bitvec_set_uint(&bv, si3->scheduling.where, 3);
379 } else
380 bitvec_set_bit(&bv, L);
381
382 /* GPRS Indicator */
383 append_gprs_ind(&bv, &si3->gprs_ind);
384
Maxf3f35052016-04-15 16:04:44 +0200385 /* 3G Early Classmark Sending Restriction controlled by
386 * early_cm_ctrl above */
387 bitvec_set_bit(&bv, H);
388
389 if (si3->si2quater_indicator) {
390 bitvec_set_bit(&bv, H); /* indicator struct present */
391 bitvec_set_uint(&bv, 0, 1); /* message is sent on BCCH Norm */
392 }
393
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100394 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
395 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530396}
397
398static int append_lsa_params(struct bitvec *bv,
399 const struct gsm48_lsa_params *lsa_params)
400{
401 /* FIXME */
Holger Hans Peter Freytherae80f922010-04-10 00:05:16 +0200402 return -1;
Harald Weltea43f7892009-12-01 18:04:30 +0530403}
404
405/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100406int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len)
Harald Weltea43f7892009-12-01 18:04:30 +0530407{
408 struct bitvec bv;
409
410 memset(&bv, 0, sizeof(bv));
411 bv.data = data;
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100412 bv.data_len = len;
Harald Weltea43f7892009-12-01 18:04:30 +0530413
414 /* SI4 Rest Octets O */
415 append_selection_params(&bv, &si4->selection_params);
416 append_power_offset(&bv, &si4->power_offset);
417 append_gprs_ind(&bv, &si4->gprs_ind);
418
419 if (0 /* FIXME */) {
420 /* H and SI4 Rest Octets S */
421 bitvec_set_bit(&bv, H);
422
423 /* LSA Parameters */
424 if (si4->lsa_params.present) {
425 bitvec_set_bit(&bv, H);
426 append_lsa_params(&bv, &si4->lsa_params);
427 } else
428 bitvec_set_bit(&bv, L);
429
430 /* Cell Identity */
431 if (1) {
432 bitvec_set_bit(&bv, H);
433 bitvec_set_uint(&bv, si4->cell_id, 16);
434 } else
435 bitvec_set_bit(&bv, L);
436
437 /* LSA ID Information */
438 if (0) {
439 bitvec_set_bit(&bv, H);
440 /* FIXME */
441 } else
442 bitvec_set_bit(&bv, L);
443 } else {
444 /* L and break indicator */
445 bitvec_set_bit(&bv, L);
446 bitvec_set_bit(&bv, si4->break_ind ? H : L);
447 }
448
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100449 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530450}
451
452/* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a:
453 < GPRS Mobile Allocation IE > ::=
454 < HSN : bit (6) >
455 { 0 | 1 < RFL number list : < RFL number list struct > > }
456 { 0 < MA_LENGTH : bit (6) >
457 < MA_BITMAP: bit (val(MA_LENGTH) + 1) >
458 | 1 { 0 | 1 <ARFCN index list : < ARFCN index list struct > > } } ;
459
460 < RFL number list struct > :: =
461 < RFL_NUMBER : bit (4) >
462 { 0 | 1 < RFL number list struct > } ;
463 < ARFCN index list struct > ::=
464 < ARFCN_INDEX : bit(6) >
465 { 0 | 1 < ARFCN index list struct > } ;
466 */
467static int append_gprs_mobile_alloc(struct bitvec *bv)
468{
469 /* Hopping Sequence Number */
470 bitvec_set_uint(bv, 0, 6);
471
472 if (0) {
473 /* We want to use a RFL number list */
474 bitvec_set_bit(bv, 1);
475 /* FIXME: RFL number list */
476 } else
477 bitvec_set_bit(bv, 0);
478
479 if (0) {
480 /* We want to use a MA_BITMAP */
481 bitvec_set_bit(bv, 0);
482 /* FIXME: MA_LENGTH, MA_BITMAP, ... */
483 } else {
484 bitvec_set_bit(bv, 1);
485 if (0) {
486 /* We want to provide an ARFCN index list */
487 bitvec_set_bit(bv, 1);
488 /* FIXME */
489 } else
490 bitvec_set_bit(bv, 0);
491 }
492 return 0;
493}
494
495static int encode_t3192(unsigned int t3192)
496{
497 if (t3192 == 0)
498 return 3;
499 else if (t3192 <= 80)
500 return 4;
501 else if (t3192 <= 120)
502 return 5;
503 else if (t3192 <= 160)
504 return 6;
505 else if (t3192 <= 200)
506 return 7;
507 else if (t3192 <= 500)
508 return 0;
509 else if (t3192 <= 1000)
510 return 1;
511 else if (t3192 <= 1500)
512 return 2;
513 else
514 return -EINVAL;
515}
516
517static int encode_drx_timer(unsigned int drx)
518{
519 if (drx == 0)
520 return 0;
521 else if (drx == 1)
522 return 1;
523 else if (drx == 2)
524 return 2;
525 else if (drx <= 4)
526 return 3;
527 else if (drx <= 8)
528 return 4;
529 else if (drx <= 16)
530 return 5;
531 else if (drx <= 32)
532 return 6;
533 else if (drx <= 64)
534 return 7;
535 else
536 return -EINVAL;
537}
538
539/* GPRS Cell Options as per TS 04.60 Chapter 12.24
540 < GPRS Cell Options IE > ::=
541 < NMO : bit(2) >
542 < T3168 : bit(3) >
543 < T3192 : bit(3) >
544 < DRX_TIMER_MAX: bit(3) >
545 < ACCESS_BURST_TYPE: bit >
546 < CONTROL_ACK_TYPE : bit >
547 < BS_CV_MAX: bit(4) >
548 { 0 | 1 < PAN_DEC : bit(3) >
549 < PAN_INC : bit(3) >
550 < PAN_MAX : bit(3) >
551 { 0 | 1 < Extension Length : bit(6) >
552 < bit (val(Extension Length) + 1
553 & { < Extension Information > ! { bit ** = <no string> } } ;
554 < Extension Information > ::=
555 { 0 | 1 < EGPRS_PACKET_CHANNEL_REQUEST : bit >
556 < BEP_PERIOD : bit(4) > }
557 < PFC_FEATURE_MODE : bit >
558 < DTM_SUPPORT : bit >
559 <BSS_PAGING_COORDINATION: bit >
560 <spare bit > ** ;
561 */
Harald Weltea4e2d042009-12-20 17:08:22 +0100562static int append_gprs_cell_opt(struct bitvec *bv,
563 const struct gprs_cell_options *gco)
Harald Weltea43f7892009-12-01 18:04:30 +0530564{
565 int t3192, drx_timer_max;
566
567 t3192 = encode_t3192(gco->t3192);
568 if (t3192 < 0)
569 return t3192;
570
571 drx_timer_max = encode_drx_timer(gco->drx_timer_max);
572 if (drx_timer_max < 0)
573 return drx_timer_max;
574
575 bitvec_set_uint(bv, gco->nmo, 2);
576 bitvec_set_uint(bv, gco->t3168 / 500, 3);
577 bitvec_set_uint(bv, t3192, 3);
578 bitvec_set_uint(bv, drx_timer_max, 3);
579 /* ACCESS_BURST_TYPE: Hard-code 8bit */
580 bitvec_set_bit(bv, 0);
581 /* CONTROL_ACK_TYPE: Hard-code to RLC/MAC control block */
582 bitvec_set_bit(bv, 1);
583 bitvec_set_uint(bv, gco->bs_cv_max, 4);
584
Harald Weltea4b16652010-05-31 12:54:23 +0200585 if (0) {
586 /* hard-code no PAN_{DEC,INC,MAX} */
587 bitvec_set_bit(bv, 0);
588 } else {
589 /* copied from ip.access BSC protocol trace */
590 bitvec_set_bit(bv, 1);
591 bitvec_set_uint(bv, 1, 3); /* DEC */
592 bitvec_set_uint(bv, 1, 3); /* INC */
593 bitvec_set_uint(bv, 15, 3); /* MAX */
594 }
Harald Weltea43f7892009-12-01 18:04:30 +0530595
Harald Welteda0586a2010-04-18 14:49:05 +0200596 if (!gco->ext_info_present) {
597 /* no extension information */
598 bitvec_set_bit(bv, 0);
599 } else {
600 /* extension information */
601 bitvec_set_bit(bv, 1);
602 if (!gco->ext_info.egprs_supported) {
603 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200604 bitvec_set_uint(bv, (1 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200605 /* EGPRS supported in the cell */
606 bitvec_set_bit(bv, 0);
607 } else {
608 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200609 bitvec_set_uint(bv, (1 + 5 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200610 /* EGPRS supported in the cell */
611 bitvec_set_bit(bv, 1);
612 /* 1bit EGPRS PACKET CHANNEL REQUEST */
613 bitvec_set_bit(bv, gco->ext_info.use_egprs_p_ch_req);
614 /* 4bit BEP PERIOD */
615 bitvec_set_uint(bv, gco->ext_info.bep_period, 4);
616 }
617 bitvec_set_bit(bv, gco->ext_info.pfc_supported);
618 bitvec_set_bit(bv, gco->ext_info.dtm_supported);
619 bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination);
620 }
Harald Weltea43f7892009-12-01 18:04:30 +0530621
622 return 0;
623}
624
625static void append_gprs_pwr_ctrl_pars(struct bitvec *bv,
Harald Weltea4e2d042009-12-20 17:08:22 +0100626 const struct gprs_power_ctrl_pars *pcp)
Harald Weltea43f7892009-12-01 18:04:30 +0530627{
628 bitvec_set_uint(bv, pcp->alpha, 4);
629 bitvec_set_uint(bv, pcp->t_avg_w, 5);
630 bitvec_set_uint(bv, pcp->t_avg_t, 5);
631 bitvec_set_uint(bv, pcp->pc_meas_chan, 1);
632 bitvec_set_uint(bv, pcp->n_avg_i, 4);
633}
634
Harald Welte5fda9082010-04-18 22:41:01 +0200635/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200636int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13)
Harald Weltea43f7892009-12-01 18:04:30 +0530637{
638 struct bitvec bv;
639
640 memset(&bv, 0, sizeof(bv));
641 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100642 bv.data_len = 20;
Harald Weltea43f7892009-12-01 18:04:30 +0530643
644 if (0) {
645 /* No rest octets */
646 bitvec_set_bit(&bv, L);
647 } else {
648 bitvec_set_bit(&bv, H);
649 bitvec_set_uint(&bv, si13->bcch_change_mark, 3);
650 bitvec_set_uint(&bv, si13->si_change_field, 4);
Harald Welte97a282b2010-03-14 15:37:43 +0800651 if (1) {
Harald Weltea43f7892009-12-01 18:04:30 +0530652 bitvec_set_bit(&bv, 0);
653 } else {
654 bitvec_set_bit(&bv, 1);
655 bitvec_set_uint(&bv, si13->bcch_change_mark, 2);
656 append_gprs_mobile_alloc(&bv);
657 }
658 if (!si13->pbcch_present) {
659 /* PBCCH not present in cell */
660 bitvec_set_bit(&bv, 0);
661 bitvec_set_uint(&bv, si13->no_pbcch.rac, 8);
662 bitvec_set_bit(&bv, si13->no_pbcch.spgc_ccch_sup);
663 bitvec_set_uint(&bv, si13->no_pbcch.prio_acc_thr, 3);
664 bitvec_set_uint(&bv, si13->no_pbcch.net_ctrl_ord, 2);
665 append_gprs_cell_opt(&bv, &si13->cell_opts);
666 append_gprs_pwr_ctrl_pars(&bv, &si13->pwr_ctrl_pars);
667 } else {
668 /* PBCCH present in cell */
669 bitvec_set_bit(&bv, 1);
670 bitvec_set_uint(&bv, si13->pbcch.psi1_rep_per, 4);
671 /* PBCCH Descripiton */
672 bitvec_set_uint(&bv, si13->pbcch.pb, 4);
673 bitvec_set_uint(&bv, si13->pbcch.tsc, 3);
674 bitvec_set_uint(&bv, si13->pbcch.tn, 3);
675 switch (si13->pbcch.carrier_type) {
676 case PBCCH_BCCH:
677 bitvec_set_bit(&bv, 0);
678 bitvec_set_bit(&bv, 0);
679 break;
680 case PBCCH_ARFCN:
681 bitvec_set_bit(&bv, 0);
682 bitvec_set_bit(&bv, 1);
683 bitvec_set_uint(&bv, si13->pbcch.arfcn, 10);
684 break;
685 case PBCCH_MAIO:
686 bitvec_set_bit(&bv, 1);
687 bitvec_set_uint(&bv, si13->pbcch.maio, 6);
688 break;
689 }
690 }
Harald Welte5fda9082010-04-18 22:41:01 +0200691 /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */
692 bitvec_set_bit(&bv, H); /* added Release 99 */
693 /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS
694 * was only added in this Release */
695 bitvec_set_bit(&bv, 1);
Harald Weltea43f7892009-12-01 18:04:30 +0530696 }
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100697 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
698 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530699}