blob: c59024a9029d51471cc55e98fee07659c496e2f0 [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 Welted1252502009-01-01 01:50:32 +000029#include <signal.h>
Holger Freyther9a3ee0f2009-01-02 00:40:15 +000030#include <fcntl.h>
31#include <sys/stat.h>
Harald Welte52b1f982008-12-23 20:25:15 +000032
Holger Freytherb332f612008-12-27 12:46:51 +000033#define _GNU_SOURCE
34#include <getopt.h>
35
Harald Welte255539c2008-12-28 02:26:27 +000036#include <openbsc/db.h>
37#include <openbsc/timer.h>
Harald Welte8470bf22008-12-25 23:28:35 +000038#include <openbsc/gsm_data.h>
Harald Welte255539c2008-12-28 02:26:27 +000039#include <openbsc/gsm_04_08.h>
Harald Weltead384642008-12-26 10:20:07 +000040#include <openbsc/select.h>
Harald Welte8470bf22008-12-25 23:28:35 +000041#include <openbsc/abis_rsl.h>
42#include <openbsc/abis_nm.h>
Harald Welte702d8702008-12-26 20:25:35 +000043#include <openbsc/debug.h>
Holger Freyther5677ae32008-12-27 09:41:03 +000044#include <openbsc/misdn.h>
Harald Welte52b1f982008-12-23 20:25:15 +000045
46/* global pointer to the gsm network data structure */
47static struct gsm_network *gsmnet;
48
Holger Freytherefde7fb2008-12-28 14:14:56 +000049/* MCC and MNC for the Location Area Identifier */
50static int MCC = 1;
51static int MNC = 1;
Holger Freytherbde36102008-12-28 22:51:39 +000052static const char *database_name = "hlr.sqlite3";
Holger Freytherefde7fb2008-12-28 14:14:56 +000053
Holger Freyther07cc8d82008-12-29 06:23:46 +000054/* forward declarations */
Holger Freytherb7193e42008-12-29 17:44:08 +000055static void bsc_hack_update_request(struct gsm_bts *bts,
56 u_int32_t assigned_tmi, int accepted);
Holger Freyther3186bf22008-12-29 06:23:49 +000057static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
58 enum gsm_chreq_reason_t reason);
Holger Freyther88ea8322008-12-29 06:23:52 +000059static void bsc_hack_channel_response(struct gsm_lchan *chan, int acked);
Holger Freytherb7193e42008-12-29 17:44:08 +000060static void bsc_hack_call_state_changed(struct gsm_lchan *chan,
61 enum gsm_call_state new_state);
Holger Freyther07cc8d82008-12-29 06:23:46 +000062
Holger Freytherefde7fb2008-12-28 14:14:56 +000063
Harald Welte52b1f982008-12-23 20:25:15 +000064/* The following definitions are for OM and NM packets that we cannot yet
65 * generate by code but we just pass on */
66
67// BTS Site Manager, SET ATTRIBUTES
68
69/*
70 Object Class: BTS Site Manager
71 Instance 1: FF
72 Instance 2: FF
73 Instance 3: FF
74SET ATTRIBUTES
75 sAbisExternalTime: 2007/09/08 14:36:11
76 omLAPDRelTimer: 30sec
77 shortLAPDIntTimer: 5sec
78 emergencyTimer1: 10 minutes
79 emergencyTimer2: 0 minutes
80*/
81
82unsigned char msg_1[] =
83{
84 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
85 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
86 0x02, 0x00, 0x00
87};
88
89// BTS, SET BTS ATTRIBUTES
90
91/*
92 Object Class: BTS
93 BTS relat. Number: 0
94 Instance 2: FF
95 Instance 3: FF
96SET BTS ATTRIBUTES
97 bsIdentityCode / BSIC:
98 PLMN_colour_code: 7h
99 BS_colour_code: 7h
100 BTS Air Timer T3105: 4 ,unit 10 ms
101 btsIsHopping: FALSE
102 periodCCCHLoadIndication: 255sec
103 thresholdCCCHLoadIndication: 100%
104 cellAllocationNumber: 00h = GSM 900
105 enableInterferenceClass: 00h = Disabled
106 fACCHQual: 6 (FACCH stealing flags minus 1)
107 intaveParameter: 31 SACCH multiframes
108 interferenceLevelBoundaries:
109 Interference Boundary 1: 0Ah
110 Interference Boundary 2: 0Fh
111 Interference Boundary 3: 14h
112 Interference Boundary 4: 19h
113 Interference Boundary 5: 1Eh
114 mSTxPwrMax: 11
115 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
116 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
117 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
118 30=33dBm, 31=32dBm
119 ny1:
120 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
121 powerOutputThresholds:
122 Out Power Fault Threshold: -10 dB
123 Red Out Power Threshold: - 6 dB
124 Excessive Out Power Threshold: 5 dB
125 rACHBusyThreshold: -127 dBm
126 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
127 rfResourceIndicationPeriod: 125 SACCH multiframes
128 T200:
129 SDCCH: 044 in 5 ms
130 FACCH/Full rate: 031 in 5 ms
131 FACCH/Half rate: 041 in 5 ms
132 SACCH with TCH SAPI0: 090 in 10 ms
133 SACCH with SDCCH: 090 in 10 ms
134 SDCCH with SAPI3: 090 in 5 ms
135 SACCH with TCH SAPI3: 135 in 10 ms
136 tSync: 9000 units of 10 msec
137 tTrau: 9000 units of 10 msec
138 enableUmLoopTest: 00h = disabled
139 enableExcessiveDistance: 00h = Disabled
140 excessiveDistance: 64km
141 hoppingMode: 00h = baseband hopping
142 cellType: 00h = Standard Cell
143 BCCH ARFCN / bCCHFrequency: 1
144*/
145
146unsigned char msg_2[] =
147{
148 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
149 0xFF, 0x0C, 0x64, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
150 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
151 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
152 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
153 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
154 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
155};
156
157// Handover Recognition, SET ATTRIBUTES
158
159/*
160Illegal Contents GSM Formatted O&M Msg
161 Object Class: Handover Recognition
162 BTS relat. Number: 0
163 Instance 2: FF
164 Instance 3: FF
165SET ATTRIBUTES
166 enableDelayPowerBudgetHO: 00h = Disabled
167 enableDistanceHO: 00h = Disabled
168 enableInternalInterCellHandover: 00h = Disabled
169 enableInternalIntraCellHandover: 00h = Disabled
170 enablePowerBudgetHO: 00h = Disabled
171 enableRXLEVHO: 00h = Disabled
172 enableRXQUALHO: 00h = Disabled
173 hoAveragingDistance: 8 SACCH multiframes
174 hoAveragingLev:
175 A_LEV_HO: 8 SACCH multiframes
176 W_LEV_HO: 1 SACCH multiframes
177 hoAveragingPowerBudget: 16 SACCH multiframes
178 hoAveragingQual:
179 A_QUAL_HO: 8 SACCH multiframes
180 W_QUAL_HO: 2 SACCH multiframes
181 hoLowerThresholdLevDL: (10 - 110) dBm
182 hoLowerThresholdLevUL: (5 - 110) dBm
183 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
184 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
185 hoThresholdLevDLintra : (20 - 110) dBm
186 hoThresholdLevULintra: (20 - 110) dBm
187 hoThresholdMsRangeMax: 20 km
188 nCell: 06h
189 timerHORequest: 3 ,unit 2 SACCH multiframes
190*/
191
192unsigned char msg_3[] =
193{
194 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
195 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
196 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
197 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
198 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
199 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
200 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
201 0x20, 0xF7, 0x01, 0x3C,
202};
203
204// Power Control, SET ATTRIBUTES
205
206/*
207 Object Class: Power Control
208 BTS relat. Number: 0
209 Instance 2: FF
210 Instance 3: FF
211SET ATTRIBUTES
212 enableMsPowerControl: 00h = Disabled
213 enablePowerControlRLFW: 00h = Disabled
214 pcAveragingLev:
215 A_LEV_PC: 4 SACCH multiframes
216 W_LEV_PC: 1 SACCH multiframes
217 pcAveragingQual:
218 A_QUAL_PC: 4 SACCH multiframes
219 W_QUAL_PC: 2 SACCH multiframes
220 pcLowerThresholdLevDL: 0Fh
221 pcLowerThresholdLevUL: 0Ah
222 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
223 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
224 pcRLFThreshold: 0Ch
225 pcUpperThresholdLevDL: 14h
226 pcUpperThresholdLevUL: 0Fh
227 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
228 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
229 powerConfirm: 2 ,unit 2 SACCH multiframes
230 powerControlInterval: 2 ,unit 2 SACCH multiframes
231 powerIncrStepSize: 02h = 4 dB
232 powerRedStepSize: 01h = 2 dB
233 radioLinkTimeoutBs: 64 SACCH multiframes
234 enableBSPowerControl: 00h = disabled
235*/
236
237unsigned char msg_4[] =
238{
239 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
240 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
241 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
242 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
243};
244
245
246// Transceiver, SET TRX ATTRIBUTES (TRX 0)
247
248/*
249 Object Class: Transceiver
250 BTS relat. Number: 0
251 Tranceiver number: 0
252 Instance 3: FF
253SET TRX ATTRIBUTES
254 aRFCNList (HEX): 0001
255 txPwrMaxReduction: 00h = 0dB
256 radioMeasGran: 254 SACCH multiframes
257 radioMeasRep: 01h = enabled
258 memberOfEmergencyConfig: 01h = TRUE
259 trxArea: 00h = TRX doesn't belong to a concentric cell
260*/
261
262unsigned char msg_6[] =
263{
264 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
265 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
266};
267
268
269static void bootstrap_om(struct gsm_bts *bts)
270{
271 struct gsm_bts_trx *trx = &bts->trx[0];
272
Harald Weltead384642008-12-26 10:20:07 +0000273 fprintf(stdout, "bootstrapping OML\n");
274
Harald Welte52b1f982008-12-23 20:25:15 +0000275 /* stop sending event reports */
276 abis_nm_event_reports(bts, 0);
277
278 /* begin DB transmission */
279 abis_nm_db_transmission(bts, 1);
280
Harald Welte702d8702008-12-26 20:25:35 +0000281 /* end DB transmission */
282 abis_nm_db_transmission(bts, 0);
283
284 /* Reset BTS Site manager resource */
285 abis_nm_reset_resource(bts);
286
287 /* begin DB transmission */
288 abis_nm_db_transmission(bts, 1);
289
Harald Welte52b1f982008-12-23 20:25:15 +0000290 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
291 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
292 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
293 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
294
295 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
296 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
297 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
298
299 /* Use TEI 1 for signalling */
300 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
301 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
302#if 0
303 /* TRX 1 */
304 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
305 /* FIXME: TRX ATTRIBUTE */
306 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
307#endif
308
309 /* SET CHANNEL ATTRIBUTE TS1 */
310 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
311 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
312 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
313
314 /* SET CHANNEL ATTRIBUTE TS2 */
315 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
316 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
317 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
318
319 /* SET CHANNEL ATTRIBUTE TS3 */
320 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
321 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
322 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
323
324 /* SET CHANNEL ATTRIBUTE TS4 */
325 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
326 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
327 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
328
329 /* SET CHANNEL ATTRIBUTE TS5 */
330 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
331 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
332 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
333
334 /* SET CHANNEL ATTRIBUTE TS6 */
335 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
336 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
337 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
338
339 /* SET CHANNEL ATTRIBUTE TS7 */
340 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
341 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
342 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
343
344 /* end DB transmission */
345 abis_nm_db_transmission(bts, 0);
346
347 /* Reset BTS Site manager resource */
348 abis_nm_reset_resource(bts);
349
350 /* restart sending event reports */
351 abis_nm_event_reports(bts, 1);
352}
353
Harald Welted1252502009-01-01 01:50:32 +0000354static int shutdown_om(struct gsm_bts *bts)
355{
356 /* stop sending event reports */
357 abis_nm_event_reports(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000358
Harald Welted1252502009-01-01 01:50:32 +0000359 /* begin DB transmission */
360 abis_nm_db_transmission(bts, 1);
361
362 /* end DB transmission */
363 abis_nm_db_transmission(bts, 0);
364
365 /* Reset BTS Site manager resource */
366 abis_nm_reset_resource(bts);
367
368 return 0;
369}
370
371static int shutdown_net(struct gsm_network *net)
372{
373 int i;
374 for (i = 0; i < net->num_bts; i++) {
375 int rc;
376 rc = shutdown_om(&net->bts[i]);
377 if (rc < 0)
378 return rc;
379 }
380
381 return 0;
382}
Harald Welte52b1f982008-12-23 20:25:15 +0000383
384struct bcch_info {
385 u_int8_t type;
386 u_int8_t len;
387 const u_int8_t *data;
388};
389
390/*
391SYSTEM INFORMATION TYPE 1
392 Cell channel description
393 Format-ID bit map 0
394 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
395 RACH Control Parameters
396 maximum 7 retransmissions
397 8 slots used to spread transmission
398 cell not barred for access
399 call reestablishment not allowed
400 Access Control Class = 0000
401*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000402static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000403 /* header */0x55, 0x06, 0x19,
404 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
406 /* rach */0xD5, 0x00, 0x00,
407 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000408};
409
410/*
411 SYSTEM INFORMATION TYPE 2
412 Neighbour Cells Description
413 EXT-IND: Carries the complete BA
414 BA-IND = 0
415 Format-ID bit map 0
416 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
417 NCC permitted (NCC) = FF
418 RACH Control Parameters
419 maximum 7 retransmissions
420 8 slots used to spread transmission
421 cell not barred for access
422 call reestablishment not allowed
423 Access Control Class = 0000
424*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000425static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000426 /* header */0x59, 0x06, 0x1A,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 /* ncc */0xFF,
430 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000431};
432
433/*
434SYSTEM INFORMATION TYPE 3
435 Cell identity = 00001 (1h)
436 Location area identification
437 Mobile Country Code (MCC): 001
438 Mobile Network Code (MNC): 01
439 Location Area Code (LAC): 00001 (1h)
440 Control Channel Description
441 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
442 0 blocks reserved for access grant
443 1 channel used for CCCH, with SDCCH
444 5 multiframes period for PAGING REQUEST
445 Time-out T3212 = 0
446 Cell Options BCCH
447 Power control indicator: not set
448 MSs shall not use uplink DTX
449 Radio link timeout = 36
450 Cell Selection Parameters
451 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000452 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000453 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
454 Half rate support (NECI): New establishment causes are not supported
455 min.RX signal level for MS = 0
456 RACH Control Parameters
457 maximum 7 retransmissions
458 8 slots used to spread transmission
459 cell not barred for access
460 call reestablishment not allowed
461 Access Control Class = 0000
462 SI 3 Rest Octets
463 Cell Bar Qualify (CBQ): 0
464 Cell Reselect Offset = 0 dB
465 Temporary Offset = 0 dB
466 Penalty Time = 20 s
467 System Information 2ter Indicator (2TI): 0 = not available
468 Early Classmark Sending Control (ECSC): 0 = forbidden
469 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
470*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000471static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000472 /* header */0x49, 0x06, 0x1B,
473 /* cell */0x00, 0x01,
474 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
475 /* desc */0x01, 0x03, 0x00,
476 /* option*/0x28,
477 /* selection*/0x62, 0x00,
478 /* rach */0xD5, 0x00, 0x00,
479 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000480};
481
482/*
483SYSTEM INFORMATION TYPE 4
484 Location area identification
485 Mobile Country Code (MCC): 001
486 Mobile Network Code (MNC): 01
487 Location Area Code (LAC): 00001 (1h)
488 Cell Selection Parameters
489 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
490 max.TX power level MS may use for CCH = 2
491 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
492 Half rate support (NECI): New establishment causes are not supported
493 min.RX signal level for MS = 0
494 RACH Control Parameters
495 maximum 7 retransmissions
496 8 slots used to spread transmission
497 cell not barred for access
498 call reestablishment not allowed
499 Access Control Class = 0000
500 Channel Description
501 Type = SDCCH/4[2]
502 Timeslot Number: 0
503 Training Sequence Code: 7h
504 ARFCN: 1
505 SI Rest Octets
506 Cell Bar Qualify (CBQ): 0
507 Cell Reselect Offset = 0 dB
508 Temporary Offset = 0 dB
509 Penalty Time = 20 s
510*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000511static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000512 /* header */0x41, 0x06, 0x1C,
513 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
514 /* sel */0x62, 0x00,
515 /* rach*/0xD5, 0x00, 0x00,
516 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000517 0x2B, 0x2B, 0x2B
518};
519
520/*
521 SYSTEM INFORMATION TYPE 5
522 Neighbour Cells Description
523 EXT-IND: Carries the complete BA
524 BA-IND = 0
525 Format-ID bit map 0
526 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
527*/
528
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000529static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000530 /* header without l2 len*/0x06, 0x1D,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000533};
534
535// SYSTEM INFORMATION TYPE 6
536
537/*
538SACCH FILLING
539 System Info Type: SYSTEM INFORMATION 6
540 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
541
542SYSTEM INFORMATION TYPE 6
543 Cell identity = 00001 (1h)
544 Location area identification
545 Mobile Country Code (MCC): 001
546 Mobile Network Code (MNC): 01
547 Location Area Code (LAC): 00001 (1h)
548 Cell Options SACCH
549 Power control indicator: not set
550 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
551 Radio link timeout = 36
552 NCC permitted (NCC) = FF
553*/
554
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000555static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000556 /* header */0x06, 0x1E,
557 /* cell id*/ 0x00, 0x01,
558 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
559 /* options */ 0x28,
560 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000561};
562
563
564
565static const struct bcch_info bcch_infos[] = {
566 {
567 .type = RSL_SYSTEM_INFO_1,
568 .len = sizeof(si1),
569 .data = si1,
570 }, {
571 .type = RSL_SYSTEM_INFO_2,
572 .len = sizeof(si2),
573 .data = si2,
574 }, {
575 .type = RSL_SYSTEM_INFO_3,
576 .len = sizeof(si3),
577 .data = si3,
578 }, {
579 .type = RSL_SYSTEM_INFO_4,
580 .len = sizeof(si4),
581 .data = si4,
582 },
583};
584
Holger Freyther24287b62008-12-28 16:32:41 +0000585static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
586static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
587static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
588static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000589static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
590static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000591
Harald Welte52b1f982008-12-23 20:25:15 +0000592/* set all system information types */
593static int set_system_infos(struct gsm_bts *bts)
594{
595 int i;
596
597 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
598 rsl_bcch_info(bts, bcch_infos[i].type,
599 bcch_infos[i].data,
600 bcch_infos[i].len);
601 }
602 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
603 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000604
605 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000606}
607
608static void activate_traffic_channels(struct gsm_bts_trx *trx)
609{
610 int i;
611
612 /* channel 0 is CCCH */
613 for (i = 1; i < 8; i++)
614 rsl_chan_activate_tch_f(&trx->ts[i]);
615}
616
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000617/*
618 * Patch the various SYSTEM INFORMATION tables to update
619 * the LAI
620 */
621static void patch_tables(struct gsm_bts *bts)
622{
623 /* covert the raw packet to the struct */
624 struct gsm48_system_information_type_3 *type_3 =
625 (struct gsm48_system_information_type_3*)&si3;
626 struct gsm48_system_information_type_4 *type_4 =
627 (struct gsm48_system_information_type_4*)&si4;
628 struct gsm48_system_information_type_6 *type_6 =
629 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000630 struct gsm48_loc_area_id lai;
631
632 gsm0408_generate_lai(&lai, bts->network->country_code,
633 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000634
635 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000636 type_3->lai = lai;
637 type_4->lai = lai;
638 type_6->lai = lai;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000639}
640
641
Harald Weltead384642008-12-26 10:20:07 +0000642static void bootstrap_rsl(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000643{
Harald Welteb84e2f42008-12-28 23:42:04 +0000644 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000645 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000646 set_system_infos(bts);
647
648 /* FIXME: defer this until the channels are used */
Harald Welte702d8702008-12-26 20:25:35 +0000649 //activate_traffic_channels(&bts->trx[0]);
Harald Welte52b1f982008-12-23 20:25:15 +0000650}
651
Harald Weltead384642008-12-26 10:20:07 +0000652static void mi_cb(int event, struct gsm_bts *bts)
653{
654 switch (event) {
655 case EVT_E1_OML_UP:
656 bootstrap_om(bts);
657 break;
658 case EVT_E1_RSL_UP:
659 bootstrap_rsl(bts);
660 break;
661 default:
662 /* FIXME: deal with TEI or L1 link loss */
663 break;
664 }
665}
666
667static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000668{
669 struct gsm_bts *bts;
670
671 /* initialize our data structures */
Holger Freytherefde7fb2008-12-28 14:14:56 +0000672 gsmnet = gsm_network_init(1, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000673 if (!gsmnet)
674 return -ENOMEM;
Harald Weltef5cbab72008-12-30 18:00:15 +0000675
676 gsmnet->name_short = "25C3";
677 gsmnet->name_long = "25C3 GSM";
Harald Welte52b1f982008-12-23 20:25:15 +0000678 bts = &gsmnet->bts[0];
679 bts->location_area_code = 1;
680 bts->trx[0].arfcn = HARDCODED_ARFCN;
Harald Weltef5cbab72008-12-30 18:00:15 +0000681#if 0
Holger Freytherb7193e42008-12-29 17:44:08 +0000682 gsmnet->update_request = bsc_hack_update_request;
Holger Freyther3186bf22008-12-29 06:23:49 +0000683 gsmnet->channel_allocated = bsc_hack_channel_allocated;
Holger Freyther88ea8322008-12-29 06:23:52 +0000684 gsmnet->channel_response = bsc_hack_channel_response;
Holger Freytherb7193e42008-12-29 17:44:08 +0000685 gsmnet->call_state_changed = bsc_hack_call_state_changed;
Harald Weltef5cbab72008-12-30 18:00:15 +0000686#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000687
Harald Weltead384642008-12-26 10:20:07 +0000688 if (mi_setup(bts, 0, mi_cb) < 0)
689 return -EIO;
690
691 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000692}
Harald Weltef6b7a902008-12-26 00:05:11 +0000693
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000694
695static void create_pcap_file(char *file)
696{
697 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
698 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
699
700 if (fd < 0) {
701 perror("Failed to open file for pcap");
702 return;
703 }
704
705 mi_set_pcap_fd(fd);
706}
707
Holger Freytherb332f612008-12-27 12:46:51 +0000708static void print_usage()
709{
710 printf("Usage: bsc_hack\n");
711}
712
713static void print_help()
714{
715 printf(" Some useful help...\n");
716 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000717 printf(" -s --disable-color\n");
718 printf(" -n --network-code number(MNC) \n");
719 printf(" -c --country-code number (MCC) \n");
Holger Freytherbde36102008-12-28 22:51:39 +0000720 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +0000721 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freythere97f7fb2008-12-31 18:52:11 +0000722 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000723 printf(" -p --pcap file The filename of the pcap file\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000724 printf(" -h --help this text\n");
725}
726
727static void handle_options(int argc, char** argv)
728{
729 while (1) {
730 int option_index = 0, c;
731 static struct option long_options[] = {
732 {"help", 0, 0, 'h'},
733 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000734 {"disable-color", 0, 0, 's'},
735 {"network-code", 1, 0, 'n'},
736 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000737 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +0000738 {"authorize-everyone", 0, 0, 'a'},
Holger Freythere97f7fb2008-12-31 18:52:11 +0000739 {"reject-cause", 1, 0, 'r'},
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000740 {"pcap", 1, 0, 'p'},
Holger Freytherb332f612008-12-27 12:46:51 +0000741 {0, 0, 0, 0}
742 };
743
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000744 c = getopt_long(argc, argv, "hc:n:d:sar:p:",
Holger Freytherb332f612008-12-27 12:46:51 +0000745 long_options, &option_index);
746 if (c == -1)
747 break;
748
749 switch (c) {
750 case 'h':
751 print_usage();
752 print_help();
753 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000754 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000755 debug_use_color(0);
756 break;
757 case 'd':
758 debug_parse_category_mask(optarg);
759 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000760 case 'n':
761 MNC = atoi(optarg);
762 break;
763 case 'c':
764 MCC = atoi(optarg);
765 break;
Holger Freytherbde36102008-12-28 22:51:39 +0000766 case 'l':
767 database_name = strdup(optarg);
768 break;
Holger Freyther89824fc2008-12-30 16:18:18 +0000769 case 'a':
770 gsm0408_allow_everyone(1);
771 break;
Holger Freythere97f7fb2008-12-31 18:52:11 +0000772 case 'r':
773 gsm0408_set_reject_cause(atoi(optarg));
774 break;
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000775 case 'p':
776 create_pcap_file(optarg);
777 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000778 default:
779 /* ignore */
780 break;
781 }
782 }
783}
784
Harald Welte255539c2008-12-28 02:26:27 +0000785static struct timer_list pag_timer;
786
787/* handles uppercase decimal and hexadecimal */
788static u_int8_t char2bcd(char c)
789{
790 if (c <= '9')
791 return c - '0';
792 else
793 return c - 'A';
794}
795
796static int string_to_mi(u_int8_t *mi, const char *string,
797 u_int8_t type)
798{
799 u_int8_t *cur = mi+3;
800
801 mi[0] = GSM48_IE_MOBILE_ID;
802 //mi[1] = TMSI_LEN;
803 mi[2] = type & GSM_MI_TYPE_MASK;
804
805 if (strlen(string) & 0x01)
806 mi[2] |= char2bcd(*string++) << 4;
807 else
808 mi[2] |= 0xf0;
809
810 while (*string && *(string+1))
811 *cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4);
812
813 mi[1] = cur - mi;
814
815 return cur - mi;
816}
817
Holger Freyther07cc8d82008-12-29 06:23:46 +0000818/*
819 * Stations that registered and that we need to page
820 */
821struct pending_registered_station {
822 struct llist_head entry;
Harald Welte255539c2008-12-28 02:26:27 +0000823
Holger Freyther07cc8d82008-12-29 06:23:46 +0000824 /* the tmsi of the subscriber */
825 u_int32_t tmsi;
826 int last_page_group;
827};
828
829static LLIST_HEAD(pending_stations);
830
831static void pag_timer_cb(void *data);
832static struct timer_list pag_timer = {
833 .cb = pag_timer_cb,
834};
835
836/* page the tmsi and wait for the channel request */
837static void pag_timer_cb(void *data)
Harald Welte255539c2008-12-28 02:26:27 +0000838{
839 struct gsm_bts *bts = &gsmnet->bts[0];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000840 struct pending_registered_station *pending_station;
Harald Welte255539c2008-12-28 02:26:27 +0000841 u_int8_t mi[128];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000842 unsigned int mi_len;
Harald Welte255539c2008-12-28 02:26:27 +0000843
Harald Welte21768812009-01-01 00:32:49 +0000844return;
Harald Weltef5cbab72008-12-30 18:00:15 +0000845
Holger Freyther07cc8d82008-12-29 06:23:46 +0000846 if (llist_empty(&pending_stations)) {
847 DEBUGP(DPAG, "pag_timer_cb but no pending mobile stations\n");
Harald Welte255539c2008-12-28 02:26:27 +0000848 return;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000849 }
Harald Welte255539c2008-12-28 02:26:27 +0000850
Holger Freyther355701b2009-01-01 18:02:29 +0000851 /* FIXME: 05.02 6.5.2 Determination of CCCH_GROUP and PAGING_GROUP... */
Holger Freyther07cc8d82008-12-29 06:23:46 +0000852 /* get the station to page */
853 pending_station = (struct pending_registered_station*) pending_stations.next;
854 mi_len = generate_mid_from_tmsi(mi, pending_station->tmsi);
855 rsl_paging_cmd(bts, pending_station->last_page_group, mi_len, mi, RSL_CHANNEED_TCH_F);
Harald Welte255539c2008-12-28 02:26:27 +0000856
Holger Freyther07cc8d82008-12-29 06:23:46 +0000857 /* which group to page next */
858 pending_station->last_page_group = (pending_station->last_page_group+1) % 12;
859 schedule_timer(&pag_timer, 1, 0);
860}
Harald Welte255539c2008-12-28 02:26:27 +0000861
Holger Freyther07cc8d82008-12-29 06:23:46 +0000862/*
863 * initiate the a page command for the given
864 * station and retry until we get a channel request
865 */
866static void station_timer_cb(void *data)
867{
868 DEBUGP(DPAG, "Initiating paging of a channel\n");
869 pag_timer_cb(0);
870}
Harald Welte255539c2008-12-28 02:26:27 +0000871
Holger Freyther07cc8d82008-12-29 06:23:46 +0000872static struct timer_list station_timer = {
873 .cb = station_timer_cb,
874};
875
876/*
877 * schedule work
878 */
Holger Freytherb7193e42008-12-29 17:44:08 +0000879static void bsc_hack_update_request(struct gsm_bts *bts, u_int32_t tmsi, int accepted)
Holger Freyther07cc8d82008-12-29 06:23:46 +0000880{
881 struct pending_registered_station *station =
882 (struct pending_registered_station*)malloc(sizeof(*station));
Holger Freytherb7193e42008-12-29 17:44:08 +0000883
884 /*
885 * Only deal with LOCATION UPDATE REQUEST we have
886 * accepted.
887 */
888 if (!accepted)
889 return;
890
891
Holger Freyther07cc8d82008-12-29 06:23:46 +0000892 station->tmsi = tmsi;
893 station->last_page_group = 0;
894 llist_add_tail(&station->entry, &pending_stations);
895
896 if (!timer_pending(&station_timer))
897 schedule_timer(&station_timer, 1, 0);
Harald Welte255539c2008-12-28 02:26:27 +0000898}
899
Holger Freyther3186bf22008-12-29 06:23:49 +0000900static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
901 enum gsm_chreq_reason_t chreq_reason)
902{
903 struct pending_registered_station *station;
904 if (chreq_reason != GSM_CHREQ_REASON_PAG)
905 return;
906
907 if (llist_empty(&pending_stations)) {
908 DEBUGP(DPAG, "Channel allocated for pag but not waitin for it\n");
909 return;
910 }
911
912 station = (struct pending_registered_station*) pending_stations.next;
913
914 DEBUGP(DPAG, "CHAN RQD due PAG %d on %d for %u\n", chan->type, chan->nr, station->tmsi);
915
916 /* allocate some token in the chan for us */
917 chan->user_data = (void*)station->tmsi;
918 del_timer(&pag_timer);
919}
920
Holger Freyther88ea8322008-12-29 06:23:52 +0000921static void bsc_hack_channel_response(struct gsm_lchan *lchan, int ack)
Holger Freyther24893de2008-12-29 06:23:51 +0000922{
923 struct pending_registered_station *station;
924 if (llist_empty(&pending_stations)) {
Holger Freyther24893de2008-12-29 06:23:51 +0000925 return;
926 }
927
928 station = (struct pending_registered_station*) pending_stations.next;
929 if (station->tmsi != (u_int32_t)lchan->user_data) {
930 DEBUGP(DPAG, "Hmmm the channel is not allocated by the"
931 "station we wanted channel: %u us:%u\n",
932 (u_int32_t)(lchan->user_data), station->tmsi);
933 return;
934 }
935
Holger Freyther88ea8322008-12-29 06:23:52 +0000936 if (ack) {
937 DEBUGP(DPAG, "We have probably paged a channel for tmsi: %u on %d\n",
938 station->tmsi, lchan->nr);
Holger Freyther24893de2008-12-29 06:23:51 +0000939
Holger Freyther88ea8322008-12-29 06:23:52 +0000940 llist_del(&station->entry);
941 free(station);
Holger Freytherabade7a2008-12-29 06:42:15 +0000942
943 /*
944 * start a call
945 */
946 gsm48_cc_tx_setup(lchan);
Holger Freyther88ea8322008-12-29 06:23:52 +0000947 } else {
948 /*
949 * give up and go to the next channel
950 */
951 llist_del(&station->entry);
952 free(station);
953 pag_timer_cb(0);
Holger Freyther24893de2008-12-29 06:23:51 +0000954 }
Holger Freyther24893de2008-12-29 06:23:51 +0000955}
956
Holger Freytherb7193e42008-12-29 17:44:08 +0000957static void bsc_hack_call_state_changed(struct gsm_lchan *lchan,
958 enum gsm_call_state new_state)
Holger Freyther2eafef52008-12-29 06:42:17 +0000959{
960 DEBUGP(DPAG, "Call released jumping to the next...\n");
Holger Freytherb7193e42008-12-29 17:44:08 +0000961
962 /* only handle the transition back to the NULL state */
963 if (new_state != GSM_CSTATE_NULL)
964 return;
965
Holger Freyther2eafef52008-12-29 06:42:17 +0000966 rsl_chan_release(lchan);
967
968 /* next!!! */
969 pag_timer_cb(0);
970}
971
Harald Welted1252502009-01-01 01:50:32 +0000972static void signal_handler(int signal)
973{
974 fprintf(stdout, "signal %u received\n", signal);
975
976 switch (signal) {
977 case SIGHUP:
978 case SIGABRT:
979 shutdown_net(gsmnet);
980 break;
981 default:
982 break;
983 }
984}
985
Harald Weltef6b7a902008-12-26 00:05:11 +0000986int main(int argc, char **argv)
987{
Holger Freytherb332f612008-12-27 12:46:51 +0000988 /* parse options */
989 handle_options(argc, argv);
990
Holger Freytherbde36102008-12-28 22:51:39 +0000991 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +0000992 printf("DB: Failed to init database. Please check the option settings.\n");
993 return 1;
994 }
995 printf("DB: Database initialized.\n");
996
997 if (db_prepare()) {
998 printf("DB: Failed to prepare database.\n");
999 return 1;
1000 }
1001 printf("DB: Database prepared.\n");
1002
Harald Weltef6b7a902008-12-26 00:05:11 +00001003 bootstrap_network();
1004
Harald Welted1252502009-01-01 01:50:32 +00001005 signal(SIGHUP, &signal_handler);
1006 signal(SIGABRT, &signal_handler);
1007
Harald Weltef6b7a902008-12-26 00:05:11 +00001008 while (1) {
1009 bsc_select_main();
1010 }
1011}