blob: 7c6d7cd9274e12b6b9e2e9ae35ac1b7a469f8d70 [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 */
Max39999a72017-10-10 16:20:23 +020062static inline bool 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;
Max39999a72017-10-10 16:20:23 +020067 int16_t rem = budget - 6; /* account for mandatory stop bit and THRESH_E-UTRAN_high */
68 uint8_t earfcn_budget;
Max70fdd242017-06-15 15:10:53 +020069
70 if (budget <= 6)
Max39999a72017-10-10 16:20:23 +020071 return false;
Max70fdd242017-06-15 15:10:53 +020072
73 OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
74
Maxf39d03a2017-05-12 17:00:30 +020075 /* first we have to properly adjust budget requirements */
76 if (e->prio_valid) /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
77 rem -= 4;
78 else
79 rem--;
80
81 if (e->thresh_lo_valid) /* THRESH_E-UTRAN_low: */
82 rem -= 6;
83 else
84 rem--;
85
86 if (e->qrxlm_valid) /* E-UTRAN_QRXLEVMIN: */
87 rem -= 6;
88 else
89 rem--;
90
Max39999a72017-10-10 16:20:23 +020091 if (rem < 0)
92 return false;
93
Maxf39d03a2017-05-12 17:00:30 +020094 /* now we can proceed with actually adding EARFCNs within adjusted budget limit */
Max59a1bf32016-04-15 16:04:46 +020095 for (i = 0; i < e->length; i++) {
96 if (e->arfcn[i] != OSMO_EARFCN_INVALID) {
Maxf39d03a2017-05-12 17:00:30 +020097 if (skip < offset) {
98 skip++; /* ignore EARFCNs added on previous calls */
99 } else {
Max70fdd242017-06-15 15:10:53 +0200100 earfcn_budget = 17; /* compute budget per-EARFCN */
Maxf39d03a2017-05-12 17:00:30 +0200101 if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
102 earfcn_budget++;
103 else
104 earfcn_budget += 4;
Max59a1bf32016-04-15 16:04:46 +0200105
Max70fdd242017-06-15 15:10:53 +0200106 if (rem - earfcn_budget < 0)
Maxf39d03a2017-05-12 17:00:30 +0200107 break;
Max70fdd242017-06-15 15:10:53 +0200108 else {
Maxf39d03a2017-05-12 17:00:30 +0200109 bts->e_offset++;
Max70fdd242017-06-15 15:10:53 +0200110 rem -= earfcn_budget;
Max39999a72017-10-10 16:20:23 +0200111
112 if (rem < 0)
113 return false;
114
Maxf39d03a2017-05-12 17:00:30 +0200115 bitvec_set_bit(bv, 1); /* EARFCN: */
116 bitvec_set_uint(bv, e->arfcn[i], 16);
117
118 if (OSMO_EARFCN_MEAS_INVALID == e->meas_bw[i])
119 bitvec_set_bit(bv, 0);
120 else { /* Measurement Bandwidth: 9.1.54 */
121 bitvec_set_bit(bv, 1);
122 bitvec_set_uint(bv, e->meas_bw[i], 3);
123 }
124 }
Max59a1bf32016-04-15 16:04:46 +0200125 }
126 }
127 }
128
129 /* stop bit - end of EARFCN + Measurement Bandwidth sequence */
130 bitvec_set_bit(bv, 0);
131
Maxf39d03a2017-05-12 17:00:30 +0200132 /* Note: we don't support different EARFCN arrays each with different priority, threshold etc. */
133
Max59a1bf32016-04-15 16:04:46 +0200134 if (e->prio_valid) {
135 /* E-UTRAN_PRIORITY: 3GPP TS 45.008*/
136 bitvec_set_bit(bv, 1);
137 bitvec_set_uint(bv, e->prio, 3);
138 } else
139 bitvec_set_bit(bv, 0);
140
141 /* THRESH_E-UTRAN_high */
142 bitvec_set_uint(bv, e->thresh_hi, 5);
143
144 if (e->thresh_lo_valid) {
145 /* THRESH_E-UTRAN_low: */
146 bitvec_set_bit(bv, 1);
147 bitvec_set_uint(bv, e->thresh_lo, 5);
148 } else
149 bitvec_set_bit(bv, 0);
150
151 if (e->qrxlm_valid) {
152 /* E-UTRAN_QRXLEVMIN: */
153 bitvec_set_bit(bv, 1);
154 bitvec_set_uint(bv, e->qrxlm, 5);
155 } else
156 bitvec_set_bit(bv, 0);
Max39999a72017-10-10 16:20:23 +0200157
158 return true;
Max59a1bf32016-04-15 16:04:46 +0200159}
160
Maxf39d03a2017-05-12 17:00:30 +0200161static inline void append_earfcn(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
Max59a1bf32016-04-15 16:04:46 +0200162{
Max39999a72017-10-10 16:20:23 +0200163 bool appended;
164 unsigned int old = bv->cur_bit; /* save current position to make rollback possible */
Max70fdd242017-06-15 15:10:53 +0200165 int rem = budget - 25;
166 if (rem <= 0)
167 return;
168
169 OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
170
Max59a1bf32016-04-15 16:04:46 +0200171 /* Additions in Rel-5: */
172 bitvec_set_bit(bv, H);
173 /* No 3G Additional Measurement Param. Descr. */
174 bitvec_set_bit(bv, 0);
175 /* No 3G ADDITIONAL MEASUREMENT Param. Descr. 2 */
176 bitvec_set_bit(bv, 0);
177 /* Additions in Rel-6: */
178 bitvec_set_bit(bv, H);
179 /* 3G_CCN_ACTIVE */
180 bitvec_set_bit(bv, 0);
181 /* Additions in Rel-7: */
182 bitvec_set_bit(bv, H);
183 /* No 700_REPORTING_OFFSET */
184 bitvec_set_bit(bv, 0);
185 /* No 810_REPORTING_OFFSET */
186 bitvec_set_bit(bv, 0);
187 /* Additions in Rel-8: */
188 bitvec_set_bit(bv, H);
189
190 /* Priority and E-UTRAN Parameters Description */
191 bitvec_set_bit(bv, 1);
192
193 /* No Serving Cell Priority Parameters Descr. */
194 bitvec_set_bit(bv, 0);
195 /* No 3G Priority Parameters Description */
196 bitvec_set_bit(bv, 0);
197 /* E-UTRAN Parameters Description */
198 bitvec_set_bit(bv, 1);
199
200 /* E-UTRAN_CCN_ACTIVE */
201 bitvec_set_bit(bv, 0);
202 /* E-UTRAN_Start: 9.1.54 */
203 bitvec_set_bit(bv, 1);
204 /* E-UTRAN_Stop: 9.1.54 */
205 bitvec_set_bit(bv, 1);
206
207 /* No E-UTRAN Measurement Parameters Descr. */
208 bitvec_set_bit(bv, 0);
209 /* No GPRS E-UTRAN Measurement Param. Descr. */
210 bitvec_set_bit(bv, 0);
211
212 /* Note: each of next 3 "repeated" structures might be repeated any
213 (0, 1, 2...) times - we only support 1 and 0 */
214
215 /* Repeated E-UTRAN Neighbour Cells */
216 bitvec_set_bit(bv, 1);
217
Max39999a72017-10-10 16:20:23 +0200218 appended = append_eutran_neib_cell(bv, bts, rem);
219 if (!appended) { /* appending is impossible within current budget: rollback */
220 bv->cur_bit = old;
221 return;
222 }
Max59a1bf32016-04-15 16:04:46 +0200223
224 /* stop bit - end of Repeated E-UTRAN Neighbour Cells sequence: */
225 bitvec_set_bit(bv, 0);
226
227 /* Note: following 2 repeated structs are not supported ATM */
228 /* stop bit - end of Repeated E-UTRAN Not Allowed Cells sequence: */
229 bitvec_set_bit(bv, 0);
230 /* stop bit - end of Repeated E-UTRAN PCID to TA mapping sequence: */
231 bitvec_set_bit(bv, 0);
232
233 /* Priority and E-UTRAN Parameters Description ends here */
234 /* No 3G CSG Description */
235 bitvec_set_bit(bv, 0);
236 /* No E-UTRAN CSG Description */
237 bitvec_set_bit(bv, 0);
238 /* No Additions in Rel-9: */
239 bitvec_set_bit(bv, L);
240}
241
Maxf39d03a2017-05-12 17:00:30 +0200242static inline int f0_helper(int *sc, size_t length, uint8_t *chan_list)
Maxe610e702016-12-19 13:41:48 +0100243{
Maxf39d03a2017-05-12 17:00:30 +0200244 int w[RANGE_ENC_MAX_ARFCNS] = { 0 };
245
246 return range_encode(ARFCN_RANGE_1024, sc, length, w, 0, chan_list);
247}
248
249/* Estimate how many bits it'll take to append single FDD UARFCN */
Max081ceba2017-09-29 14:10:24 +0200250static inline int append_utran_fdd_length(uint16_t u, const int *sc, size_t sc_len, size_t length)
Maxf39d03a2017-05-12 17:00:30 +0200251{
252 uint8_t chan_list[16] = { 0 };
253 int tmp[sc_len], f0;
254
255 memcpy(tmp, sc, sizeof(tmp));
256
257 f0 = f0_helper(tmp, length, chan_list);
258 if (f0 < 0)
259 return f0;
260
261 return 21 + range1024_p(length);
262}
263
264/* Append single FDD UARFCN */
265static inline int append_utran_fdd(struct bitvec *bv, uint16_t u, int *sc, size_t length)
266{
267 uint8_t chan_list[16] = { 0 };
268 int f0 = f0_helper(sc, length, chan_list);
269
270 if (f0 < 0)
271 return f0;
272
Maxe610e702016-12-19 13:41:48 +0100273 /* Repeated UTRAN FDD Neighbour Cells */
274 bitvec_set_bit(bv, 1);
275
276 /* FDD-ARFCN */
277 bitvec_set_bit(bv, 0);
278 bitvec_set_uint(bv, u, 14);
279
Maxe610e702016-12-19 13:41:48 +0100280 /* FDD_Indic0: parameter value '0000000000' is a member of the set? */
281 bitvec_set_bit(bv, f0);
282 /* NR_OF_FDD_CELLS */
283 bitvec_set_uint(bv, length, 5);
284
285 f0 = bv->cur_bit;
286 bitvec_add_range1024(bv, (struct gsm48_range_1024 *)chan_list);
287 bv->cur_bit = f0 + range1024_p(length);
Maxf39d03a2017-05-12 17:00:30 +0200288
289 return 21 + range1024_p(length);
Maxe610e702016-12-19 13:41:48 +0100290}
291
Max081ceba2017-09-29 14:10:24 +0200292static inline int try_adding_uarfcn(struct bitvec *bv, struct gsm_bts *bts, uint16_t uarfcn,
293 uint8_t num_sc, uint8_t start_pos, uint8_t budget)
Max26679e02016-04-20 15:57:13 +0200294{
Max081ceba2017-09-29 14:10:24 +0200295 int i, k, rc, a[bts->si_common.uarfcn_length];
296
297 if (budget < 23)
298 return -ENOMEM;
299
300 /* copy corresponding Scrambling Codes: range encoder make in-place modifications */
301 for (i = start_pos, k = 0; i < num_sc; a[k++] = bts->si_common.data.scramble_list[i++]);
302
303 /* estimate bit length requirements */
304 rc = append_utran_fdd_length(uarfcn, a, bts->si_common.uarfcn_length, k);
305 if (rc < 0)
306 return rc; /* range encoder failure */
307
308 if (budget - rc <= 0)
309 return -ENOMEM; /* we have ran out of budget in current SI2q */
310
311 /* compute next offset */
312 bts->u_offset += k;
313
314 return budget - append_utran_fdd(bv, uarfcn, a, k);
315}
316
317/* Append multiple FDD UARFCNs */
318static inline void append_uarfcns(struct bitvec *bv, struct gsm_bts *bts, uint8_t budget)
319{
320 const uint16_t *u = bts->si_common.data.uarfcn_list;
Max7d73cc72017-10-02 18:37:46 +0200321 int i, rem = budget - 7, st = bts->u_offset; /* account for constant bits right away */
Maxf39d03a2017-05-12 17:00:30 +0200322 uint16_t cu = u[bts->u_offset]; /* caller ensures that length is positive */
Max70fdd242017-06-15 15:10:53 +0200323
324 OSMO_ASSERT(budget <= SI2Q_MAX_LEN);
325
326 if (budget <= 7)
Max081ceba2017-09-29 14:10:24 +0200327 return;
Max26679e02016-04-20 15:57:13 +0200328
329 /* 3G Neighbour Cell Description */
330 bitvec_set_bit(bv, 1);
331 /* No Index_Start_3G */
332 bitvec_set_bit(bv, 0);
333 /* No Absolute_Index_Start_EMR */
334 bitvec_set_bit(bv, 0);
335
336 /* UTRAN FDD Description */
337 bitvec_set_bit(bv, 1);
338 /* No Bandwidth_FDD */
339 bitvec_set_bit(bv, 0);
340
Max081ceba2017-09-29 14:10:24 +0200341 for (i = bts->u_offset; i <= bts->si_common.uarfcn_length; i++)
Maxe610e702016-12-19 13:41:48 +0100342 if (u[i] != cu) { /* we've reached new UARFCN */
Max081ceba2017-09-29 14:10:24 +0200343 rem = try_adding_uarfcn(bv, bts, cu, i, st, rem);
344 if (rem < 0)
345 break;
Maxf39d03a2017-05-12 17:00:30 +0200346
Max081ceba2017-09-29 14:10:24 +0200347 if (i < bts->si_common.uarfcn_length) {
348 cu = u[i];
349 st = i;
350 } else
351 break;
Maxe610e702016-12-19 13:41:48 +0100352 }
Max26679e02016-04-20 15:57:13 +0200353
354 /* stop bit - end of Repeated UTRAN FDD Neighbour Cells */
355 bitvec_set_bit(bv, 0);
356
357 /* UTRAN TDD Description */
358 bitvec_set_bit(bv, 0);
359}
360
Max59a1bf32016-04-15 16:04:46 +0200361/* generate SI2quater rest octets: 3GPP TS 44.018 § 10.5.2.33b */
Maxf39d03a2017-05-12 17:00:30 +0200362int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts)
Max59a1bf32016-04-15 16:04:46 +0200363{
Max881064e2016-12-14 14:51:40 +0100364 int rc;
Max59a1bf32016-04-15 16:04:46 +0200365 struct bitvec bv;
Max70fdd242017-06-15 15:10:53 +0200366
367 if (bts->si2q_count < bts->si2q_index)
368 return -EINVAL;
369
Max59a1bf32016-04-15 16:04:46 +0200370 bv.data = data;
371 bv.data_len = 20;
372 bitvec_zero(&bv);
373
Harald Welteaa70d9d2017-09-30 09:22:30 +0800374 /* BA_IND: Set to '0' as that's what we use for SI2xxx type,
375 * whereas '1' is used for SI5xxx type messages. The point here
376 * is to be able to correlate whether a given MS measurement
377 * report was using the neighbor cells advertised in SI2 or in
378 * SI5, as those two could very well be different */
379 bitvec_set_bit(&bv, 0);
Max59a1bf32016-04-15 16:04:46 +0200380 /* 3G_BA_IND */
381 bitvec_set_bit(&bv, 1);
382 /* MP_CHANGE_MARK */
383 bitvec_set_bit(&bv, 0);
384
Max59a1bf32016-04-15 16:04:46 +0200385 /* SI2quater_INDEX */
Maxf39d03a2017-05-12 17:00:30 +0200386 bitvec_set_uint(&bv, bts->si2q_index, 4);
Max59a1bf32016-04-15 16:04:46 +0200387 /* SI2quater_COUNT */
Maxf39d03a2017-05-12 17:00:30 +0200388 bitvec_set_uint(&bv, bts->si2q_count, 4);
Max59a1bf32016-04-15 16:04:46 +0200389
390 /* No Measurement_Parameters Description */
391 bitvec_set_bit(&bv, 0);
392 /* No GPRS_Real Time Difference Description */
393 bitvec_set_bit(&bv, 0);
394 /* No GPRS_BSIC Description */
395 bitvec_set_bit(&bv, 0);
396 /* No GPRS_REPORT PRIORITY Description */
397 bitvec_set_bit(&bv, 0);
398 /* No GPRS_MEASUREMENT_Parameters Description */
399 bitvec_set_bit(&bv, 0);
400 /* No NC Measurement Parameters */
401 bitvec_set_bit(&bv, 0);
402 /* No extension (length) */
403 bitvec_set_bit(&bv, 0);
404
Max70fdd242017-06-15 15:10:53 +0200405 rc = SI2Q_MAX_LEN - (bv.cur_bit + 3);
Max081ceba2017-09-29 14:10:24 +0200406 if (rc > 0 && bts->si_common.uarfcn_length - bts->u_offset > 0)
407 append_uarfcns(&bv, bts, rc);
408 else /* No 3G Neighbour Cell Description */
Max59a1bf32016-04-15 16:04:46 +0200409 bitvec_set_bit(&bv, 0);
Max59a1bf32016-04-15 16:04:46 +0200410
411 /* No 3G Measurement Parameters Description */
412 bitvec_set_bit(&bv, 0);
413 /* No GPRS_3G_MEASUREMENT Parameters Descr. */
414 bitvec_set_bit(&bv, 0);
415
Max70fdd242017-06-15 15:10:53 +0200416 rc = SI2Q_MAX_LEN - bv.cur_bit;
417 if (rc > 0 && si2q_earfcn_count(&bts->si_common.si2quater_neigh_list) - bts->e_offset > 0)
418 append_earfcn(&bv, bts, rc);
419 else /* No Additions in Rel-5: */
Max59a1bf32016-04-15 16:04:46 +0200420 bitvec_set_bit(&bv, L);
Max59a1bf32016-04-15 16:04:46 +0200421
422 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
423 return bv.data_len;
424}
425
Harald Weltea43f7892009-12-01 18:04:30 +0530426/* Append selection parameters to bitvec */
427static void append_selection_params(struct bitvec *bv,
428 const struct gsm48_si_selection_params *sp)
429{
430 if (sp->present) {
431 bitvec_set_bit(bv, H);
432 bitvec_set_bit(bv, sp->cbq);
433 bitvec_set_uint(bv, sp->cell_resel_off, 6);
434 bitvec_set_uint(bv, sp->temp_offs, 3);
435 bitvec_set_uint(bv, sp->penalty_time, 5);
436 } else
437 bitvec_set_bit(bv, L);
438}
439
440/* Append power offset to bitvec */
441static void append_power_offset(struct bitvec *bv,
442 const struct gsm48_si_power_offset *po)
443{
444 if (po->present) {
445 bitvec_set_bit(bv, H);
446 bitvec_set_uint(bv, po->power_offset, 2);
447 } else
448 bitvec_set_bit(bv, L);
449}
450
451/* Append GPRS indicator to bitvec */
452static void append_gprs_ind(struct bitvec *bv,
453 const struct gsm48_si3_gprs_ind *gi)
454{
455 if (gi->present) {
456 bitvec_set_bit(bv, H);
457 bitvec_set_uint(bv, gi->ra_colour, 3);
458 /* 0 == SI13 in BCCH Norm, 1 == SI13 sent on BCCH Ext */
459 bitvec_set_bit(bv, gi->si13_position);
460 } else
461 bitvec_set_bit(bv, L);
462}
463
464
465/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200466int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3)
Harald Weltea43f7892009-12-01 18:04:30 +0530467{
468 struct bitvec bv;
469
470 memset(&bv, 0, sizeof(bv));
471 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100472 bv.data_len = 4;
Harald Weltea43f7892009-12-01 18:04:30 +0530473
474 /* Optional Selection Parameters */
475 append_selection_params(&bv, &si3->selection_params);
476
477 /* Optional Power Offset */
478 append_power_offset(&bv, &si3->power_offset);
479
480 /* Do we have a SI2ter on the BCCH? */
481 if (si3->si2ter_indicator)
482 bitvec_set_bit(&bv, H);
483 else
484 bitvec_set_bit(&bv, L);
485
486 /* Early Classmark Sending Control */
487 if (si3->early_cm_ctrl)
488 bitvec_set_bit(&bv, H);
489 else
490 bitvec_set_bit(&bv, L);
491
492 /* Do we have a SI Type 9 on the BCCH? */
493 if (si3->scheduling.present) {
494 bitvec_set_bit(&bv, H);
495 bitvec_set_uint(&bv, si3->scheduling.where, 3);
496 } else
497 bitvec_set_bit(&bv, L);
498
499 /* GPRS Indicator */
500 append_gprs_ind(&bv, &si3->gprs_ind);
501
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100502 /* 3G Early Classmark Sending Restriction. If H, then controlled by
Maxf3f35052016-04-15 16:04:44 +0200503 * early_cm_ctrl above */
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100504 if (si3->early_cm_restrict_3g)
505 bitvec_set_bit(&bv, L);
506 else
507 bitvec_set_bit(&bv, H);
Maxf3f35052016-04-15 16:04:44 +0200508
509 if (si3->si2quater_indicator) {
510 bitvec_set_bit(&bv, H); /* indicator struct present */
511 bitvec_set_uint(&bv, 0, 1); /* message is sent on BCCH Norm */
512 }
513
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100514 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
515 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530516}
517
518static int append_lsa_params(struct bitvec *bv,
519 const struct gsm48_lsa_params *lsa_params)
520{
521 /* FIXME */
Holger Hans Peter Freytherae80f922010-04-10 00:05:16 +0200522 return -1;
Harald Weltea43f7892009-12-01 18:04:30 +0530523}
524
525/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100526int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len)
Harald Weltea43f7892009-12-01 18:04:30 +0530527{
528 struct bitvec bv;
529
530 memset(&bv, 0, sizeof(bv));
531 bv.data = data;
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100532 bv.data_len = len;
Harald Weltea43f7892009-12-01 18:04:30 +0530533
534 /* SI4 Rest Octets O */
535 append_selection_params(&bv, &si4->selection_params);
536 append_power_offset(&bv, &si4->power_offset);
537 append_gprs_ind(&bv, &si4->gprs_ind);
538
539 if (0 /* FIXME */) {
540 /* H and SI4 Rest Octets S */
541 bitvec_set_bit(&bv, H);
542
543 /* LSA Parameters */
544 if (si4->lsa_params.present) {
545 bitvec_set_bit(&bv, H);
546 append_lsa_params(&bv, &si4->lsa_params);
547 } else
548 bitvec_set_bit(&bv, L);
549
550 /* Cell Identity */
551 if (1) {
552 bitvec_set_bit(&bv, H);
553 bitvec_set_uint(&bv, si4->cell_id, 16);
554 } else
555 bitvec_set_bit(&bv, L);
556
557 /* LSA ID Information */
558 if (0) {
559 bitvec_set_bit(&bv, H);
560 /* FIXME */
561 } else
562 bitvec_set_bit(&bv, L);
563 } else {
564 /* L and break indicator */
565 bitvec_set_bit(&bv, L);
566 bitvec_set_bit(&bv, si4->break_ind ? H : L);
567 }
568
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100569 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530570}
571
Holger Hans Peter Freyther82dd9832016-05-17 23:20:03 +0200572
573/* GSM 04.18 ETSI TS 101 503 V8.27.0 (2006-05)
574
575<SI6 rest octets> ::=
576{L | H <PCH and NCH info>}
577{L | H <VBS/VGCS options : bit(2)>}
578{ < DTM_support : bit == L > I < DTM_support : bit == H >
579< RAC : bit (8) >
580< MAX_LAPDm : bit (3) > }
581< Band indicator >
582{ L | H < GPRS_MS_TXPWR_MAX_CCH : bit (5) > }
583<implicit spare >;
584*/
585int rest_octets_si6(uint8_t *data, bool is1800_net)
586{
587 struct bitvec bv;
588
589 memset(&bv, 0, sizeof(bv));
590 bv.data = data;
591 bv.data_len = 1;
592
593 /* no PCH/NCH info */
594 bitvec_set_bit(&bv, L);
595 /* no VBS/VGCS options */
596 bitvec_set_bit(&bv, L);
597 /* no DTM_support */
598 bitvec_set_bit(&bv, L);
599 /* band indicator */
600 if (is1800_net)
601 bitvec_set_bit(&bv, L);
602 else
603 bitvec_set_bit(&bv, H);
604 /* no GPRS_MS_TXPWR_MAX_CCH */
605 bitvec_set_bit(&bv, L);
606
607 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
608 return bv.data_len;
609}
610
Harald Weltea43f7892009-12-01 18:04:30 +0530611/* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a:
612 < GPRS Mobile Allocation IE > ::=
613 < HSN : bit (6) >
614 { 0 | 1 < RFL number list : < RFL number list struct > > }
615 { 0 < MA_LENGTH : bit (6) >
616 < MA_BITMAP: bit (val(MA_LENGTH) + 1) >
617 | 1 { 0 | 1 <ARFCN index list : < ARFCN index list struct > > } } ;
618
619 < RFL number list struct > :: =
620 < RFL_NUMBER : bit (4) >
621 { 0 | 1 < RFL number list struct > } ;
622 < ARFCN index list struct > ::=
623 < ARFCN_INDEX : bit(6) >
624 { 0 | 1 < ARFCN index list struct > } ;
625 */
626static int append_gprs_mobile_alloc(struct bitvec *bv)
627{
628 /* Hopping Sequence Number */
629 bitvec_set_uint(bv, 0, 6);
630
631 if (0) {
632 /* We want to use a RFL number list */
633 bitvec_set_bit(bv, 1);
634 /* FIXME: RFL number list */
635 } else
636 bitvec_set_bit(bv, 0);
637
638 if (0) {
639 /* We want to use a MA_BITMAP */
640 bitvec_set_bit(bv, 0);
641 /* FIXME: MA_LENGTH, MA_BITMAP, ... */
642 } else {
643 bitvec_set_bit(bv, 1);
644 if (0) {
645 /* We want to provide an ARFCN index list */
646 bitvec_set_bit(bv, 1);
647 /* FIXME */
648 } else
649 bitvec_set_bit(bv, 0);
650 }
651 return 0;
652}
653
654static int encode_t3192(unsigned int t3192)
655{
Philipp Maier3d6cb332016-12-20 14:23:45 +0100656 /* See also 3GPP TS 44.060
657 Table 12.24.2: GPRS Cell Options information element details */
Harald Weltea43f7892009-12-01 18:04:30 +0530658 if (t3192 == 0)
659 return 3;
660 else if (t3192 <= 80)
661 return 4;
662 else if (t3192 <= 120)
663 return 5;
664 else if (t3192 <= 160)
665 return 6;
666 else if (t3192 <= 200)
667 return 7;
668 else if (t3192 <= 500)
669 return 0;
670 else if (t3192 <= 1000)
671 return 1;
672 else if (t3192 <= 1500)
673 return 2;
674 else
675 return -EINVAL;
676}
677
678static int encode_drx_timer(unsigned int drx)
679{
680 if (drx == 0)
681 return 0;
682 else if (drx == 1)
683 return 1;
684 else if (drx == 2)
685 return 2;
686 else if (drx <= 4)
687 return 3;
688 else if (drx <= 8)
689 return 4;
690 else if (drx <= 16)
691 return 5;
692 else if (drx <= 32)
693 return 6;
694 else if (drx <= 64)
695 return 7;
696 else
697 return -EINVAL;
698}
699
700/* GPRS Cell Options as per TS 04.60 Chapter 12.24
701 < GPRS Cell Options IE > ::=
702 < NMO : bit(2) >
703 < T3168 : bit(3) >
704 < T3192 : bit(3) >
705 < DRX_TIMER_MAX: bit(3) >
706 < ACCESS_BURST_TYPE: bit >
707 < CONTROL_ACK_TYPE : bit >
708 < BS_CV_MAX: bit(4) >
709 { 0 | 1 < PAN_DEC : bit(3) >
710 < PAN_INC : bit(3) >
711 < PAN_MAX : bit(3) >
712 { 0 | 1 < Extension Length : bit(6) >
713 < bit (val(Extension Length) + 1
714 & { < Extension Information > ! { bit ** = <no string> } } ;
715 < Extension Information > ::=
716 { 0 | 1 < EGPRS_PACKET_CHANNEL_REQUEST : bit >
717 < BEP_PERIOD : bit(4) > }
718 < PFC_FEATURE_MODE : bit >
719 < DTM_SUPPORT : bit >
720 <BSS_PAGING_COORDINATION: bit >
721 <spare bit > ** ;
722 */
Harald Weltea4e2d042009-12-20 17:08:22 +0100723static int append_gprs_cell_opt(struct bitvec *bv,
724 const struct gprs_cell_options *gco)
Harald Weltea43f7892009-12-01 18:04:30 +0530725{
726 int t3192, drx_timer_max;
727
728 t3192 = encode_t3192(gco->t3192);
729 if (t3192 < 0)
730 return t3192;
731
732 drx_timer_max = encode_drx_timer(gco->drx_timer_max);
733 if (drx_timer_max < 0)
734 return drx_timer_max;
735
736 bitvec_set_uint(bv, gco->nmo, 2);
Philipp Maier3d6cb332016-12-20 14:23:45 +0100737
738 /* See also 3GPP TS 44.060
739 Table 12.24.2: GPRS Cell Options information element details */
740 bitvec_set_uint(bv, gco->t3168 / 500 - 1, 3);
741
Harald Weltea43f7892009-12-01 18:04:30 +0530742 bitvec_set_uint(bv, t3192, 3);
743 bitvec_set_uint(bv, drx_timer_max, 3);
744 /* ACCESS_BURST_TYPE: Hard-code 8bit */
745 bitvec_set_bit(bv, 0);
Max292ec582016-07-28 11:55:37 +0200746 /* CONTROL_ACK_TYPE: */
747 bitvec_set_bit(bv, gco->ctrl_ack_type_use_block);
Harald Weltea43f7892009-12-01 18:04:30 +0530748 bitvec_set_uint(bv, gco->bs_cv_max, 4);
749
Harald Weltea4b16652010-05-31 12:54:23 +0200750 if (0) {
751 /* hard-code no PAN_{DEC,INC,MAX} */
752 bitvec_set_bit(bv, 0);
753 } else {
754 /* copied from ip.access BSC protocol trace */
755 bitvec_set_bit(bv, 1);
756 bitvec_set_uint(bv, 1, 3); /* DEC */
757 bitvec_set_uint(bv, 1, 3); /* INC */
758 bitvec_set_uint(bv, 15, 3); /* MAX */
759 }
Harald Weltea43f7892009-12-01 18:04:30 +0530760
Harald Welteda0586a2010-04-18 14:49:05 +0200761 if (!gco->ext_info_present) {
762 /* no extension information */
763 bitvec_set_bit(bv, 0);
764 } else {
765 /* extension information */
766 bitvec_set_bit(bv, 1);
767 if (!gco->ext_info.egprs_supported) {
768 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200769 bitvec_set_uint(bv, (1 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200770 /* EGPRS supported in the cell */
771 bitvec_set_bit(bv, 0);
772 } else {
773 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200774 bitvec_set_uint(bv, (1 + 5 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200775 /* EGPRS supported in the cell */
776 bitvec_set_bit(bv, 1);
bhargava350533c2016-07-21 11:14:34 +0530777
Harald Welteda0586a2010-04-18 14:49:05 +0200778 /* 1bit EGPRS PACKET CHANNEL REQUEST */
bhargava350533c2016-07-21 11:14:34 +0530779 if (gco->supports_egprs_11bit_rach == 0) {
780 bitvec_set_bit(bv,
781 gco->ext_info.use_egprs_p_ch_req);
782 } else {
783 bitvec_set_bit(bv, 0);
784 }
785
Harald Welteda0586a2010-04-18 14:49:05 +0200786 /* 4bit BEP PERIOD */
787 bitvec_set_uint(bv, gco->ext_info.bep_period, 4);
788 }
789 bitvec_set_bit(bv, gco->ext_info.pfc_supported);
790 bitvec_set_bit(bv, gco->ext_info.dtm_supported);
791 bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination);
792 }
Harald Weltea43f7892009-12-01 18:04:30 +0530793
794 return 0;
795}
796
797static void append_gprs_pwr_ctrl_pars(struct bitvec *bv,
Harald Weltea4e2d042009-12-20 17:08:22 +0100798 const struct gprs_power_ctrl_pars *pcp)
Harald Weltea43f7892009-12-01 18:04:30 +0530799{
800 bitvec_set_uint(bv, pcp->alpha, 4);
801 bitvec_set_uint(bv, pcp->t_avg_w, 5);
802 bitvec_set_uint(bv, pcp->t_avg_t, 5);
803 bitvec_set_uint(bv, pcp->pc_meas_chan, 1);
804 bitvec_set_uint(bv, pcp->n_avg_i, 4);
805}
806
Harald Welte5fda9082010-04-18 22:41:01 +0200807/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200808int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13)
Harald Weltea43f7892009-12-01 18:04:30 +0530809{
810 struct bitvec bv;
811
812 memset(&bv, 0, sizeof(bv));
813 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100814 bv.data_len = 20;
Harald Weltea43f7892009-12-01 18:04:30 +0530815
816 if (0) {
817 /* No rest octets */
818 bitvec_set_bit(&bv, L);
819 } else {
820 bitvec_set_bit(&bv, H);
821 bitvec_set_uint(&bv, si13->bcch_change_mark, 3);
822 bitvec_set_uint(&bv, si13->si_change_field, 4);
Harald Welte97a282b2010-03-14 15:37:43 +0800823 if (1) {
Harald Weltea43f7892009-12-01 18:04:30 +0530824 bitvec_set_bit(&bv, 0);
825 } else {
826 bitvec_set_bit(&bv, 1);
827 bitvec_set_uint(&bv, si13->bcch_change_mark, 2);
828 append_gprs_mobile_alloc(&bv);
829 }
Max72fbc952017-08-29 13:14:24 +0200830 /* PBCCH not present in cell:
831 it shall never be indicated according to 3GPP TS 44.018 Table 10.5.2.37b.1 */
832 bitvec_set_bit(&bv, 0);
833 bitvec_set_uint(&bv, si13->rac, 8);
834 bitvec_set_bit(&bv, si13->spgc_ccch_sup);
835 bitvec_set_uint(&bv, si13->prio_acc_thr, 3);
836 bitvec_set_uint(&bv, si13->net_ctrl_ord, 2);
837 append_gprs_cell_opt(&bv, &si13->cell_opts);
838 append_gprs_pwr_ctrl_pars(&bv, &si13->pwr_ctrl_pars);
839
Harald Welte5fda9082010-04-18 22:41:01 +0200840 /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */
841 bitvec_set_bit(&bv, H); /* added Release 99 */
842 /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS
843 * was only added in this Release */
844 bitvec_set_bit(&bv, 1);
Harald Weltea43f7892009-12-01 18:04:30 +0530845 }
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100846 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
847 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530848}