blob: 39301e6a51267adcb1439643ed9f4f9c2b3446de [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001/* A hackish minimal BSC (+MSC +HLR) implementation */
2
3/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
Harald Weltef6b7a902008-12-26 00:05:11 +000022#include <unistd.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <stdarg.h>
26#include <time.h>
27#include <string.h>
Harald Weltead384642008-12-26 10:20:07 +000028#include <errno.h>
Harald Welte52b1f982008-12-23 20:25:15 +000029
Holger Freytherb332f612008-12-27 12:46:51 +000030#define _GNU_SOURCE
31#include <getopt.h>
32
Harald Welte255539c2008-12-28 02:26:27 +000033#include <openbsc/db.h>
34#include <openbsc/timer.h>
Harald Welte8470bf22008-12-25 23:28:35 +000035#include <openbsc/gsm_data.h>
Harald Welte255539c2008-12-28 02:26:27 +000036#include <openbsc/gsm_04_08.h>
Harald Weltead384642008-12-26 10:20:07 +000037#include <openbsc/select.h>
Harald Welte8470bf22008-12-25 23:28:35 +000038#include <openbsc/abis_rsl.h>
39#include <openbsc/abis_nm.h>
Harald Welte702d8702008-12-26 20:25:35 +000040#include <openbsc/debug.h>
Holger Freyther5677ae32008-12-27 09:41:03 +000041#include <openbsc/misdn.h>
Harald Welte52b1f982008-12-23 20:25:15 +000042
43/* global pointer to the gsm network data structure */
44static struct gsm_network *gsmnet;
45
Holger Freytherefde7fb2008-12-28 14:14:56 +000046/* MCC and MNC for the Location Area Identifier */
47static int MCC = 1;
48static int MNC = 1;
Holger Freytherbde36102008-12-28 22:51:39 +000049static const char *database_name = "hlr.sqlite3";
Holger Freytherefde7fb2008-12-28 14:14:56 +000050
Holger Freyther07cc8d82008-12-29 06:23:46 +000051/* forward declarations */
Holger Freytherb7193e42008-12-29 17:44:08 +000052static void bsc_hack_update_request(struct gsm_bts *bts,
53 u_int32_t assigned_tmi, int accepted);
Holger Freyther3186bf22008-12-29 06:23:49 +000054static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
55 enum gsm_chreq_reason_t reason);
Holger Freyther88ea8322008-12-29 06:23:52 +000056static void bsc_hack_channel_response(struct gsm_lchan *chan, int acked);
Holger Freytherb7193e42008-12-29 17:44:08 +000057static void bsc_hack_call_state_changed(struct gsm_lchan *chan,
58 enum gsm_call_state new_state);
Holger Freyther07cc8d82008-12-29 06:23:46 +000059
Holger Freytherefde7fb2008-12-28 14:14:56 +000060
Harald Welte52b1f982008-12-23 20:25:15 +000061/* The following definitions are for OM and NM packets that we cannot yet
62 * generate by code but we just pass on */
63
64// BTS Site Manager, SET ATTRIBUTES
65
66/*
67 Object Class: BTS Site Manager
68 Instance 1: FF
69 Instance 2: FF
70 Instance 3: FF
71SET ATTRIBUTES
72 sAbisExternalTime: 2007/09/08 14:36:11
73 omLAPDRelTimer: 30sec
74 shortLAPDIntTimer: 5sec
75 emergencyTimer1: 10 minutes
76 emergencyTimer2: 0 minutes
77*/
78
79unsigned char msg_1[] =
80{
81 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
82 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
83 0x02, 0x00, 0x00
84};
85
86// BTS, SET BTS ATTRIBUTES
87
88/*
89 Object Class: BTS
90 BTS relat. Number: 0
91 Instance 2: FF
92 Instance 3: FF
93SET BTS ATTRIBUTES
94 bsIdentityCode / BSIC:
95 PLMN_colour_code: 7h
96 BS_colour_code: 7h
97 BTS Air Timer T3105: 4 ,unit 10 ms
98 btsIsHopping: FALSE
99 periodCCCHLoadIndication: 255sec
100 thresholdCCCHLoadIndication: 100%
101 cellAllocationNumber: 00h = GSM 900
102 enableInterferenceClass: 00h = Disabled
103 fACCHQual: 6 (FACCH stealing flags minus 1)
104 intaveParameter: 31 SACCH multiframes
105 interferenceLevelBoundaries:
106 Interference Boundary 1: 0Ah
107 Interference Boundary 2: 0Fh
108 Interference Boundary 3: 14h
109 Interference Boundary 4: 19h
110 Interference Boundary 5: 1Eh
111 mSTxPwrMax: 11
112 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
113 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
114 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
115 30=33dBm, 31=32dBm
116 ny1:
117 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
118 powerOutputThresholds:
119 Out Power Fault Threshold: -10 dB
120 Red Out Power Threshold: - 6 dB
121 Excessive Out Power Threshold: 5 dB
122 rACHBusyThreshold: -127 dBm
123 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
124 rfResourceIndicationPeriod: 125 SACCH multiframes
125 T200:
126 SDCCH: 044 in 5 ms
127 FACCH/Full rate: 031 in 5 ms
128 FACCH/Half rate: 041 in 5 ms
129 SACCH with TCH SAPI0: 090 in 10 ms
130 SACCH with SDCCH: 090 in 10 ms
131 SDCCH with SAPI3: 090 in 5 ms
132 SACCH with TCH SAPI3: 135 in 10 ms
133 tSync: 9000 units of 10 msec
134 tTrau: 9000 units of 10 msec
135 enableUmLoopTest: 00h = disabled
136 enableExcessiveDistance: 00h = Disabled
137 excessiveDistance: 64km
138 hoppingMode: 00h = baseband hopping
139 cellType: 00h = Standard Cell
140 BCCH ARFCN / bCCHFrequency: 1
141*/
142
143unsigned char msg_2[] =
144{
145 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
146 0xFF, 0x0C, 0x64, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
147 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
148 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
149 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
150 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
151 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
152};
153
154// Handover Recognition, SET ATTRIBUTES
155
156/*
157Illegal Contents GSM Formatted O&M Msg
158 Object Class: Handover Recognition
159 BTS relat. Number: 0
160 Instance 2: FF
161 Instance 3: FF
162SET ATTRIBUTES
163 enableDelayPowerBudgetHO: 00h = Disabled
164 enableDistanceHO: 00h = Disabled
165 enableInternalInterCellHandover: 00h = Disabled
166 enableInternalIntraCellHandover: 00h = Disabled
167 enablePowerBudgetHO: 00h = Disabled
168 enableRXLEVHO: 00h = Disabled
169 enableRXQUALHO: 00h = Disabled
170 hoAveragingDistance: 8 SACCH multiframes
171 hoAveragingLev:
172 A_LEV_HO: 8 SACCH multiframes
173 W_LEV_HO: 1 SACCH multiframes
174 hoAveragingPowerBudget: 16 SACCH multiframes
175 hoAveragingQual:
176 A_QUAL_HO: 8 SACCH multiframes
177 W_QUAL_HO: 2 SACCH multiframes
178 hoLowerThresholdLevDL: (10 - 110) dBm
179 hoLowerThresholdLevUL: (5 - 110) dBm
180 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
181 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
182 hoThresholdLevDLintra : (20 - 110) dBm
183 hoThresholdLevULintra: (20 - 110) dBm
184 hoThresholdMsRangeMax: 20 km
185 nCell: 06h
186 timerHORequest: 3 ,unit 2 SACCH multiframes
187*/
188
189unsigned char msg_3[] =
190{
191 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
192 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
193 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
194 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
195 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
196 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
197 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
198 0x20, 0xF7, 0x01, 0x3C,
199};
200
201// Power Control, SET ATTRIBUTES
202
203/*
204 Object Class: Power Control
205 BTS relat. Number: 0
206 Instance 2: FF
207 Instance 3: FF
208SET ATTRIBUTES
209 enableMsPowerControl: 00h = Disabled
210 enablePowerControlRLFW: 00h = Disabled
211 pcAveragingLev:
212 A_LEV_PC: 4 SACCH multiframes
213 W_LEV_PC: 1 SACCH multiframes
214 pcAveragingQual:
215 A_QUAL_PC: 4 SACCH multiframes
216 W_QUAL_PC: 2 SACCH multiframes
217 pcLowerThresholdLevDL: 0Fh
218 pcLowerThresholdLevUL: 0Ah
219 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
220 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
221 pcRLFThreshold: 0Ch
222 pcUpperThresholdLevDL: 14h
223 pcUpperThresholdLevUL: 0Fh
224 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
225 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
226 powerConfirm: 2 ,unit 2 SACCH multiframes
227 powerControlInterval: 2 ,unit 2 SACCH multiframes
228 powerIncrStepSize: 02h = 4 dB
229 powerRedStepSize: 01h = 2 dB
230 radioLinkTimeoutBs: 64 SACCH multiframes
231 enableBSPowerControl: 00h = disabled
232*/
233
234unsigned char msg_4[] =
235{
236 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
237 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
238 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
239 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
240};
241
242
243// Transceiver, SET TRX ATTRIBUTES (TRX 0)
244
245/*
246 Object Class: Transceiver
247 BTS relat. Number: 0
248 Tranceiver number: 0
249 Instance 3: FF
250SET TRX ATTRIBUTES
251 aRFCNList (HEX): 0001
252 txPwrMaxReduction: 00h = 0dB
253 radioMeasGran: 254 SACCH multiframes
254 radioMeasRep: 01h = enabled
255 memberOfEmergencyConfig: 01h = TRUE
256 trxArea: 00h = TRX doesn't belong to a concentric cell
257*/
258
259unsigned char msg_6[] =
260{
261 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
262 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
263};
264
265
266static void bootstrap_om(struct gsm_bts *bts)
267{
268 struct gsm_bts_trx *trx = &bts->trx[0];
269
Harald Weltead384642008-12-26 10:20:07 +0000270 fprintf(stdout, "bootstrapping OML\n");
271
Harald Welte52b1f982008-12-23 20:25:15 +0000272 /* stop sending event reports */
273 abis_nm_event_reports(bts, 0);
274
275 /* begin DB transmission */
276 abis_nm_db_transmission(bts, 1);
277
Harald Welte702d8702008-12-26 20:25:35 +0000278 /* end DB transmission */
279 abis_nm_db_transmission(bts, 0);
280
281 /* Reset BTS Site manager resource */
282 abis_nm_reset_resource(bts);
283
284 /* begin DB transmission */
285 abis_nm_db_transmission(bts, 1);
286
Harald Welte52b1f982008-12-23 20:25:15 +0000287 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
288 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
289 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
290 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
291
292 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
293 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
294 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
295
296 /* Use TEI 1 for signalling */
297 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
298 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
299#if 0
300 /* TRX 1 */
301 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
302 /* FIXME: TRX ATTRIBUTE */
303 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
304#endif
305
306 /* SET CHANNEL ATTRIBUTE TS1 */
307 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
308 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
309 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
310
311 /* SET CHANNEL ATTRIBUTE TS2 */
312 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
313 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
314 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
315
316 /* SET CHANNEL ATTRIBUTE TS3 */
317 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
318 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
319 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
320
321 /* SET CHANNEL ATTRIBUTE TS4 */
322 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
323 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
324 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
325
326 /* SET CHANNEL ATTRIBUTE TS5 */
327 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
328 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
329 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
330
331 /* SET CHANNEL ATTRIBUTE TS6 */
332 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
333 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
334 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
335
336 /* SET CHANNEL ATTRIBUTE TS7 */
337 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
338 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
339 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
340
341 /* end DB transmission */
342 abis_nm_db_transmission(bts, 0);
343
344 /* Reset BTS Site manager resource */
345 abis_nm_reset_resource(bts);
346
347 /* restart sending event reports */
348 abis_nm_event_reports(bts, 1);
349}
350
351
352
353struct bcch_info {
354 u_int8_t type;
355 u_int8_t len;
356 const u_int8_t *data;
357};
358
359/*
360SYSTEM INFORMATION TYPE 1
361 Cell channel description
362 Format-ID bit map 0
363 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
364 RACH Control Parameters
365 maximum 7 retransmissions
366 8 slots used to spread transmission
367 cell not barred for access
368 call reestablishment not allowed
369 Access Control Class = 0000
370*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000371static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000372 /* header */0x55, 0x06, 0x19,
373 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
375 /* rach */0xD5, 0x00, 0x00,
376 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000377};
378
379/*
380 SYSTEM INFORMATION TYPE 2
381 Neighbour Cells Description
382 EXT-IND: Carries the complete BA
383 BA-IND = 0
384 Format-ID bit map 0
385 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
386 NCC permitted (NCC) = FF
387 RACH Control Parameters
388 maximum 7 retransmissions
389 8 slots used to spread transmission
390 cell not barred for access
391 call reestablishment not allowed
392 Access Control Class = 0000
393*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000394static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000395 /* header */0x59, 0x06, 0x1A,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 /* ncc */0xFF,
399 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000400};
401
402/*
403SYSTEM INFORMATION TYPE 3
404 Cell identity = 00001 (1h)
405 Location area identification
406 Mobile Country Code (MCC): 001
407 Mobile Network Code (MNC): 01
408 Location Area Code (LAC): 00001 (1h)
409 Control Channel Description
410 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
411 0 blocks reserved for access grant
412 1 channel used for CCCH, with SDCCH
413 5 multiframes period for PAGING REQUEST
414 Time-out T3212 = 0
415 Cell Options BCCH
416 Power control indicator: not set
417 MSs shall not use uplink DTX
418 Radio link timeout = 36
419 Cell Selection Parameters
420 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000421 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000422 Additional Reselect Parameter Indication (ACS) = only SYSTEM INFO 4: The SI rest octets, if present, shall be used to derive the value of PI and possibly C2 parameters
423 Half rate support (NECI): New establishment causes are not supported
424 min.RX signal level for MS = 0
425 RACH Control Parameters
426 maximum 7 retransmissions
427 8 slots used to spread transmission
428 cell not barred for access
429 call reestablishment not allowed
430 Access Control Class = 0000
431 SI 3 Rest Octets
432 Cell Bar Qualify (CBQ): 0
433 Cell Reselect Offset = 0 dB
434 Temporary Offset = 0 dB
435 Penalty Time = 20 s
436 System Information 2ter Indicator (2TI): 0 = not available
437 Early Classmark Sending Control (ECSC): 0 = forbidden
438 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
439*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000440static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000441 /* header */0x49, 0x06, 0x1B,
442 /* cell */0x00, 0x01,
443 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
444 /* desc */0x01, 0x03, 0x00,
445 /* option*/0x28,
446 /* selection*/0x62, 0x00,
447 /* rach */0xD5, 0x00, 0x00,
448 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000449};
450
451/*
452SYSTEM INFORMATION TYPE 4
453 Location area identification
454 Mobile Country Code (MCC): 001
455 Mobile Network Code (MNC): 01
456 Location Area Code (LAC): 00001 (1h)
457 Cell Selection Parameters
458 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
459 max.TX power level MS may use for CCH = 2
460 Additional Reselect Parameter Indication (ACS) = only SYSTEM INFO 4: The SI rest octets, if present, shall be used to derive the value of PI and possibly C2 parameters
461 Half rate support (NECI): New establishment causes are not supported
462 min.RX signal level for MS = 0
463 RACH Control Parameters
464 maximum 7 retransmissions
465 8 slots used to spread transmission
466 cell not barred for access
467 call reestablishment not allowed
468 Access Control Class = 0000
469 Channel Description
470 Type = SDCCH/4[2]
471 Timeslot Number: 0
472 Training Sequence Code: 7h
473 ARFCN: 1
474 SI Rest Octets
475 Cell Bar Qualify (CBQ): 0
476 Cell Reselect Offset = 0 dB
477 Temporary Offset = 0 dB
478 Penalty Time = 20 s
479*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000480static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000481 /* header */0x41, 0x06, 0x1C,
482 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
483 /* sel */0x62, 0x00,
484 /* rach*/0xD5, 0x00, 0x00,
485 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000486 0x2B, 0x2B, 0x2B
487};
488
489/*
490 SYSTEM INFORMATION TYPE 5
491 Neighbour Cells Description
492 EXT-IND: Carries the complete BA
493 BA-IND = 0
494 Format-ID bit map 0
495 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
496*/
497
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000498static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000499 /* header without l2 len*/0x06, 0x1D,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000502};
503
504// SYSTEM INFORMATION TYPE 6
505
506/*
507SACCH FILLING
508 System Info Type: SYSTEM INFORMATION 6
509 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
510
511SYSTEM INFORMATION TYPE 6
512 Cell identity = 00001 (1h)
513 Location area identification
514 Mobile Country Code (MCC): 001
515 Mobile Network Code (MNC): 01
516 Location Area Code (LAC): 00001 (1h)
517 Cell Options SACCH
518 Power control indicator: not set
519 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
520 Radio link timeout = 36
521 NCC permitted (NCC) = FF
522*/
523
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000524static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000525 /* header */0x06, 0x1E,
526 /* cell id*/ 0x00, 0x01,
527 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
528 /* options */ 0x28,
529 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000530};
531
532
533
534static const struct bcch_info bcch_infos[] = {
535 {
536 .type = RSL_SYSTEM_INFO_1,
537 .len = sizeof(si1),
538 .data = si1,
539 }, {
540 .type = RSL_SYSTEM_INFO_2,
541 .len = sizeof(si2),
542 .data = si2,
543 }, {
544 .type = RSL_SYSTEM_INFO_3,
545 .len = sizeof(si3),
546 .data = si3,
547 }, {
548 .type = RSL_SYSTEM_INFO_4,
549 .len = sizeof(si4),
550 .data = si4,
551 },
552};
553
Holger Freyther24287b62008-12-28 16:32:41 +0000554static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
555static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
556static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
557static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000558static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
559static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000560
Harald Welte52b1f982008-12-23 20:25:15 +0000561/* set all system information types */
562static int set_system_infos(struct gsm_bts *bts)
563{
564 int i;
565
566 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
567 rsl_bcch_info(bts, bcch_infos[i].type,
568 bcch_infos[i].data,
569 bcch_infos[i].len);
570 }
571 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
572 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000573
574 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000575}
576
577static void activate_traffic_channels(struct gsm_bts_trx *trx)
578{
579 int i;
580
581 /* channel 0 is CCCH */
582 for (i = 1; i < 8; i++)
583 rsl_chan_activate_tch_f(&trx->ts[i]);
584}
585
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000586/*
587 * Patch the various SYSTEM INFORMATION tables to update
588 * the LAI
589 */
590static void patch_tables(struct gsm_bts *bts)
591{
592 /* covert the raw packet to the struct */
593 struct gsm48_system_information_type_3 *type_3 =
594 (struct gsm48_system_information_type_3*)&si3;
595 struct gsm48_system_information_type_4 *type_4 =
596 (struct gsm48_system_information_type_4*)&si4;
597 struct gsm48_system_information_type_6 *type_6 =
598 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000599 struct gsm48_loc_area_id lai;
600
601 gsm0408_generate_lai(&lai, bts->network->country_code,
602 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000603
604 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000605 type_3->lai = lai;
606 type_4->lai = lai;
607 type_6->lai = lai;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000608}
609
610
Harald Weltead384642008-12-26 10:20:07 +0000611static void bootstrap_rsl(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000612{
Harald Welteb84e2f42008-12-28 23:42:04 +0000613 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000614 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000615 set_system_infos(bts);
616
617 /* FIXME: defer this until the channels are used */
Harald Welte702d8702008-12-26 20:25:35 +0000618 //activate_traffic_channels(&bts->trx[0]);
Harald Welte52b1f982008-12-23 20:25:15 +0000619}
620
Harald Weltead384642008-12-26 10:20:07 +0000621static void mi_cb(int event, struct gsm_bts *bts)
622{
623 switch (event) {
624 case EVT_E1_OML_UP:
625 bootstrap_om(bts);
626 break;
627 case EVT_E1_RSL_UP:
628 bootstrap_rsl(bts);
629 break;
630 default:
631 /* FIXME: deal with TEI or L1 link loss */
632 break;
633 }
634}
635
636static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000637{
638 struct gsm_bts *bts;
639
640 /* initialize our data structures */
Holger Freytherefde7fb2008-12-28 14:14:56 +0000641 gsmnet = gsm_network_init(1, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000642 if (!gsmnet)
643 return -ENOMEM;
Harald Weltef5cbab72008-12-30 18:00:15 +0000644
645 gsmnet->name_short = "25C3";
646 gsmnet->name_long = "25C3 GSM";
Harald Welte52b1f982008-12-23 20:25:15 +0000647 bts = &gsmnet->bts[0];
648 bts->location_area_code = 1;
649 bts->trx[0].arfcn = HARDCODED_ARFCN;
Harald Weltef5cbab72008-12-30 18:00:15 +0000650#if 0
Holger Freytherb7193e42008-12-29 17:44:08 +0000651 gsmnet->update_request = bsc_hack_update_request;
Holger Freyther3186bf22008-12-29 06:23:49 +0000652 gsmnet->channel_allocated = bsc_hack_channel_allocated;
Holger Freyther88ea8322008-12-29 06:23:52 +0000653 gsmnet->channel_response = bsc_hack_channel_response;
Holger Freytherb7193e42008-12-29 17:44:08 +0000654 gsmnet->call_state_changed = bsc_hack_call_state_changed;
Harald Weltef5cbab72008-12-30 18:00:15 +0000655#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000656
Harald Weltead384642008-12-26 10:20:07 +0000657 if (mi_setup(bts, 0, mi_cb) < 0)
658 return -EIO;
659
660 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000661}
Harald Weltef6b7a902008-12-26 00:05:11 +0000662
Holger Freytherb332f612008-12-27 12:46:51 +0000663static void print_usage()
664{
665 printf("Usage: bsc_hack\n");
666}
667
668static void print_help()
669{
670 printf(" Some useful help...\n");
671 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000672 printf(" -s --disable-color\n");
673 printf(" -n --network-code number(MNC) \n");
674 printf(" -c --country-code number (MCC) \n");
Holger Freytherbde36102008-12-28 22:51:39 +0000675 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +0000676 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freythere97f7fb2008-12-31 18:52:11 +0000677 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000678 printf(" -h --help this text\n");
679}
680
681static void handle_options(int argc, char** argv)
682{
683 while (1) {
684 int option_index = 0, c;
685 static struct option long_options[] = {
686 {"help", 0, 0, 'h'},
687 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000688 {"disable-color", 0, 0, 's'},
689 {"network-code", 1, 0, 'n'},
690 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000691 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +0000692 {"authorize-everyone", 0, 0, 'a'},
Holger Freythere97f7fb2008-12-31 18:52:11 +0000693 {"reject-cause", 1, 0, 'r'},
Holger Freytherb332f612008-12-27 12:46:51 +0000694 {0, 0, 0, 0}
695 };
696
Holger Freythere97f7fb2008-12-31 18:52:11 +0000697 c = getopt_long(argc, argv, "hc:n:d:sar:",
Holger Freytherb332f612008-12-27 12:46:51 +0000698 long_options, &option_index);
699 if (c == -1)
700 break;
701
702 switch (c) {
703 case 'h':
704 print_usage();
705 print_help();
706 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000707 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000708 debug_use_color(0);
709 break;
710 case 'd':
711 debug_parse_category_mask(optarg);
712 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000713 case 'n':
714 MNC = atoi(optarg);
715 break;
716 case 'c':
717 MCC = atoi(optarg);
718 break;
Holger Freytherbde36102008-12-28 22:51:39 +0000719 case 'l':
720 database_name = strdup(optarg);
721 break;
Holger Freyther89824fc2008-12-30 16:18:18 +0000722 case 'a':
723 gsm0408_allow_everyone(1);
724 break;
Holger Freythere97f7fb2008-12-31 18:52:11 +0000725 case 'r':
726 gsm0408_set_reject_cause(atoi(optarg));
727 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000728 default:
729 /* ignore */
730 break;
731 }
732 }
733}
734
Harald Welte255539c2008-12-28 02:26:27 +0000735static struct timer_list pag_timer;
736
737/* handles uppercase decimal and hexadecimal */
738static u_int8_t char2bcd(char c)
739{
740 if (c <= '9')
741 return c - '0';
742 else
743 return c - 'A';
744}
745
746static int string_to_mi(u_int8_t *mi, const char *string,
747 u_int8_t type)
748{
749 u_int8_t *cur = mi+3;
750
751 mi[0] = GSM48_IE_MOBILE_ID;
752 //mi[1] = TMSI_LEN;
753 mi[2] = type & GSM_MI_TYPE_MASK;
754
755 if (strlen(string) & 0x01)
756 mi[2] |= char2bcd(*string++) << 4;
757 else
758 mi[2] |= 0xf0;
759
760 while (*string && *(string+1))
761 *cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4);
762
763 mi[1] = cur - mi;
764
765 return cur - mi;
766}
767
Holger Freyther07cc8d82008-12-29 06:23:46 +0000768/*
769 * Stations that registered and that we need to page
770 */
771struct pending_registered_station {
772 struct llist_head entry;
Harald Welte255539c2008-12-28 02:26:27 +0000773
Holger Freyther07cc8d82008-12-29 06:23:46 +0000774 /* the tmsi of the subscriber */
775 u_int32_t tmsi;
776 int last_page_group;
777};
778
779static LLIST_HEAD(pending_stations);
780
781static void pag_timer_cb(void *data);
782static struct timer_list pag_timer = {
783 .cb = pag_timer_cb,
784};
785
786/* page the tmsi and wait for the channel request */
787static void pag_timer_cb(void *data)
Harald Welte255539c2008-12-28 02:26:27 +0000788{
789 struct gsm_bts *bts = &gsmnet->bts[0];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000790 struct pending_registered_station *pending_station;
Harald Welte255539c2008-12-28 02:26:27 +0000791 u_int8_t mi[128];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000792 unsigned int mi_len;
Harald Welte255539c2008-12-28 02:26:27 +0000793
Harald Weltef5cbab72008-12-30 18:00:15 +0000794return 0;
795
Holger Freyther07cc8d82008-12-29 06:23:46 +0000796 if (llist_empty(&pending_stations)) {
797 DEBUGP(DPAG, "pag_timer_cb but no pending mobile stations\n");
Harald Welte255539c2008-12-28 02:26:27 +0000798 return;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000799 }
Harald Welte255539c2008-12-28 02:26:27 +0000800
Holger Freyther07cc8d82008-12-29 06:23:46 +0000801 /* get the station to page */
802 pending_station = (struct pending_registered_station*) pending_stations.next;
803 mi_len = generate_mid_from_tmsi(mi, pending_station->tmsi);
804 rsl_paging_cmd(bts, pending_station->last_page_group, mi_len, mi, RSL_CHANNEED_TCH_F);
Harald Welte255539c2008-12-28 02:26:27 +0000805
Holger Freyther07cc8d82008-12-29 06:23:46 +0000806 /* which group to page next */
807 pending_station->last_page_group = (pending_station->last_page_group+1) % 12;
808 schedule_timer(&pag_timer, 1, 0);
809}
Harald Welte255539c2008-12-28 02:26:27 +0000810
Holger Freyther07cc8d82008-12-29 06:23:46 +0000811/*
812 * initiate the a page command for the given
813 * station and retry until we get a channel request
814 */
815static void station_timer_cb(void *data)
816{
817 DEBUGP(DPAG, "Initiating paging of a channel\n");
818 pag_timer_cb(0);
819}
Harald Welte255539c2008-12-28 02:26:27 +0000820
Holger Freyther07cc8d82008-12-29 06:23:46 +0000821static struct timer_list station_timer = {
822 .cb = station_timer_cb,
823};
824
825/*
826 * schedule work
827 */
Holger Freytherb7193e42008-12-29 17:44:08 +0000828static void bsc_hack_update_request(struct gsm_bts *bts, u_int32_t tmsi, int accepted)
Holger Freyther07cc8d82008-12-29 06:23:46 +0000829{
830 struct pending_registered_station *station =
831 (struct pending_registered_station*)malloc(sizeof(*station));
Holger Freytherb7193e42008-12-29 17:44:08 +0000832
833 /*
834 * Only deal with LOCATION UPDATE REQUEST we have
835 * accepted.
836 */
837 if (!accepted)
838 return;
839
840
Holger Freyther07cc8d82008-12-29 06:23:46 +0000841 station->tmsi = tmsi;
842 station->last_page_group = 0;
843 llist_add_tail(&station->entry, &pending_stations);
844
845 if (!timer_pending(&station_timer))
846 schedule_timer(&station_timer, 1, 0);
Harald Welte255539c2008-12-28 02:26:27 +0000847}
848
Holger Freyther3186bf22008-12-29 06:23:49 +0000849static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
850 enum gsm_chreq_reason_t chreq_reason)
851{
852 struct pending_registered_station *station;
853 if (chreq_reason != GSM_CHREQ_REASON_PAG)
854 return;
855
856 if (llist_empty(&pending_stations)) {
857 DEBUGP(DPAG, "Channel allocated for pag but not waitin for it\n");
858 return;
859 }
860
861 station = (struct pending_registered_station*) pending_stations.next;
862
863 DEBUGP(DPAG, "CHAN RQD due PAG %d on %d for %u\n", chan->type, chan->nr, station->tmsi);
864
865 /* allocate some token in the chan for us */
866 chan->user_data = (void*)station->tmsi;
867 del_timer(&pag_timer);
868}
869
Holger Freyther88ea8322008-12-29 06:23:52 +0000870static void bsc_hack_channel_response(struct gsm_lchan *lchan, int ack)
Holger Freyther24893de2008-12-29 06:23:51 +0000871{
872 struct pending_registered_station *station;
873 if (llist_empty(&pending_stations)) {
Holger Freyther24893de2008-12-29 06:23:51 +0000874 return;
875 }
876
877 station = (struct pending_registered_station*) pending_stations.next;
878 if (station->tmsi != (u_int32_t)lchan->user_data) {
879 DEBUGP(DPAG, "Hmmm the channel is not allocated by the"
880 "station we wanted channel: %u us:%u\n",
881 (u_int32_t)(lchan->user_data), station->tmsi);
882 return;
883 }
884
Holger Freyther88ea8322008-12-29 06:23:52 +0000885 if (ack) {
886 DEBUGP(DPAG, "We have probably paged a channel for tmsi: %u on %d\n",
887 station->tmsi, lchan->nr);
Holger Freyther24893de2008-12-29 06:23:51 +0000888
Holger Freyther88ea8322008-12-29 06:23:52 +0000889 llist_del(&station->entry);
890 free(station);
Holger Freytherabade7a2008-12-29 06:42:15 +0000891
892 /*
893 * start a call
894 */
895 gsm48_cc_tx_setup(lchan);
Holger Freyther88ea8322008-12-29 06:23:52 +0000896 } else {
897 /*
898 * give up and go to the next channel
899 */
900 llist_del(&station->entry);
901 free(station);
902 pag_timer_cb(0);
Holger Freyther24893de2008-12-29 06:23:51 +0000903 }
Holger Freyther24893de2008-12-29 06:23:51 +0000904}
905
Holger Freytherb7193e42008-12-29 17:44:08 +0000906static void bsc_hack_call_state_changed(struct gsm_lchan *lchan,
907 enum gsm_call_state new_state)
Holger Freyther2eafef52008-12-29 06:42:17 +0000908{
909 DEBUGP(DPAG, "Call released jumping to the next...\n");
Holger Freytherb7193e42008-12-29 17:44:08 +0000910
911 /* only handle the transition back to the NULL state */
912 if (new_state != GSM_CSTATE_NULL)
913 return;
914
Holger Freyther2eafef52008-12-29 06:42:17 +0000915 rsl_chan_release(lchan);
916
917 /* next!!! */
918 pag_timer_cb(0);
919}
920
Harald Weltef6b7a902008-12-26 00:05:11 +0000921int main(int argc, char **argv)
922{
Holger Freytherb332f612008-12-27 12:46:51 +0000923 /* parse options */
924 handle_options(argc, argv);
925
Holger Freytherbde36102008-12-28 22:51:39 +0000926 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +0000927 printf("DB: Failed to init database. Please check the option settings.\n");
928 return 1;
929 }
930 printf("DB: Database initialized.\n");
931
932 if (db_prepare()) {
933 printf("DB: Failed to prepare database.\n");
934 return 1;
935 }
936 printf("DB: Database prepared.\n");
937
Harald Weltef6b7a902008-12-26 00:05:11 +0000938 bootstrap_network();
939
940 while (1) {
941 bsc_select_main();
942 }
943}