blob: e409c7290192104488e40141a2a50177b2f29f80 [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 */
52static void bsc_hack_update_request_accepted(struct gsm_bts *bts, u_int32_t assigned_tmi);
53
Holger Freytherefde7fb2008-12-28 14:14:56 +000054
Harald Welte52b1f982008-12-23 20:25:15 +000055/* The following definitions are for OM and NM packets that we cannot yet
56 * generate by code but we just pass on */
57
58// BTS Site Manager, SET ATTRIBUTES
59
60/*
61 Object Class: BTS Site Manager
62 Instance 1: FF
63 Instance 2: FF
64 Instance 3: FF
65SET ATTRIBUTES
66 sAbisExternalTime: 2007/09/08 14:36:11
67 omLAPDRelTimer: 30sec
68 shortLAPDIntTimer: 5sec
69 emergencyTimer1: 10 minutes
70 emergencyTimer2: 0 minutes
71*/
72
73unsigned char msg_1[] =
74{
75 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
76 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
77 0x02, 0x00, 0x00
78};
79
80// BTS, SET BTS ATTRIBUTES
81
82/*
83 Object Class: BTS
84 BTS relat. Number: 0
85 Instance 2: FF
86 Instance 3: FF
87SET BTS ATTRIBUTES
88 bsIdentityCode / BSIC:
89 PLMN_colour_code: 7h
90 BS_colour_code: 7h
91 BTS Air Timer T3105: 4 ,unit 10 ms
92 btsIsHopping: FALSE
93 periodCCCHLoadIndication: 255sec
94 thresholdCCCHLoadIndication: 100%
95 cellAllocationNumber: 00h = GSM 900
96 enableInterferenceClass: 00h = Disabled
97 fACCHQual: 6 (FACCH stealing flags minus 1)
98 intaveParameter: 31 SACCH multiframes
99 interferenceLevelBoundaries:
100 Interference Boundary 1: 0Ah
101 Interference Boundary 2: 0Fh
102 Interference Boundary 3: 14h
103 Interference Boundary 4: 19h
104 Interference Boundary 5: 1Eh
105 mSTxPwrMax: 11
106 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
107 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
108 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
109 30=33dBm, 31=32dBm
110 ny1:
111 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
112 powerOutputThresholds:
113 Out Power Fault Threshold: -10 dB
114 Red Out Power Threshold: - 6 dB
115 Excessive Out Power Threshold: 5 dB
116 rACHBusyThreshold: -127 dBm
117 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
118 rfResourceIndicationPeriod: 125 SACCH multiframes
119 T200:
120 SDCCH: 044 in 5 ms
121 FACCH/Full rate: 031 in 5 ms
122 FACCH/Half rate: 041 in 5 ms
123 SACCH with TCH SAPI0: 090 in 10 ms
124 SACCH with SDCCH: 090 in 10 ms
125 SDCCH with SAPI3: 090 in 5 ms
126 SACCH with TCH SAPI3: 135 in 10 ms
127 tSync: 9000 units of 10 msec
128 tTrau: 9000 units of 10 msec
129 enableUmLoopTest: 00h = disabled
130 enableExcessiveDistance: 00h = Disabled
131 excessiveDistance: 64km
132 hoppingMode: 00h = baseband hopping
133 cellType: 00h = Standard Cell
134 BCCH ARFCN / bCCHFrequency: 1
135*/
136
137unsigned char msg_2[] =
138{
139 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
140 0xFF, 0x0C, 0x64, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
141 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
142 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
143 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
144 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
145 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
146};
147
148// Handover Recognition, SET ATTRIBUTES
149
150/*
151Illegal Contents GSM Formatted O&M Msg
152 Object Class: Handover Recognition
153 BTS relat. Number: 0
154 Instance 2: FF
155 Instance 3: FF
156SET ATTRIBUTES
157 enableDelayPowerBudgetHO: 00h = Disabled
158 enableDistanceHO: 00h = Disabled
159 enableInternalInterCellHandover: 00h = Disabled
160 enableInternalIntraCellHandover: 00h = Disabled
161 enablePowerBudgetHO: 00h = Disabled
162 enableRXLEVHO: 00h = Disabled
163 enableRXQUALHO: 00h = Disabled
164 hoAveragingDistance: 8 SACCH multiframes
165 hoAveragingLev:
166 A_LEV_HO: 8 SACCH multiframes
167 W_LEV_HO: 1 SACCH multiframes
168 hoAveragingPowerBudget: 16 SACCH multiframes
169 hoAveragingQual:
170 A_QUAL_HO: 8 SACCH multiframes
171 W_QUAL_HO: 2 SACCH multiframes
172 hoLowerThresholdLevDL: (10 - 110) dBm
173 hoLowerThresholdLevUL: (5 - 110) dBm
174 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
175 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
176 hoThresholdLevDLintra : (20 - 110) dBm
177 hoThresholdLevULintra: (20 - 110) dBm
178 hoThresholdMsRangeMax: 20 km
179 nCell: 06h
180 timerHORequest: 3 ,unit 2 SACCH multiframes
181*/
182
183unsigned char msg_3[] =
184{
185 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
186 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
187 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
188 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
189 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
190 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
191 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
192 0x20, 0xF7, 0x01, 0x3C,
193};
194
195// Power Control, SET ATTRIBUTES
196
197/*
198 Object Class: Power Control
199 BTS relat. Number: 0
200 Instance 2: FF
201 Instance 3: FF
202SET ATTRIBUTES
203 enableMsPowerControl: 00h = Disabled
204 enablePowerControlRLFW: 00h = Disabled
205 pcAveragingLev:
206 A_LEV_PC: 4 SACCH multiframes
207 W_LEV_PC: 1 SACCH multiframes
208 pcAveragingQual:
209 A_QUAL_PC: 4 SACCH multiframes
210 W_QUAL_PC: 2 SACCH multiframes
211 pcLowerThresholdLevDL: 0Fh
212 pcLowerThresholdLevUL: 0Ah
213 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
214 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
215 pcRLFThreshold: 0Ch
216 pcUpperThresholdLevDL: 14h
217 pcUpperThresholdLevUL: 0Fh
218 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
219 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
220 powerConfirm: 2 ,unit 2 SACCH multiframes
221 powerControlInterval: 2 ,unit 2 SACCH multiframes
222 powerIncrStepSize: 02h = 4 dB
223 powerRedStepSize: 01h = 2 dB
224 radioLinkTimeoutBs: 64 SACCH multiframes
225 enableBSPowerControl: 00h = disabled
226*/
227
228unsigned char msg_4[] =
229{
230 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
231 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
232 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
233 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
234};
235
236
237// Transceiver, SET TRX ATTRIBUTES (TRX 0)
238
239/*
240 Object Class: Transceiver
241 BTS relat. Number: 0
242 Tranceiver number: 0
243 Instance 3: FF
244SET TRX ATTRIBUTES
245 aRFCNList (HEX): 0001
246 txPwrMaxReduction: 00h = 0dB
247 radioMeasGran: 254 SACCH multiframes
248 radioMeasRep: 01h = enabled
249 memberOfEmergencyConfig: 01h = TRUE
250 trxArea: 00h = TRX doesn't belong to a concentric cell
251*/
252
253unsigned char msg_6[] =
254{
255 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
256 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
257};
258
259
260static void bootstrap_om(struct gsm_bts *bts)
261{
262 struct gsm_bts_trx *trx = &bts->trx[0];
263
Harald Weltead384642008-12-26 10:20:07 +0000264 fprintf(stdout, "bootstrapping OML\n");
265
Harald Welte52b1f982008-12-23 20:25:15 +0000266 /* stop sending event reports */
267 abis_nm_event_reports(bts, 0);
268
269 /* begin DB transmission */
270 abis_nm_db_transmission(bts, 1);
271
Harald Welte702d8702008-12-26 20:25:35 +0000272 /* end DB transmission */
273 abis_nm_db_transmission(bts, 0);
274
275 /* Reset BTS Site manager resource */
276 abis_nm_reset_resource(bts);
277
278 /* begin DB transmission */
279 abis_nm_db_transmission(bts, 1);
280
Harald Welte52b1f982008-12-23 20:25:15 +0000281 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
282 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
283 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
284 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
285
286 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
287 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
288 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
289
290 /* Use TEI 1 for signalling */
291 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
292 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
293#if 0
294 /* TRX 1 */
295 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
296 /* FIXME: TRX ATTRIBUTE */
297 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
298#endif
299
300 /* SET CHANNEL ATTRIBUTE TS1 */
301 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
302 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
303 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
304
305 /* SET CHANNEL ATTRIBUTE TS2 */
306 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
307 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
308 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
309
310 /* SET CHANNEL ATTRIBUTE TS3 */
311 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
312 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
313 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
314
315 /* SET CHANNEL ATTRIBUTE TS4 */
316 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
317 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
318 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
319
320 /* SET CHANNEL ATTRIBUTE TS5 */
321 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
322 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
323 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
324
325 /* SET CHANNEL ATTRIBUTE TS6 */
326 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
327 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
328 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
329
330 /* SET CHANNEL ATTRIBUTE TS7 */
331 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
332 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
333 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
334
335 /* end DB transmission */
336 abis_nm_db_transmission(bts, 0);
337
338 /* Reset BTS Site manager resource */
339 abis_nm_reset_resource(bts);
340
341 /* restart sending event reports */
342 abis_nm_event_reports(bts, 1);
343}
344
345
346
347struct bcch_info {
348 u_int8_t type;
349 u_int8_t len;
350 const u_int8_t *data;
351};
352
353/*
354SYSTEM INFORMATION TYPE 1
355 Cell channel description
356 Format-ID bit map 0
357 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
358 RACH Control Parameters
359 maximum 7 retransmissions
360 8 slots used to spread transmission
361 cell not barred for access
362 call reestablishment not allowed
363 Access Control Class = 0000
364*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000365static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000366 /* header */0x55, 0x06, 0x19,
367 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
369 /* rach */0xD5, 0x00, 0x00,
370 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000371};
372
373/*
374 SYSTEM INFORMATION TYPE 2
375 Neighbour Cells Description
376 EXT-IND: Carries the complete BA
377 BA-IND = 0
378 Format-ID bit map 0
379 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
380 NCC permitted (NCC) = FF
381 RACH Control Parameters
382 maximum 7 retransmissions
383 8 slots used to spread transmission
384 cell not barred for access
385 call reestablishment not allowed
386 Access Control Class = 0000
387*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000388static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000389 /* header */0x59, 0x06, 0x1A,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 /* ncc */0xFF,
393 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000394};
395
396/*
397SYSTEM INFORMATION TYPE 3
398 Cell identity = 00001 (1h)
399 Location area identification
400 Mobile Country Code (MCC): 001
401 Mobile Network Code (MNC): 01
402 Location Area Code (LAC): 00001 (1h)
403 Control Channel Description
404 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
405 0 blocks reserved for access grant
406 1 channel used for CCCH, with SDCCH
407 5 multiframes period for PAGING REQUEST
408 Time-out T3212 = 0
409 Cell Options BCCH
410 Power control indicator: not set
411 MSs shall not use uplink DTX
412 Radio link timeout = 36
413 Cell Selection Parameters
414 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000415 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000416 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
417 Half rate support (NECI): New establishment causes are not supported
418 min.RX signal level for MS = 0
419 RACH Control Parameters
420 maximum 7 retransmissions
421 8 slots used to spread transmission
422 cell not barred for access
423 call reestablishment not allowed
424 Access Control Class = 0000
425 SI 3 Rest Octets
426 Cell Bar Qualify (CBQ): 0
427 Cell Reselect Offset = 0 dB
428 Temporary Offset = 0 dB
429 Penalty Time = 20 s
430 System Information 2ter Indicator (2TI): 0 = not available
431 Early Classmark Sending Control (ECSC): 0 = forbidden
432 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
433*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000434static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000435 /* header */0x49, 0x06, 0x1B,
436 /* cell */0x00, 0x01,
437 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
438 /* desc */0x01, 0x03, 0x00,
439 /* option*/0x28,
440 /* selection*/0x62, 0x00,
441 /* rach */0xD5, 0x00, 0x00,
442 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000443};
444
445/*
446SYSTEM INFORMATION TYPE 4
447 Location area identification
448 Mobile Country Code (MCC): 001
449 Mobile Network Code (MNC): 01
450 Location Area Code (LAC): 00001 (1h)
451 Cell Selection Parameters
452 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
453 max.TX power level MS may use for CCH = 2
454 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
455 Half rate support (NECI): New establishment causes are not supported
456 min.RX signal level for MS = 0
457 RACH Control Parameters
458 maximum 7 retransmissions
459 8 slots used to spread transmission
460 cell not barred for access
461 call reestablishment not allowed
462 Access Control Class = 0000
463 Channel Description
464 Type = SDCCH/4[2]
465 Timeslot Number: 0
466 Training Sequence Code: 7h
467 ARFCN: 1
468 SI Rest Octets
469 Cell Bar Qualify (CBQ): 0
470 Cell Reselect Offset = 0 dB
471 Temporary Offset = 0 dB
472 Penalty Time = 20 s
473*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000474static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000475 /* header */0x41, 0x06, 0x1C,
476 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
477 /* sel */0x62, 0x00,
478 /* rach*/0xD5, 0x00, 0x00,
479 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000480 0x2B, 0x2B, 0x2B
481};
482
483/*
484 SYSTEM INFORMATION TYPE 5
485 Neighbour Cells Description
486 EXT-IND: Carries the complete BA
487 BA-IND = 0
488 Format-ID bit map 0
489 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
490*/
491
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000492static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000493 /* header without l2 len*/0x06, 0x1D,
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000496};
497
498// SYSTEM INFORMATION TYPE 6
499
500/*
501SACCH FILLING
502 System Info Type: SYSTEM INFORMATION 6
503 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
504
505SYSTEM INFORMATION TYPE 6
506 Cell identity = 00001 (1h)
507 Location area identification
508 Mobile Country Code (MCC): 001
509 Mobile Network Code (MNC): 01
510 Location Area Code (LAC): 00001 (1h)
511 Cell Options SACCH
512 Power control indicator: not set
513 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
514 Radio link timeout = 36
515 NCC permitted (NCC) = FF
516*/
517
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000518static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000519 /* header */0x06, 0x1E,
520 /* cell id*/ 0x00, 0x01,
521 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
522 /* options */ 0x28,
523 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000524};
525
526
527
528static const struct bcch_info bcch_infos[] = {
529 {
530 .type = RSL_SYSTEM_INFO_1,
531 .len = sizeof(si1),
532 .data = si1,
533 }, {
534 .type = RSL_SYSTEM_INFO_2,
535 .len = sizeof(si2),
536 .data = si2,
537 }, {
538 .type = RSL_SYSTEM_INFO_3,
539 .len = sizeof(si3),
540 .data = si3,
541 }, {
542 .type = RSL_SYSTEM_INFO_4,
543 .len = sizeof(si4),
544 .data = si4,
545 },
546};
547
Holger Freyther24287b62008-12-28 16:32:41 +0000548static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
549static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
550static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
551static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000552static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
553static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000554
Harald Welte52b1f982008-12-23 20:25:15 +0000555/* set all system information types */
556static int set_system_infos(struct gsm_bts *bts)
557{
558 int i;
559
560 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
561 rsl_bcch_info(bts, bcch_infos[i].type,
562 bcch_infos[i].data,
563 bcch_infos[i].len);
564 }
565 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
566 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000567
568 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000569}
570
571static void activate_traffic_channels(struct gsm_bts_trx *trx)
572{
573 int i;
574
575 /* channel 0 is CCCH */
576 for (i = 1; i < 8; i++)
577 rsl_chan_activate_tch_f(&trx->ts[i]);
578}
579
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000580/*
581 * Patch the various SYSTEM INFORMATION tables to update
582 * the LAI
583 */
584static void patch_tables(struct gsm_bts *bts)
585{
586 /* covert the raw packet to the struct */
587 struct gsm48_system_information_type_3 *type_3 =
588 (struct gsm48_system_information_type_3*)&si3;
589 struct gsm48_system_information_type_4 *type_4 =
590 (struct gsm48_system_information_type_4*)&si4;
591 struct gsm48_system_information_type_6 *type_6 =
592 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000593 struct gsm48_loc_area_id lai;
594
595 gsm0408_generate_lai(&lai, bts->network->country_code,
596 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000597
598 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000599 type_3->lai = lai;
600 type_4->lai = lai;
601 type_6->lai = lai;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000602}
603
604
Harald Weltead384642008-12-26 10:20:07 +0000605static void bootstrap_rsl(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000606{
Harald Welteb84e2f42008-12-28 23:42:04 +0000607 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000608 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000609 set_system_infos(bts);
610
611 /* FIXME: defer this until the channels are used */
Harald Welte702d8702008-12-26 20:25:35 +0000612 //activate_traffic_channels(&bts->trx[0]);
Harald Welte52b1f982008-12-23 20:25:15 +0000613}
614
Harald Weltead384642008-12-26 10:20:07 +0000615static void mi_cb(int event, struct gsm_bts *bts)
616{
617 switch (event) {
618 case EVT_E1_OML_UP:
619 bootstrap_om(bts);
620 break;
621 case EVT_E1_RSL_UP:
622 bootstrap_rsl(bts);
623 break;
624 default:
625 /* FIXME: deal with TEI or L1 link loss */
626 break;
627 }
628}
629
630static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000631{
632 struct gsm_bts *bts;
633
634 /* initialize our data structures */
Holger Freytherefde7fb2008-12-28 14:14:56 +0000635 gsmnet = gsm_network_init(1, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000636 if (!gsmnet)
637 return -ENOMEM;
638
Harald Welte52b1f982008-12-23 20:25:15 +0000639 bts = &gsmnet->bts[0];
640 bts->location_area_code = 1;
641 bts->trx[0].arfcn = HARDCODED_ARFCN;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000642 gsmnet->update_request_accepted = bsc_hack_update_request_accepted;
Harald Welte52b1f982008-12-23 20:25:15 +0000643
Harald Weltead384642008-12-26 10:20:07 +0000644 if (mi_setup(bts, 0, mi_cb) < 0)
645 return -EIO;
646
647 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000648}
Harald Weltef6b7a902008-12-26 00:05:11 +0000649
Holger Freytherb332f612008-12-27 12:46:51 +0000650static void print_usage()
651{
652 printf("Usage: bsc_hack\n");
653}
654
655static void print_help()
656{
657 printf(" Some useful help...\n");
658 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000659 printf(" -s --disable-color\n");
660 printf(" -n --network-code number(MNC) \n");
661 printf(" -c --country-code number (MCC) \n");
Holger Freytherbde36102008-12-28 22:51:39 +0000662 printf(" -l --database db-name The database to use\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000663 printf(" -h --help this text\n");
664}
665
666static void handle_options(int argc, char** argv)
667{
668 while (1) {
669 int option_index = 0, c;
670 static struct option long_options[] = {
671 {"help", 0, 0, 'h'},
672 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000673 {"disable-color", 0, 0, 's'},
674 {"network-code", 1, 0, 'n'},
675 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000676 {"database", 1, 0, 'l'},
Holger Freytherb332f612008-12-27 12:46:51 +0000677 {0, 0, 0, 0}
678 };
679
Holger Freyther33a61842008-12-28 16:57:19 +0000680 c = getopt_long(argc, argv, "hc:n:d:s",
Holger Freytherb332f612008-12-27 12:46:51 +0000681 long_options, &option_index);
682 if (c == -1)
683 break;
684
685 switch (c) {
686 case 'h':
687 print_usage();
688 print_help();
689 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000690 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000691 debug_use_color(0);
692 break;
693 case 'd':
694 debug_parse_category_mask(optarg);
695 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000696 case 'n':
697 MNC = atoi(optarg);
698 break;
699 case 'c':
700 MCC = atoi(optarg);
701 break;
Holger Freytherbde36102008-12-28 22:51:39 +0000702 case 'l':
703 database_name = strdup(optarg);
704 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000705 default:
706 /* ignore */
707 break;
708 }
709 }
710}
711
Harald Welte255539c2008-12-28 02:26:27 +0000712static struct timer_list pag_timer;
713
714/* handles uppercase decimal and hexadecimal */
715static u_int8_t char2bcd(char c)
716{
717 if (c <= '9')
718 return c - '0';
719 else
720 return c - 'A';
721}
722
723static int string_to_mi(u_int8_t *mi, const char *string,
724 u_int8_t type)
725{
726 u_int8_t *cur = mi+3;
727
728 mi[0] = GSM48_IE_MOBILE_ID;
729 //mi[1] = TMSI_LEN;
730 mi[2] = type & GSM_MI_TYPE_MASK;
731
732 if (strlen(string) & 0x01)
733 mi[2] |= char2bcd(*string++) << 4;
734 else
735 mi[2] |= 0xf0;
736
737 while (*string && *(string+1))
738 *cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4);
739
740 mi[1] = cur - mi;
741
742 return cur - mi;
743}
744
Holger Freyther07cc8d82008-12-29 06:23:46 +0000745/*
746 * Stations that registered and that we need to page
747 */
748struct pending_registered_station {
749 struct llist_head entry;
Harald Welte255539c2008-12-28 02:26:27 +0000750
Holger Freyther07cc8d82008-12-29 06:23:46 +0000751 /* the tmsi of the subscriber */
752 u_int32_t tmsi;
753 int last_page_group;
754};
755
756static LLIST_HEAD(pending_stations);
757
758static void pag_timer_cb(void *data);
759static struct timer_list pag_timer = {
760 .cb = pag_timer_cb,
761};
762
763/* page the tmsi and wait for the channel request */
764static void pag_timer_cb(void *data)
Harald Welte255539c2008-12-28 02:26:27 +0000765{
766 struct gsm_bts *bts = &gsmnet->bts[0];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000767 struct pending_registered_station *pending_station;
Harald Welte255539c2008-12-28 02:26:27 +0000768 u_int8_t mi[128];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000769 unsigned int mi_len;
Harald Welte255539c2008-12-28 02:26:27 +0000770
Holger Freyther07cc8d82008-12-29 06:23:46 +0000771 if (llist_empty(&pending_stations)) {
772 DEBUGP(DPAG, "pag_timer_cb but no pending mobile stations\n");
Harald Welte255539c2008-12-28 02:26:27 +0000773 return;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000774 }
Harald Welte255539c2008-12-28 02:26:27 +0000775
Holger Freyther07cc8d82008-12-29 06:23:46 +0000776 /* get the station to page */
777 pending_station = (struct pending_registered_station*) pending_stations.next;
778 mi_len = generate_mid_from_tmsi(mi, pending_station->tmsi);
779 rsl_paging_cmd(bts, pending_station->last_page_group, mi_len, mi, RSL_CHANNEED_TCH_F);
Harald Welte255539c2008-12-28 02:26:27 +0000780
Holger Freyther07cc8d82008-12-29 06:23:46 +0000781 /* which group to page next */
782 pending_station->last_page_group = (pending_station->last_page_group+1) % 12;
783 schedule_timer(&pag_timer, 1, 0);
784}
Harald Welte255539c2008-12-28 02:26:27 +0000785
Holger Freyther07cc8d82008-12-29 06:23:46 +0000786/*
787 * initiate the a page command for the given
788 * station and retry until we get a channel request
789 */
790static void station_timer_cb(void *data)
791{
792 DEBUGP(DPAG, "Initiating paging of a channel\n");
793 pag_timer_cb(0);
794}
Harald Welte255539c2008-12-28 02:26:27 +0000795
Holger Freyther07cc8d82008-12-29 06:23:46 +0000796static struct timer_list station_timer = {
797 .cb = station_timer_cb,
798};
799
800/*
801 * schedule work
802 */
803static void bsc_hack_update_request_accepted(struct gsm_bts *bts, u_int32_t tmsi)
804{
805 struct pending_registered_station *station =
806 (struct pending_registered_station*)malloc(sizeof(*station));
807 station->tmsi = tmsi;
808 station->last_page_group = 0;
809 llist_add_tail(&station->entry, &pending_stations);
810
811 if (!timer_pending(&station_timer))
812 schedule_timer(&station_timer, 1, 0);
Harald Welte255539c2008-12-28 02:26:27 +0000813}
814
Harald Weltef6b7a902008-12-26 00:05:11 +0000815int main(int argc, char **argv)
816{
Holger Freytherb332f612008-12-27 12:46:51 +0000817 /* parse options */
818 handle_options(argc, argv);
819
Holger Freytherbde36102008-12-28 22:51:39 +0000820 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +0000821 printf("DB: Failed to init database. Please check the option settings.\n");
822 return 1;
823 }
824 printf("DB: Database initialized.\n");
825
826 if (db_prepare()) {
827 printf("DB: Failed to prepare database.\n");
828 return 1;
829 }
830 printf("DB: Database prepared.\n");
831
Harald Weltef6b7a902008-12-26 00:05:11 +0000832 bootstrap_network();
833
834 while (1) {
835 bsc_select_main();
836 }
837}