blob: 09c4a90145fd8bb42b76ea887c98b3c6db04e432 [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
Neels Hofmeyrc0164792017-09-04 15:15:32 +020029#include <osmocom/bsc/debug.h>
30#include <osmocom/bsc/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>
Neels Hofmeyrc0164792017-09-04 15:15:32 +020033#include <osmocom/bsc/rest_octets.h>
34#include <osmocom/bsc/arfcn_range_encode.h>
35#include <osmocom/bsc/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
Maxf39d03a2017-05-12 17:00:30 +020061/* Append Repeated E-UTRAN Neighbour Cell to bitvec: see 3GPP TS 44.018 Table 10.5.2.33b.1 */
62static inline void append_eutran_neib_cell(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
Max59a1bf32016-04-15 16:04:46 +020063{
Maxf39d03a2017-05-12 17:00:30 +020064 const struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list;
65 unsigned i, skip = 0;
66 size_t offset = bts->e_offset;
67 uint8_t rem = budget - 6, earfcn_budget; /* account for mandatory stop bit and THRESH_E-UTRAN_high */
Max70fdd242017-06-15 15:10:53 +020068
69 if (budget <= 6)
70 return;
71
72 OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
73
Maxf39d03a2017-05-12 17:00:30 +020074 /* first we have to properly adjust budget requirements */
75 if (e->prio_valid) /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
76 rem -= 4;
77 else
78 rem--;
79
80 if (e->thresh_lo_valid) /* THRESH_E-UTRAN_low: */
81 rem -= 6;
82 else
83 rem--;
84
85 if (e->qrxlm_valid) /* E-UTRAN_QRXLEVMIN: */
86 rem -= 6;
87 else
88 rem--;
89
90 /* now we can proceed with actually adding EARFCNs within adjusted budget limit */
Max59a1bf32016-04-15 16:04:46 +020091 for (i = 0; i < e->length; i++) {
92 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
Maxf39d03a2017-05-12 17:00:30 +020093 if (skip < offset) {
94 skip++; /* ignore EARFCNs added on previous calls */
95 } else {
Max70fdd242017-06-15 15:10:53 +020096 earfcn_budget = 17; /* compute budget per-EARFCN */
Maxf39d03a2017-05-12 17:00:30 +020097 if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
98 earfcn_budget++;
99 else
100 earfcn_budget += 4;
Max59a1bf32016-04-15 16:04:46 +0200101
Max70fdd242017-06-15 15:10:53 +0200102 if (rem - earfcn_budget < 0)
Maxf39d03a2017-05-12 17:00:30 +0200103 break;
Max70fdd242017-06-15 15:10:53 +0200104 else {
Maxf39d03a2017-05-12 17:00:30 +0200105 bts->e_offset++;
Max70fdd242017-06-15 15:10:53 +0200106 rem -= earfcn_budget;
Maxf39d03a2017-05-12 17:00:30 +0200107 bitvec_set_bit(bv, 1); /* EARFCN: */
108 bitvec_set_uint(bv, e->arfcn[i], 16);
109
110 if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
111 bitvec_set_bit(bv, 0);
112 else { /* Measurement Bandwidth: 9.1.54 */
113 bitvec_set_bit(bv, 1);
114 bitvec_set_uint(bv, e->meas_bw[i], 3);
115 }
116 }
Max59a1bf32016-04-15 16:04:46 +0200117 }
118 }
119 }
120
121 /* stop bit - end of EARFCN + Measurement Bandwidth sequence */
122 bitvec_set_bit(bv, 0);
123
Maxf39d03a2017-05-12 17:00:30 +0200124 /* Note: we don't support different EARFCN arrays each with different priority, threshold etc. */
125
Max59a1bf32016-04-15 16:04:46 +0200126 if (e->prio_valid) {
127 /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
128 bitvec_set_bit(bv, 1);
129 bitvec_set_uint(bv, e->prio, 3);
130 } else
131 bitvec_set_bit(bv, 0);
132
133 /* THRESH_E-UTRAN_high */
134 bitvec_set_uint(bv, e->thresh_hi, 5);
135
136 if (e->thresh_lo_valid) {
137 /* THRESH_E-UTRAN_low: */
138 bitvec_set_bit(bv, 1);
139 bitvec_set_uint(bv, e->thresh_lo, 5);
140 } else
141 bitvec_set_bit(bv, 0);
142
143 if (e->qrxlm_valid) {
144 /* E-UTRAN_QRXLEVMIN: */
145 bitvec_set_bit(bv, 1);
146 bitvec_set_uint(bv, e->qrxlm, 5);
147 } else
148 bitvec_set_bit(bv, 0);
149}
150
Maxf39d03a2017-05-12 17:00:30 +0200151static inline void append_earfcn(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
Max59a1bf32016-04-15 16:04:46 +0200152{
Max70fdd242017-06-15 15:10:53 +0200153 int rem = budget - 25;
154 if (rem <= 0)
155 return;
156
157 OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
158
Max59a1bf32016-04-15 16:04:46 +0200159 /* Additions in Rel-5: */
160 bitvec_set_bit(bv, H);
161 /* No 3G Additional Measurement Param. Descr. */
162 bitvec_set_bit(bv, 0);
163 /* No 3G ADDITIONAL MEASUREMENT Param. Descr. 2 */
164 bitvec_set_bit(bv, 0);
165 /* Additions in Rel-6: */
166 bitvec_set_bit(bv, H);
167 /* 3G_CCN_ACTIVE */
168 bitvec_set_bit(bv, 0);
169 /* Additions in Rel-7: */
170 bitvec_set_bit(bv, H);
171 /* No 700_REPORTING_OFFSET */
172 bitvec_set_bit(bv, 0);
173 /* No 810_REPORTING_OFFSET */
174 bitvec_set_bit(bv, 0);
175 /* Additions in Rel-8: */
176 bitvec_set_bit(bv, H);
177
178 /* Priority and E-UTRAN Parameters Description */
179 bitvec_set_bit(bv, 1);
180
181 /* No Serving Cell Priority Parameters Descr. */
182 bitvec_set_bit(bv, 0);
183 /* No 3G Priority Parameters Description */
184 bitvec_set_bit(bv, 0);
185 /* E-UTRAN Parameters Description */
186 bitvec_set_bit(bv, 1);
187
188 /* E-UTRAN_CCN_ACTIVE */
189 bitvec_set_bit(bv, 0);
190 /* E-UTRAN_Start: 9.1.54 */
191 bitvec_set_bit(bv, 1);
192 /* E-UTRAN_Stop: 9.1.54 */
193 bitvec_set_bit(bv, 1);
194
195 /* No E-UTRAN Measurement Parameters Descr. */
196 bitvec_set_bit(bv, 0);
197 /* No GPRS E-UTRAN Measurement Param. Descr. */
198 bitvec_set_bit(bv, 0);
199
200 /* Note: each of next 3 "repeated" structures might be repeated any
201 (0, 1, 2...) times - we only support 1 and 0 */
202
203 /* Repeated E-UTRAN Neighbour Cells */
204 bitvec_set_bit(bv, 1);
205
Maxf39d03a2017-05-12 17:00:30 +0200206 /* N. B: 25 bits are set in append_earfcn() - keep it in sync with budget adjustment below: */
Max70fdd242017-06-15 15:10:53 +0200207 append_eutran_neib_cell(bv, bts, rem);
Max59a1bf32016-04-15 16:04:46 +0200208
209 /* stop bit - end of Repeated E-UTRAN Neighbour Cells sequence: */
210 bitvec_set_bit(bv, 0);
211
212 /* Note: following 2 repeated structs are not supported ATM */
213 /* stop bit - end of Repeated E-UTRAN Not Allowed Cells sequence: */
214 bitvec_set_bit(bv, 0);
215 /* stop bit - end of Repeated E-UTRAN PCID to TA mapping sequence: */
216 bitvec_set_bit(bv, 0);
217
218 /* Priority and E-UTRAN Parameters Description ends here */
219 /* No 3G CSG Description */
220 bitvec_set_bit(bv, 0);
221 /* No E-UTRAN CSG Description */
222 bitvec_set_bit(bv, 0);
223 /* No Additions in Rel-9: */
224 bitvec_set_bit(bv, L);
225}
226
Maxf39d03a2017-05-12 17:00:30 +0200227static inline int f0_helper(int *sc, size_t length, uint8_t *chan_list)
Maxe610e702016-12-19 13:41:48 +0100228{
Maxf39d03a2017-05-12 17:00:30 +0200229 int w[RANGE_ENC_MAX_ARFCNS] = { 0 };
230
231 return range_encode(ARFCN_RANGE_1024, sc, length, w, 0, chan_list);
232}
233
234/* Estimate how many bits it'll take to append single FDD UARFCN */
235static inline int append_utran_fdd_length(uint16_t u, int *sc, size_t sc_len, size_t length)
236{
237 uint8_t chan_list[16] = { 0 };
238 int tmp[sc_len], f0;
239
240 memcpy(tmp, sc, sizeof(tmp));
241
242 f0 = f0_helper(tmp, length, chan_list);
243 if (f0 < 0)
244 return f0;
245
246 return 21 + range1024_p(length);
247}
248
249/* Append single FDD UARFCN */
250static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc, size_t length)
251{
252 uint8_t chan_list[16] = { 0 };
253 int f0 = f0_helper(sc, length, chan_list);
254
255 if (f0 < 0)
256 return f0;
257
Maxe610e702016-12-19 13:41:48 +0100258 /* Repeated UTRAN FDD Neighbour Cells */
259 bitvec_set_bit(bv, 1);
260
261 /* FDD-ARFCN */
262 bitvec_set_bit(bv, 0);
263 bitvec_set_uint(bv, u, 14);
264
Maxe610e702016-12-19 13:41:48 +0100265 /* FDD_Indic0: parameter value '0000000000' is a member of the set? */
266 bitvec_set_bit(bv, f0);
267 /* NR_OF_FDD_CELLS */
268 bitvec_set_uint(bv, length, 5);
269
270 f0 = bv->cur_bit;
271 bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
272 bv->cur_bit = f0 + range1024_p(length);
Maxf39d03a2017-05-12 17:00:30 +0200273
274 return 21 + range1024_p(length);
Maxe610e702016-12-19 13:41:48 +0100275}
276
277/* Append multiple FDD UARFCNs */
Maxf39d03a2017-05-12 17:00:30 +0200278static inline int append_uarfcns(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
Max26679e02016-04-20 15:57:13 +0200279{
Maxf39d03a2017-05-12 17:00:30 +0200280 const uint16_t *u = bts->si_common.data.uarfcn_list, *sc = bts->si_common.data.scramble_list;
281 int i, j, k, rc, st = 0, a[bts->si_common.uarfcn_length];
282 uint16_t cu = u[bts->u_offset]; /* caller ensures that length is positive */
Max70fdd242017-06-15 15:10:53 +0200283 uint8_t rem = budget - 7, offset_diff; /* account for constant bits right away */
284
285 OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
286
287 if (budget <= 7)
288 return -ENOMEM;
Max26679e02016-04-20 15:57:13 +0200289
290 /* 3G Neighbour Cell Description */
291 bitvec_set_bit(bv, 1);
292 /* No Index_Start_3G */
293 bitvec_set_bit(bv, 0);
294 /* No Absolute_Index_Start_EMR */
295 bitvec_set_bit(bv, 0);
296
297 /* UTRAN FDD Description */
298 bitvec_set_bit(bv, 1);
299 /* No Bandwidth_FDD */
300 bitvec_set_bit(bv, 0);
301
Maxf39d03a2017-05-12 17:00:30 +0200302 for (i = bts->u_offset; i < bts->si_common.uarfcn_length; i++) {
Max70fdd242017-06-15 15:10:53 +0200303 offset_diff = 0;
304 for (j = st, k = 0; j < i; j++) {
Maxe610e702016-12-19 13:41:48 +0100305 a[k++] = sc[j]; /* copy corresponding SCs */
Max70fdd242017-06-15 15:10:53 +0200306 offset_diff++; /* compute proper offset step */
307 }
Maxe610e702016-12-19 13:41:48 +0100308 if (u[i] != cu) { /* we've reached new UARFCN */
Maxf39d03a2017-05-12 17:00:30 +0200309 rc = append_utran_fdd_length(cu, a, bts->si_common.uarfcn_length, k);
310 if (rc < 0) { /* estimate bit length requirements */
Maxe610e702016-12-19 13:41:48 +0100311 return rc;
Maxf39d03a2017-05-12 17:00:30 +0200312 }
313
Max70fdd242017-06-15 15:10:53 +0200314 if (rem - rc <= 0)
Maxf39d03a2017-05-12 17:00:30 +0200315 break; /* we have ran out of budget in current SI2q */
Max70fdd242017-06-15 15:10:53 +0200316 else {
Maxf39d03a2017-05-12 17:00:30 +0200317 rem -= append_utran_fdd(bv, cu, a, k);
Max70fdd242017-06-15 15:10:53 +0200318 bts->u_offset += offset_diff;
Maxf39d03a2017-05-12 17:00:30 +0200319 }
Maxe610e702016-12-19 13:41:48 +0100320 cu = u[i];
321 st = i; /* update start position */
322 }
323 }
Max26679e02016-04-20 15:57:13 +0200324
Maxf39d03a2017-05-12 17:00:30 +0200325 if (rem > 22) { /* add last UARFCN not covered by previous cycle if it could possibly fit into budget */
Max70fdd242017-06-15 15:10:53 +0200326 offset_diff = 0;
327 for (i = st, k = 0; i < bts->si_common.uarfcn_length; i++) {
Maxf39d03a2017-05-12 17:00:30 +0200328 a[k++] = sc[i];
Max70fdd242017-06-15 15:10:53 +0200329 offset_diff++;
330 }
Maxf39d03a2017-05-12 17:00:30 +0200331 rc = append_utran_fdd_length(cu, a, bts->si_common.uarfcn_length, k);
332 if (rc < 0) {
333 return rc;
334 }
335
336 if (rem - rc >= 0) {
337 rem -= append_utran_fdd(bv, cu, a, k);
Max70fdd242017-06-15 15:10:53 +0200338 bts->u_offset += offset_diff;
Maxf39d03a2017-05-12 17:00:30 +0200339 }
340 }
Max26679e02016-04-20 15:57:13 +0200341
342 /* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
343 bitvec_set_bit(bv, 0);
344
345 /* UTRAN TDD Description */
346 bitvec_set_bit(bv, 0);
Max881064e2016-12-14 14:51:40 +0100347
348 return 0;
Max26679e02016-04-20 15:57:13 +0200349}
350
Max59a1bf32016-04-15 16:04:46 +0200351/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
Maxf39d03a2017-05-12 17:00:30 +0200352int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts)
Max59a1bf32016-04-15 16:04:46 +0200353{
Max881064e2016-12-14 14:51:40 +0100354 int rc;
Max59a1bf32016-04-15 16:04:46 +0200355 struct bitvec bv;
Max70fdd242017-06-15 15:10:53 +0200356
357 if (bts->si2q_count < bts->si2q_index)
358 return -EINVAL;
359
Max59a1bf32016-04-15 16:04:46 +0200360 bv.data = data;
361 bv.data_len = 20;
362 bitvec_zero(&bv);
363
Harald Welteaa70d9d2017-09-30 09:22:30 +0800364 /* BA_IND: Set to '0' as that's what we use for SI2xxx type,
365 * whereas '1' is used for SI5xxx type messages. The point here
366 * is to be able to correlate whether a given MS measurement
367 * report was using the neighbor cells advertised in SI2 or in
368 * SI5, as those two could very well be different */
369 bitvec_set_bit(&bv, 0);
Max59a1bf32016-04-15 16:04:46 +0200370 /* 3G_BA_IND */
371 bitvec_set_bit(&bv, 1);
372 /* MP_CHANGE_MARK */
373 bitvec_set_bit(&bv, 0);
374
Max59a1bf32016-04-15 16:04:46 +0200375 /* SI2quater_INDEX */
Maxf39d03a2017-05-12 17:00:30 +0200376 bitvec_set_uint(&bv, bts->si2q_index, 4);
Max59a1bf32016-04-15 16:04:46 +0200377 /* SI2quater_COUNT */
Maxf39d03a2017-05-12 17:00:30 +0200378 bitvec_set_uint(&bv, bts->si2q_count, 4);
Max59a1bf32016-04-15 16:04:46 +0200379
380 /* No Measurement_Parameters Description */
381 bitvec_set_bit(&bv, 0);
382 /* No GPRS_Real Time Difference Description */
383 bitvec_set_bit(&bv, 0);
384 /* No GPRS_BSIC Description */
385 bitvec_set_bit(&bv, 0);
386 /* No GPRS_REPORT PRIORITY Description */
387 bitvec_set_bit(&bv, 0);
388 /* No GPRS_MEASUREMENT_Parameters Description */
389 bitvec_set_bit(&bv, 0);
390 /* No NC Measurement Parameters */
391 bitvec_set_bit(&bv, 0);
392 /* No extension (length) */
393 bitvec_set_bit(&bv, 0);
394
Max70fdd242017-06-15 15:10:53 +0200395 rc = SI2Q_MAX_LEN - (bv.cur_bit + 3);
396 if (rc > 0 && bts->si_common.uarfcn_length - bts->u_offset > 0) {
397 rc = append_uarfcns(&bv, bts, rc);
Max881064e2016-12-14 14:51:40 +0100398 if (rc < 0) {
Max70fdd242017-06-15 15:10:53 +0200399 LOGP(DRR, LOGL_ERROR, "SI2quater [%u/%u]: failed to append %zu UARFCNs due to range encoding "
400 "failure: %s\n",
401 bts->si2q_index, bts->si2q_count, bts->si_common.uarfcn_length, strerror(-rc));
Max881064e2016-12-14 14:51:40 +0100402 return rc;
403 }
Max70fdd242017-06-15 15:10:53 +0200404 } else /* No 3G Neighbour Cell Description */
Max59a1bf32016-04-15 16:04:46 +0200405 bitvec_set_bit(&bv, 0);
Max59a1bf32016-04-15 16:04:46 +0200406
407 /* No 3G Measurement Parameters Description */
408 bitvec_set_bit(&bv, 0);
409 /* No GPRS_3G_MEASUREMENT Parameters Descr. */
410 bitvec_set_bit(&bv, 0);
411
Max70fdd242017-06-15 15:10:53 +0200412 rc = SI2Q_MAX_LEN - bv.cur_bit;
413 if (rc > 0 && si2q_earfcn_count(&bts->si_common.si2quater_neigh_list) - bts->e_offset > 0)
414 append_earfcn(&bv, bts, rc);
415 else /* No Additions in Rel-5: */
Max59a1bf32016-04-15 16:04:46 +0200416 bitvec_set_bit(&bv, L);
Max59a1bf32016-04-15 16:04:46 +0200417
418 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
419 return bv.data_len;
420}
421
Harald Weltea43f7892009-12-01 18:04:30 +0530422/* Append selection parameters to bitvec */
423static void append_selection_params(struct bitvec *bv,
424 const struct gsm48_si_selection_params *sp)
425{
426 if (sp->present) {
427 bitvec_set_bit(bv, H);
428 bitvec_set_bit(bv, sp->cbq);
429 bitvec_set_uint(bv, sp->cell_resel_off, 6);
430 bitvec_set_uint(bv, sp->temp_offs, 3);
431 bitvec_set_uint(bv, sp->penalty_time, 5);
432 } else
433 bitvec_set_bit(bv, L);
434}
435
436/* Append power offset to bitvec */
437static void append_power_offset(struct bitvec *bv,
438 const struct gsm48_si_power_offset *po)
439{
440 if (po->present) {
441 bitvec_set_bit(bv, H);
442 bitvec_set_uint(bv, po->power_offset, 2);
443 } else
444 bitvec_set_bit(bv, L);
445}
446
447/* Append GPRS indicator to bitvec */
448static void append_gprs_ind(struct bitvec *bv,
449 const struct gsm48_si3_gprs_ind *gi)
450{
451 if (gi->present) {
452 bitvec_set_bit(bv, H);
453 bitvec_set_uint(bv, gi->ra_colour, 3);
454 /* 0 == SI13 in BCCH Norm, 1 == SI13 sent on BCCH Ext */
455 bitvec_set_bit(bv, gi->si13_position);
456 } else
457 bitvec_set_bit(bv, L);
458}
459
460
461/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200462int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3)
Harald Weltea43f7892009-12-01 18:04:30 +0530463{
464 struct bitvec bv;
465
466 memset(&bv, 0, sizeof(bv));
467 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100468 bv.data_len = 4;
Harald Weltea43f7892009-12-01 18:04:30 +0530469
470 /* Optional Selection Parameters */
471 append_selection_params(&bv, &si3->selection_params);
472
473 /* Optional Power Offset */
474 append_power_offset(&bv, &si3->power_offset);
475
476 /* Do we have a SI2ter on the BCCH? */
477 if (si3->si2ter_indicator)
478 bitvec_set_bit(&bv, H);
479 else
480 bitvec_set_bit(&bv, L);
481
482 /* Early Classmark Sending Control */
483 if (si3->early_cm_ctrl)
484 bitvec_set_bit(&bv, H);
485 else
486 bitvec_set_bit(&bv, L);
487
488 /* Do we have a SI Type 9 on the BCCH? */
489 if (si3->scheduling.present) {
490 bitvec_set_bit(&bv, H);
491 bitvec_set_uint(&bv, si3->scheduling.where, 3);
492 } else
493 bitvec_set_bit(&bv, L);
494
495 /* GPRS Indicator */
496 append_gprs_ind(&bv, &si3->gprs_ind);
497
Maxf3f35052016-04-15 16:04:44 +0200498 /* 3G Early Classmark Sending Restriction controlled by
499 * early_cm_ctrl above */
500 bitvec_set_bit(&bv, H);
501
502 if (si3->si2quater_indicator) {
503 bitvec_set_bit(&bv, H); /* indicator struct present */
504 bitvec_set_uint(&bv, 0, 1); /* message is sent on BCCH Norm */
505 }
506
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100507 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
508 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530509}
510
511static int append_lsa_params(struct bitvec *bv,
512 const struct gsm48_lsa_params *lsa_params)
513{
514 /* FIXME */
Holger Hans Peter Freytherae80f922010-04-10 00:05:16 +0200515 return -1;
Harald Weltea43f7892009-12-01 18:04:30 +0530516}
517
518/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100519int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len)
Harald Weltea43f7892009-12-01 18:04:30 +0530520{
521 struct bitvec bv;
522
523 memset(&bv, 0, sizeof(bv));
524 bv.data = data;
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100525 bv.data_len = len;
Harald Weltea43f7892009-12-01 18:04:30 +0530526
527 /* SI4 Rest Octets O */
528 append_selection_params(&bv, &si4->selection_params);
529 append_power_offset(&bv, &si4->power_offset);
530 append_gprs_ind(&bv, &si4->gprs_ind);
531
532 if (0 /* FIXME */) {
533 /* H and SI4 Rest Octets S */
534 bitvec_set_bit(&bv, H);
535
536 /* LSA Parameters */
537 if (si4->lsa_params.present) {
538 bitvec_set_bit(&bv, H);
539 append_lsa_params(&bv, &si4->lsa_params);
540 } else
541 bitvec_set_bit(&bv, L);
542
543 /* Cell Identity */
544 if (1) {
545 bitvec_set_bit(&bv, H);
546 bitvec_set_uint(&bv, si4->cell_id, 16);
547 } else
548 bitvec_set_bit(&bv, L);
549
550 /* LSA ID Information */
551 if (0) {
552 bitvec_set_bit(&bv, H);
553 /* FIXME */
554 } else
555 bitvec_set_bit(&bv, L);
556 } else {
557 /* L and break indicator */
558 bitvec_set_bit(&bv, L);
559 bitvec_set_bit(&bv, si4->break_ind ? H : L);
560 }
561
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100562 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530563}
564
Holger Hans Peter Freyther82dd9832016-05-17 23:20:03 +0200565
566/* GSM 04.18 ETSI TS 101 503 V8.27.0 (2006-05)
567
568<SI6 rest octets> ::=
569{L | H <PCH and NCH info>}
570{L | H <VBS/VGCS options : bit(2)>}
571{ < DTM_support : bit == L > I < DTM_support : bit == H >
572< RAC : bit (8) >
573< MAX_LAPDm : bit (3) > }
574< Band indicator >
575{ L | H < GPRS_MS_TXPWR_MAX_CCH : bit (5) > }
576<implicit spare >;
577*/
578int rest_octets_si6(uint8_t *data, bool is1800_net)
579{
580 struct bitvec bv;
581
582 memset(&bv, 0, sizeof(bv));
583 bv.data = data;
584 bv.data_len = 1;
585
586 /* no PCH/NCH info */
587 bitvec_set_bit(&bv, L);
588 /* no VBS/VGCS options */
589 bitvec_set_bit(&bv, L);
590 /* no DTM_support */
591 bitvec_set_bit(&bv, L);
592 /* band indicator */
593 if (is1800_net)
594 bitvec_set_bit(&bv, L);
595 else
596 bitvec_set_bit(&bv, H);
597 /* no GPRS_MS_TXPWR_MAX_CCH */
598 bitvec_set_bit(&bv, L);
599
600 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
601 return bv.data_len;
602}
603
Harald Weltea43f7892009-12-01 18:04:30 +0530604/* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a:
605 < GPRS Mobile Allocation IE > ::=
606 < HSN : bit (6) >
607 { 0 | 1 < RFL number list : < RFL number list struct > > }
608 { 0 < MA_LENGTH : bit (6) >
609 < MA_BITMAP: bit (val(MA_LENGTH) + 1) >
610 | 1 { 0 | 1 <ARFCN index list : < ARFCN index list struct > > } } ;
611
612 < RFL number list struct > :: =
613 < RFL_NUMBER : bit (4) >
614 { 0 | 1 < RFL number list struct > } ;
615 < ARFCN index list struct > ::=
616 < ARFCN_INDEX : bit(6) >
617 { 0 | 1 < ARFCN index list struct > } ;
618 */
619static int append_gprs_mobile_alloc(struct bitvec *bv)
620{
621 /* Hopping Sequence Number */
622 bitvec_set_uint(bv, 0, 6);
623
624 if (0) {
625 /* We want to use a RFL number list */
626 bitvec_set_bit(bv, 1);
627 /* FIXME: RFL number list */
628 } else
629 bitvec_set_bit(bv, 0);
630
631 if (0) {
632 /* We want to use a MA_BITMAP */
633 bitvec_set_bit(bv, 0);
634 /* FIXME: MA_LENGTH, MA_BITMAP, ... */
635 } else {
636 bitvec_set_bit(bv, 1);
637 if (0) {
638 /* We want to provide an ARFCN index list */
639 bitvec_set_bit(bv, 1);
640 /* FIXME */
641 } else
642 bitvec_set_bit(bv, 0);
643 }
644 return 0;
645}
646
647static int encode_t3192(unsigned int t3192)
648{
Philipp Maier3d6cb332016-12-20 14:23:45 +0100649 /* See also 3GPP TS 44.060
650 Table 12.24.2: GPRS Cell Options information element details */
Harald Weltea43f7892009-12-01 18:04:30 +0530651 if (t3192 == 0)
652 return 3;
653 else if (t3192 <= 80)
654 return 4;
655 else if (t3192 <= 120)
656 return 5;
657 else if (t3192 <= 160)
658 return 6;
659 else if (t3192 <= 200)
660 return 7;
661 else if (t3192 <= 500)
662 return 0;
663 else if (t3192 <= 1000)
664 return 1;
665 else if (t3192 <= 1500)
666 return 2;
667 else
668 return -EINVAL;
669}
670
671static int encode_drx_timer(unsigned int drx)
672{
673 if (drx == 0)
674 return 0;
675 else if (drx == 1)
676 return 1;
677 else if (drx == 2)
678 return 2;
679 else if (drx <= 4)
680 return 3;
681 else if (drx <= 8)
682 return 4;
683 else if (drx <= 16)
684 return 5;
685 else if (drx <= 32)
686 return 6;
687 else if (drx <= 64)
688 return 7;
689 else
690 return -EINVAL;
691}
692
693/* GPRS Cell Options as per TS 04.60 Chapter 12.24
694 < GPRS Cell Options IE > ::=
695 < NMO : bit(2) >
696 < T3168 : bit(3) >
697 < T3192 : bit(3) >
698 < DRX_TIMER_MAX: bit(3) >
699 < ACCESS_BURST_TYPE: bit >
700 < CONTROL_ACK_TYPE : bit >
701 < BS_CV_MAX: bit(4) >
702 { 0 | 1 < PAN_DEC : bit(3) >
703 < PAN_INC : bit(3) >
704 < PAN_MAX : bit(3) >
705 { 0 | 1 < Extension Length : bit(6) >
706 < bit (val(Extension Length) + 1
707 & { < Extension Information > ! { bit ** = <no string> } } ;
708 < Extension Information > ::=
709 { 0 | 1 < EGPRS_PACKET_CHANNEL_REQUEST : bit >
710 < BEP_PERIOD : bit(4) > }
711 < PFC_FEATURE_MODE : bit >
712 < DTM_SUPPORT : bit >
713 <BSS_PAGING_COORDINATION: bit >
714 <spare bit > ** ;
715 */
Harald Weltea4e2d042009-12-20 17:08:22 +0100716static int append_gprs_cell_opt(struct bitvec *bv,
717 const struct gprs_cell_options *gco)
Harald Weltea43f7892009-12-01 18:04:30 +0530718{
719 int t3192, drx_timer_max;
720
721 t3192 = encode_t3192(gco->t3192);
722 if (t3192 < 0)
723 return t3192;
724
725 drx_timer_max = encode_drx_timer(gco->drx_timer_max);
726 if (drx_timer_max < 0)
727 return drx_timer_max;
728
729 bitvec_set_uint(bv, gco->nmo, 2);
Philipp Maier3d6cb332016-12-20 14:23:45 +0100730
731 /* See also 3GPP TS 44.060
732 Table 12.24.2: GPRS Cell Options information element details */
733 bitvec_set_uint(bv, gco->t3168 / 500 - 1, 3);
734
Harald Weltea43f7892009-12-01 18:04:30 +0530735 bitvec_set_uint(bv, t3192, 3);
736 bitvec_set_uint(bv, drx_timer_max, 3);
737 /* ACCESS_BURST_TYPE: Hard-code 8bit */
738 bitvec_set_bit(bv, 0);
Max292ec582016-07-28 11:55:37 +0200739 /* CONTROL_ACK_TYPE: */
740 bitvec_set_bit(bv, gco->ctrl_ack_type_use_block);
Harald Weltea43f7892009-12-01 18:04:30 +0530741 bitvec_set_uint(bv, gco->bs_cv_max, 4);
742
Harald Weltea4b16652010-05-31 12:54:23 +0200743 if (0) {
744 /* hard-code no PAN_{DEC,INC,MAX} */
745 bitvec_set_bit(bv, 0);
746 } else {
747 /* copied from ip.access BSC protocol trace */
748 bitvec_set_bit(bv, 1);
749 bitvec_set_uint(bv, 1, 3); /* DEC */
750 bitvec_set_uint(bv, 1, 3); /* INC */
751 bitvec_set_uint(bv, 15, 3); /* MAX */
752 }
Harald Weltea43f7892009-12-01 18:04:30 +0530753
Harald Welteda0586a2010-04-18 14:49:05 +0200754 if (!gco->ext_info_present) {
755 /* no extension information */
756 bitvec_set_bit(bv, 0);
757 } else {
758 /* extension information */
759 bitvec_set_bit(bv, 1);
760 if (!gco->ext_info.egprs_supported) {
761 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200762 bitvec_set_uint(bv, (1 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200763 /* EGPRS supported in the cell */
764 bitvec_set_bit(bv, 0);
765 } else {
766 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200767 bitvec_set_uint(bv, (1 + 5 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200768 /* EGPRS supported in the cell */
769 bitvec_set_bit(bv, 1);
bhargava350533c2016-07-21 11:14:34 +0530770
Harald Welteda0586a2010-04-18 14:49:05 +0200771 /* 1bit EGPRS PACKET CHANNEL REQUEST */
bhargava350533c2016-07-21 11:14:34 +0530772 if (gco->supports_egprs_11bit_rach == 0) {
773 bitvec_set_bit(bv,
774 gco->ext_info.use_egprs_p_ch_req);
775 } else {
776 bitvec_set_bit(bv, 0);
777 }
778
Harald Welteda0586a2010-04-18 14:49:05 +0200779 /* 4bit BEP PERIOD */
780 bitvec_set_uint(bv, gco->ext_info.bep_period, 4);
781 }
782 bitvec_set_bit(bv, gco->ext_info.pfc_supported);
783 bitvec_set_bit(bv, gco->ext_info.dtm_supported);
784 bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination);
785 }
Harald Weltea43f7892009-12-01 18:04:30 +0530786
787 return 0;
788}
789
790static void append_gprs_pwr_ctrl_pars(struct bitvec *bv,
Harald Weltea4e2d042009-12-20 17:08:22 +0100791 const struct gprs_power_ctrl_pars *pcp)
Harald Weltea43f7892009-12-01 18:04:30 +0530792{
793 bitvec_set_uint(bv, pcp->alpha, 4);
794 bitvec_set_uint(bv, pcp->t_avg_w, 5);
795 bitvec_set_uint(bv, pcp->t_avg_t, 5);
796 bitvec_set_uint(bv, pcp->pc_meas_chan, 1);
797 bitvec_set_uint(bv, pcp->n_avg_i, 4);
798}
799
Harald Welte5fda9082010-04-18 22:41:01 +0200800/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200801int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13)
Harald Weltea43f7892009-12-01 18:04:30 +0530802{
803 struct bitvec bv;
804
805 memset(&bv, 0, sizeof(bv));
806 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100807 bv.data_len = 20;
Harald Weltea43f7892009-12-01 18:04:30 +0530808
809 if (0) {
810 /* No rest octets */
811 bitvec_set_bit(&bv, L);
812 } else {
813 bitvec_set_bit(&bv, H);
814 bitvec_set_uint(&bv, si13->bcch_change_mark, 3);
815 bitvec_set_uint(&bv, si13->si_change_field, 4);
Harald Welte97a282b2010-03-14 15:37:43 +0800816 if (1) {
Harald Weltea43f7892009-12-01 18:04:30 +0530817 bitvec_set_bit(&bv, 0);
818 } else {
819 bitvec_set_bit(&bv, 1);
820 bitvec_set_uint(&bv, si13->bcch_change_mark, 2);
821 append_gprs_mobile_alloc(&bv);
822 }
Max72fbc952017-08-29 13:14:24 +0200823 /* PBCCH not present in cell:
824 it shall never be indicated according to 3GPP TS 44.018 Table 10.5.2.37b.1 */
825 bitvec_set_bit(&bv, 0);
826 bitvec_set_uint(&bv, si13->rac, 8);
827 bitvec_set_bit(&bv, si13->spgc_ccch_sup);
828 bitvec_set_uint(&bv, si13->prio_acc_thr, 3);
829 bitvec_set_uint(&bv, si13->net_ctrl_ord, 2);
830 append_gprs_cell_opt(&bv, &si13->cell_opts);
831 append_gprs_pwr_ctrl_pars(&bv, &si13->pwr_ctrl_pars);
832
Harald Welte5fda9082010-04-18 22:41:01 +0200833 /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */
834 bitvec_set_bit(&bv, H); /* added Release 99 */
835 /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS
836 * was only added in this Release */
837 bitvec_set_bit(&bv, 1);
Harald Weltea43f7892009-12-01 18:04:30 +0530838 }
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100839 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
840 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530841}