blob: 9f2b4c0abab8be770038e5b3d18a525d478bb73b [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
Max4bd710d2017-12-11 12:09:34 +0100464/* Generate SI2ter Rest Octests 3GPP TS 44.018 Table 10.5.2.33a.1 */
465int rest_octets_si2ter(uint8_t *data)
466{
467 struct bitvec bv;
468
469 memset(&bv, 0, sizeof(bv));
470 bv.data = data;
471 bv.data_len = 4;
472
473 /* No SI2ter_MP_CHANGE_MARK */
474 bitvec_set_bit(&bv, L);
475
476 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
477
478 return bv.data_len;
479}
Harald Weltea43f7892009-12-01 18:04:30 +0530480
Max61b0c302017-12-11 12:24:18 +0100481/* Generate SI2bis Rest Octests 3GPP TS 44.018 Table 10.5.2.33.1 */
482int rest_octets_si2bis(uint8_t *data)
483{
484 struct bitvec bv;
485
486 memset(&bv, 0, sizeof(bv));
487 bv.data = data;
488 bv.data_len = 1;
489
490 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
491
492 return bv.data_len;
493}
494
Harald Weltea43f7892009-12-01 18:04:30 +0530495/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200496int rest_octets_si3(uint8_t *data, const struct gsm48_si_ro_info *si3)
Harald Weltea43f7892009-12-01 18:04:30 +0530497{
498 struct bitvec bv;
499
500 memset(&bv, 0, sizeof(bv));
501 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100502 bv.data_len = 4;
Harald Weltea43f7892009-12-01 18:04:30 +0530503
504 /* Optional Selection Parameters */
505 append_selection_params(&bv, &si3->selection_params);
506
507 /* Optional Power Offset */
508 append_power_offset(&bv, &si3->power_offset);
509
510 /* Do we have a SI2ter on the BCCH? */
511 if (si3->si2ter_indicator)
512 bitvec_set_bit(&bv, H);
513 else
514 bitvec_set_bit(&bv, L);
515
516 /* Early Classmark Sending Control */
517 if (si3->early_cm_ctrl)
518 bitvec_set_bit(&bv, H);
519 else
520 bitvec_set_bit(&bv, L);
521
522 /* Do we have a SI Type 9 on the BCCH? */
523 if (si3->scheduling.present) {
524 bitvec_set_bit(&bv, H);
525 bitvec_set_uint(&bv, si3->scheduling.where, 3);
526 } else
527 bitvec_set_bit(&bv, L);
528
529 /* GPRS Indicator */
530 append_gprs_ind(&bv, &si3->gprs_ind);
531
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100532 /* 3G Early Classmark Sending Restriction. If H, then controlled by
Maxf3f35052016-04-15 16:04:44 +0200533 * early_cm_ctrl above */
Pau Espin Pedrole8dda5f2017-11-23 19:06:09 +0100534 if (si3->early_cm_restrict_3g)
535 bitvec_set_bit(&bv, L);
536 else
537 bitvec_set_bit(&bv, H);
Maxf3f35052016-04-15 16:04:44 +0200538
539 if (si3->si2quater_indicator) {
540 bitvec_set_bit(&bv, H); /* indicator struct present */
541 bitvec_set_uint(&bv, 0, 1); /* message is sent on BCCH Norm */
542 }
543
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100544 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
545 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530546}
547
548static int append_lsa_params(struct bitvec *bv,
549 const struct gsm48_lsa_params *lsa_params)
550{
551 /* FIXME */
Holger Hans Peter Freytherae80f922010-04-10 00:05:16 +0200552 return -1;
Harald Weltea43f7892009-12-01 18:04:30 +0530553}
554
555/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100556int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len)
Harald Weltea43f7892009-12-01 18:04:30 +0530557{
558 struct bitvec bv;
559
560 memset(&bv, 0, sizeof(bv));
561 bv.data = data;
Holger Hans Peter Freyther7ff77ec2010-12-29 23:06:22 +0100562 bv.data_len = len;
Harald Weltea43f7892009-12-01 18:04:30 +0530563
564 /* SI4 Rest Octets O */
565 append_selection_params(&bv, &si4->selection_params);
566 append_power_offset(&bv, &si4->power_offset);
567 append_gprs_ind(&bv, &si4->gprs_ind);
568
569 if (0 /* FIXME */) {
570 /* H and SI4 Rest Octets S */
571 bitvec_set_bit(&bv, H);
572
573 /* LSA Parameters */
574 if (si4->lsa_params.present) {
575 bitvec_set_bit(&bv, H);
576 append_lsa_params(&bv, &si4->lsa_params);
577 } else
578 bitvec_set_bit(&bv, L);
579
580 /* Cell Identity */
581 if (1) {
582 bitvec_set_bit(&bv, H);
583 bitvec_set_uint(&bv, si4->cell_id, 16);
584 } else
585 bitvec_set_bit(&bv, L);
586
587 /* LSA ID Information */
588 if (0) {
589 bitvec_set_bit(&bv, H);
590 /* FIXME */
591 } else
592 bitvec_set_bit(&bv, L);
593 } else {
594 /* L and break indicator */
595 bitvec_set_bit(&bv, L);
596 bitvec_set_bit(&bv, si4->break_ind ? H : L);
597 }
598
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100599 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530600}
601
Holger Hans Peter Freyther82dd9832016-05-17 23:20:03 +0200602
603/* GSM 04.18 ETSI TS 101 503 V8.27.0 (2006-05)
604
605<SI6 rest octets> ::=
606{L | H <PCH and NCH info>}
607{L | H <VBS/VGCS options : bit(2)>}
608{ < DTM_support : bit == L > I < DTM_support : bit == H >
609< RAC : bit (8) >
610< MAX_LAPDm : bit (3) > }
611< Band indicator >
612{ L | H < GPRS_MS_TXPWR_MAX_CCH : bit (5) > }
613<implicit spare >;
614*/
615int rest_octets_si6(uint8_t *data, bool is1800_net)
616{
617 struct bitvec bv;
618
619 memset(&bv, 0, sizeof(bv));
620 bv.data = data;
621 bv.data_len = 1;
622
623 /* no PCH/NCH info */
624 bitvec_set_bit(&bv, L);
625 /* no VBS/VGCS options */
626 bitvec_set_bit(&bv, L);
627 /* no DTM_support */
628 bitvec_set_bit(&bv, L);
629 /* band indicator */
630 if (is1800_net)
631 bitvec_set_bit(&bv, L);
632 else
633 bitvec_set_bit(&bv, H);
634 /* no GPRS_MS_TXPWR_MAX_CCH */
635 bitvec_set_bit(&bv, L);
636
637 bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
638 return bv.data_len;
639}
640
Harald Weltea43f7892009-12-01 18:04:30 +0530641/* GPRS Mobile Allocation as per TS 04.60 Chapter 12.10a:
642 < GPRS Mobile Allocation IE > ::=
643 < HSN : bit (6) >
644 { 0 | 1 < RFL number list : < RFL number list struct > > }
645 { 0 < MA_LENGTH : bit (6) >
646 < MA_BITMAP: bit (val(MA_LENGTH) + 1) >
647 | 1 { 0 | 1 <ARFCN index list : < ARFCN index list struct > > } } ;
648
649 < RFL number list struct > :: =
650 < RFL_NUMBER : bit (4) >
651 { 0 | 1 < RFL number list struct > } ;
652 < ARFCN index list struct > ::=
653 < ARFCN_INDEX : bit(6) >
654 { 0 | 1 < ARFCN index list struct > } ;
655 */
656static int append_gprs_mobile_alloc(struct bitvec *bv)
657{
658 /* Hopping Sequence Number */
659 bitvec_set_uint(bv, 0, 6);
660
661 if (0) {
662 /* We want to use a RFL number list */
663 bitvec_set_bit(bv, 1);
664 /* FIXME: RFL number list */
665 } else
666 bitvec_set_bit(bv, 0);
667
668 if (0) {
669 /* We want to use a MA_BITMAP */
670 bitvec_set_bit(bv, 0);
671 /* FIXME: MA_LENGTH, MA_BITMAP, ... */
672 } else {
673 bitvec_set_bit(bv, 1);
674 if (0) {
675 /* We want to provide an ARFCN index list */
676 bitvec_set_bit(bv, 1);
677 /* FIXME */
678 } else
679 bitvec_set_bit(bv, 0);
680 }
681 return 0;
682}
683
684static int encode_t3192(unsigned int t3192)
685{
Philipp Maier3d6cb332016-12-20 14:23:45 +0100686 /* See also 3GPP TS 44.060
687 Table 12.24.2: GPRS Cell Options information element details */
Harald Weltea43f7892009-12-01 18:04:30 +0530688 if (t3192 == 0)
689 return 3;
690 else if (t3192 <= 80)
691 return 4;
692 else if (t3192 <= 120)
693 return 5;
694 else if (t3192 <= 160)
695 return 6;
696 else if (t3192 <= 200)
697 return 7;
698 else if (t3192 <= 500)
699 return 0;
700 else if (t3192 <= 1000)
701 return 1;
702 else if (t3192 <= 1500)
703 return 2;
704 else
705 return -EINVAL;
706}
707
708static int encode_drx_timer(unsigned int drx)
709{
710 if (drx == 0)
711 return 0;
712 else if (drx == 1)
713 return 1;
714 else if (drx == 2)
715 return 2;
716 else if (drx <= 4)
717 return 3;
718 else if (drx <= 8)
719 return 4;
720 else if (drx <= 16)
721 return 5;
722 else if (drx <= 32)
723 return 6;
724 else if (drx <= 64)
725 return 7;
726 else
727 return -EINVAL;
728}
729
730/* GPRS Cell Options as per TS 04.60 Chapter 12.24
731 < GPRS Cell Options IE > ::=
732 < NMO : bit(2) >
733 < T3168 : bit(3) >
734 < T3192 : bit(3) >
735 < DRX_TIMER_MAX: bit(3) >
736 < ACCESS_BURST_TYPE: bit >
737 < CONTROL_ACK_TYPE : bit >
738 < BS_CV_MAX: bit(4) >
739 { 0 | 1 < PAN_DEC : bit(3) >
740 < PAN_INC : bit(3) >
741 < PAN_MAX : bit(3) >
742 { 0 | 1 < Extension Length : bit(6) >
743 < bit (val(Extension Length) + 1
744 & { < Extension Information > ! { bit ** = <no string> } } ;
745 < Extension Information > ::=
746 { 0 | 1 < EGPRS_PACKET_CHANNEL_REQUEST : bit >
747 < BEP_PERIOD : bit(4) > }
748 < PFC_FEATURE_MODE : bit >
749 < DTM_SUPPORT : bit >
750 <BSS_PAGING_COORDINATION: bit >
751 <spare bit > ** ;
752 */
Harald Weltea4e2d042009-12-20 17:08:22 +0100753static int append_gprs_cell_opt(struct bitvec *bv,
754 const struct gprs_cell_options *gco)
Harald Weltea43f7892009-12-01 18:04:30 +0530755{
756 int t3192, drx_timer_max;
757
758 t3192 = encode_t3192(gco->t3192);
759 if (t3192 < 0)
760 return t3192;
761
762 drx_timer_max = encode_drx_timer(gco->drx_timer_max);
763 if (drx_timer_max < 0)
764 return drx_timer_max;
765
766 bitvec_set_uint(bv, gco->nmo, 2);
Philipp Maier3d6cb332016-12-20 14:23:45 +0100767
768 /* See also 3GPP TS 44.060
769 Table 12.24.2: GPRS Cell Options information element details */
770 bitvec_set_uint(bv, gco->t3168 / 500 - 1, 3);
771
Harald Weltea43f7892009-12-01 18:04:30 +0530772 bitvec_set_uint(bv, t3192, 3);
773 bitvec_set_uint(bv, drx_timer_max, 3);
774 /* ACCESS_BURST_TYPE: Hard-code 8bit */
775 bitvec_set_bit(bv, 0);
Max292ec582016-07-28 11:55:37 +0200776 /* CONTROL_ACK_TYPE: */
777 bitvec_set_bit(bv, gco->ctrl_ack_type_use_block);
Harald Weltea43f7892009-12-01 18:04:30 +0530778 bitvec_set_uint(bv, gco->bs_cv_max, 4);
779
Harald Weltea4b16652010-05-31 12:54:23 +0200780 if (0) {
781 /* hard-code no PAN_{DEC,INC,MAX} */
782 bitvec_set_bit(bv, 0);
783 } else {
784 /* copied from ip.access BSC protocol trace */
785 bitvec_set_bit(bv, 1);
786 bitvec_set_uint(bv, 1, 3); /* DEC */
787 bitvec_set_uint(bv, 1, 3); /* INC */
788 bitvec_set_uint(bv, 15, 3); /* MAX */
789 }
Harald Weltea43f7892009-12-01 18:04:30 +0530790
Harald Welteda0586a2010-04-18 14:49:05 +0200791 if (!gco->ext_info_present) {
792 /* no extension information */
793 bitvec_set_bit(bv, 0);
794 } else {
795 /* extension information */
796 bitvec_set_bit(bv, 1);
797 if (!gco->ext_info.egprs_supported) {
798 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200799 bitvec_set_uint(bv, (1 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200800 /* EGPRS supported in the cell */
801 bitvec_set_bit(bv, 0);
802 } else {
803 /* 6bit length of extension */
Harald Welte39608dc2010-04-18 22:47:22 +0200804 bitvec_set_uint(bv, (1 + 5 + 3)-1, 6);
Harald Welteda0586a2010-04-18 14:49:05 +0200805 /* EGPRS supported in the cell */
806 bitvec_set_bit(bv, 1);
bhargava350533c2016-07-21 11:14:34 +0530807
Harald Welteda0586a2010-04-18 14:49:05 +0200808 /* 1bit EGPRS PACKET CHANNEL REQUEST */
bhargava350533c2016-07-21 11:14:34 +0530809 if (gco->supports_egprs_11bit_rach == 0) {
810 bitvec_set_bit(bv,
811 gco->ext_info.use_egprs_p_ch_req);
812 } else {
813 bitvec_set_bit(bv, 0);
814 }
815
Harald Welteda0586a2010-04-18 14:49:05 +0200816 /* 4bit BEP PERIOD */
817 bitvec_set_uint(bv, gco->ext_info.bep_period, 4);
818 }
819 bitvec_set_bit(bv, gco->ext_info.pfc_supported);
820 bitvec_set_bit(bv, gco->ext_info.dtm_supported);
821 bitvec_set_bit(bv, gco->ext_info.bss_paging_coordination);
822 }
Harald Weltea43f7892009-12-01 18:04:30 +0530823
824 return 0;
825}
826
827static void append_gprs_pwr_ctrl_pars(struct bitvec *bv,
Harald Weltea4e2d042009-12-20 17:08:22 +0100828 const struct gprs_power_ctrl_pars *pcp)
Harald Weltea43f7892009-12-01 18:04:30 +0530829{
830 bitvec_set_uint(bv, pcp->alpha, 4);
831 bitvec_set_uint(bv, pcp->t_avg_w, 5);
832 bitvec_set_uint(bv, pcp->t_avg_t, 5);
833 bitvec_set_uint(bv, pcp->pc_meas_chan, 1);
834 bitvec_set_uint(bv, pcp->n_avg_i, 4);
835}
836
Harald Welte5fda9082010-04-18 22:41:01 +0200837/* Generate SI13 Rest Octests (04.08 Chapter 10.5.2.37b) */
Holger Hans Peter Freytherc42ad8b2011-04-18 17:04:00 +0200838int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13)
Harald Weltea43f7892009-12-01 18:04:30 +0530839{
840 struct bitvec bv;
841
842 memset(&bv, 0, sizeof(bv));
843 bv.data = data;
Holger Hans Peter Freyther4cffc452010-01-06 06:44:37 +0100844 bv.data_len = 20;
Harald Weltea43f7892009-12-01 18:04:30 +0530845
846 if (0) {
847 /* No rest octets */
848 bitvec_set_bit(&bv, L);
849 } else {
850 bitvec_set_bit(&bv, H);
851 bitvec_set_uint(&bv, si13->bcch_change_mark, 3);
852 bitvec_set_uint(&bv, si13->si_change_field, 4);
Harald Welte97a282b2010-03-14 15:37:43 +0800853 if (1) {
Harald Weltea43f7892009-12-01 18:04:30 +0530854 bitvec_set_bit(&bv, 0);
855 } else {
856 bitvec_set_bit(&bv, 1);
857 bitvec_set_uint(&bv, si13->bcch_change_mark, 2);
858 append_gprs_mobile_alloc(&bv);
859 }
Max72fbc952017-08-29 13:14:24 +0200860 /* PBCCH not present in cell:
861 it shall never be indicated according to 3GPP TS 44.018 Table 10.5.2.37b.1 */
862 bitvec_set_bit(&bv, 0);
863 bitvec_set_uint(&bv, si13->rac, 8);
864 bitvec_set_bit(&bv, si13->spgc_ccch_sup);
865 bitvec_set_uint(&bv, si13->prio_acc_thr, 3);
866 bitvec_set_uint(&bv, si13->net_ctrl_ord, 2);
867 append_gprs_cell_opt(&bv, &si13->cell_opts);
868 append_gprs_pwr_ctrl_pars(&bv, &si13->pwr_ctrl_pars);
869
Harald Welte5fda9082010-04-18 22:41:01 +0200870 /* 3GPP TS 44.018 Release 6 / 10.5.2.37b */
871 bitvec_set_bit(&bv, H); /* added Release 99 */
872 /* claim our SGSN is compatible with Release 99, as EDGE and EGPRS
873 * was only added in this Release */
874 bitvec_set_bit(&bv, 1);
Harald Weltea43f7892009-12-01 18:04:30 +0530875 }
Holger Hans Peter Freythercaa14862010-01-06 07:49:58 +0100876 bitvec_spare_padding(&bv, (bv.data_len*8)-1);
877 return bv.data_len;
Harald Weltea43f7892009-12-01 18:04:30 +0530878}