blob: a3aefc6641462411a87877e6c77309b55f98fa02 [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>
Holger Freyther219518d2009-01-02 22:04:43 +00004 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
Harald Welte52b1f982008-12-23 20:25:15 +00005 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
Harald Weltef6b7a902008-12-26 00:05:11 +000023#include <unistd.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <stdarg.h>
27#include <time.h>
28#include <string.h>
Harald Weltead384642008-12-26 10:20:07 +000029#include <errno.h>
Harald Welted1252502009-01-01 01:50:32 +000030#include <signal.h>
Holger Freyther9a3ee0f2009-01-02 00:40:15 +000031#include <fcntl.h>
32#include <sys/stat.h>
Harald Welte52b1f982008-12-23 20:25:15 +000033
Holger Freytherb332f612008-12-27 12:46:51 +000034#define _GNU_SOURCE
35#include <getopt.h>
36
Harald Welte255539c2008-12-28 02:26:27 +000037#include <openbsc/db.h>
38#include <openbsc/timer.h>
Harald Welte8470bf22008-12-25 23:28:35 +000039#include <openbsc/gsm_data.h>
Harald Welte255539c2008-12-28 02:26:27 +000040#include <openbsc/gsm_04_08.h>
Harald Weltead384642008-12-26 10:20:07 +000041#include <openbsc/select.h>
Harald Welte8470bf22008-12-25 23:28:35 +000042#include <openbsc/abis_rsl.h>
43#include <openbsc/abis_nm.h>
Harald Welte702d8702008-12-26 20:25:35 +000044#include <openbsc/debug.h>
Holger Freyther5677ae32008-12-27 09:41:03 +000045#include <openbsc/misdn.h>
Holger Freyther219518d2009-01-02 22:04:43 +000046#include <openbsc/telnet_interface.h>
Harald Welte52b1f982008-12-23 20:25:15 +000047
48/* global pointer to the gsm network data structure */
49static struct gsm_network *gsmnet;
50
Holger Freytherefde7fb2008-12-28 14:14:56 +000051/* MCC and MNC for the Location Area Identifier */
52static int MCC = 1;
53static int MNC = 1;
Holger Freytherbde36102008-12-28 22:51:39 +000054static const char *database_name = "hlr.sqlite3";
Holger Freytherefde7fb2008-12-28 14:14:56 +000055
Holger Freyther07cc8d82008-12-29 06:23:46 +000056/* forward declarations */
Holger Freytherb7193e42008-12-29 17:44:08 +000057static void bsc_hack_update_request(struct gsm_bts *bts,
58 u_int32_t assigned_tmi, int accepted);
Holger Freyther3186bf22008-12-29 06:23:49 +000059static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
60 enum gsm_chreq_reason_t reason);
Holger Freyther88ea8322008-12-29 06:23:52 +000061static void bsc_hack_channel_response(struct gsm_lchan *chan, int acked);
Holger Freytherb7193e42008-12-29 17:44:08 +000062static void bsc_hack_call_state_changed(struct gsm_lchan *chan,
63 enum gsm_call_state new_state);
Holger Freyther07cc8d82008-12-29 06:23:46 +000064
Holger Freytherefde7fb2008-12-28 14:14:56 +000065
Harald Welte52b1f982008-12-23 20:25:15 +000066/* The following definitions are for OM and NM packets that we cannot yet
67 * generate by code but we just pass on */
68
69// BTS Site Manager, SET ATTRIBUTES
70
71/*
72 Object Class: BTS Site Manager
73 Instance 1: FF
74 Instance 2: FF
75 Instance 3: FF
76SET ATTRIBUTES
77 sAbisExternalTime: 2007/09/08 14:36:11
78 omLAPDRelTimer: 30sec
79 shortLAPDIntTimer: 5sec
80 emergencyTimer1: 10 minutes
81 emergencyTimer2: 0 minutes
82*/
83
84unsigned char msg_1[] =
85{
86 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
87 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
88 0x02, 0x00, 0x00
89};
90
91// BTS, SET BTS ATTRIBUTES
92
93/*
94 Object Class: BTS
95 BTS relat. Number: 0
96 Instance 2: FF
97 Instance 3: FF
98SET BTS ATTRIBUTES
99 bsIdentityCode / BSIC:
100 PLMN_colour_code: 7h
101 BS_colour_code: 7h
102 BTS Air Timer T3105: 4 ,unit 10 ms
103 btsIsHopping: FALSE
104 periodCCCHLoadIndication: 255sec
105 thresholdCCCHLoadIndication: 100%
106 cellAllocationNumber: 00h = GSM 900
107 enableInterferenceClass: 00h = Disabled
108 fACCHQual: 6 (FACCH stealing flags minus 1)
109 intaveParameter: 31 SACCH multiframes
110 interferenceLevelBoundaries:
111 Interference Boundary 1: 0Ah
112 Interference Boundary 2: 0Fh
113 Interference Boundary 3: 14h
114 Interference Boundary 4: 19h
115 Interference Boundary 5: 1Eh
116 mSTxPwrMax: 11
117 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
118 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
119 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
120 30=33dBm, 31=32dBm
121 ny1:
122 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
123 powerOutputThresholds:
124 Out Power Fault Threshold: -10 dB
125 Red Out Power Threshold: - 6 dB
126 Excessive Out Power Threshold: 5 dB
127 rACHBusyThreshold: -127 dBm
128 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
129 rfResourceIndicationPeriod: 125 SACCH multiframes
130 T200:
131 SDCCH: 044 in 5 ms
132 FACCH/Full rate: 031 in 5 ms
133 FACCH/Half rate: 041 in 5 ms
134 SACCH with TCH SAPI0: 090 in 10 ms
135 SACCH with SDCCH: 090 in 10 ms
136 SDCCH with SAPI3: 090 in 5 ms
137 SACCH with TCH SAPI3: 135 in 10 ms
138 tSync: 9000 units of 10 msec
139 tTrau: 9000 units of 10 msec
140 enableUmLoopTest: 00h = disabled
141 enableExcessiveDistance: 00h = Disabled
142 excessiveDistance: 64km
143 hoppingMode: 00h = baseband hopping
144 cellType: 00h = Standard Cell
145 BCCH ARFCN / bCCHFrequency: 1
146*/
147
148unsigned char msg_2[] =
149{
150 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
151 0xFF, 0x0C, 0x64, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
152 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
153 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
154 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
155 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
156 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
157};
158
159// Handover Recognition, SET ATTRIBUTES
160
161/*
162Illegal Contents GSM Formatted O&M Msg
163 Object Class: Handover Recognition
164 BTS relat. Number: 0
165 Instance 2: FF
166 Instance 3: FF
167SET ATTRIBUTES
168 enableDelayPowerBudgetHO: 00h = Disabled
169 enableDistanceHO: 00h = Disabled
170 enableInternalInterCellHandover: 00h = Disabled
171 enableInternalIntraCellHandover: 00h = Disabled
172 enablePowerBudgetHO: 00h = Disabled
173 enableRXLEVHO: 00h = Disabled
174 enableRXQUALHO: 00h = Disabled
175 hoAveragingDistance: 8 SACCH multiframes
176 hoAveragingLev:
177 A_LEV_HO: 8 SACCH multiframes
178 W_LEV_HO: 1 SACCH multiframes
179 hoAveragingPowerBudget: 16 SACCH multiframes
180 hoAveragingQual:
181 A_QUAL_HO: 8 SACCH multiframes
182 W_QUAL_HO: 2 SACCH multiframes
183 hoLowerThresholdLevDL: (10 - 110) dBm
184 hoLowerThresholdLevUL: (5 - 110) dBm
185 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
186 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
187 hoThresholdLevDLintra : (20 - 110) dBm
188 hoThresholdLevULintra: (20 - 110) dBm
189 hoThresholdMsRangeMax: 20 km
190 nCell: 06h
191 timerHORequest: 3 ,unit 2 SACCH multiframes
192*/
193
194unsigned char msg_3[] =
195{
196 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
197 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
198 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
199 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
200 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
201 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
202 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
203 0x20, 0xF7, 0x01, 0x3C,
204};
205
206// Power Control, SET ATTRIBUTES
207
208/*
209 Object Class: Power Control
210 BTS relat. Number: 0
211 Instance 2: FF
212 Instance 3: FF
213SET ATTRIBUTES
214 enableMsPowerControl: 00h = Disabled
215 enablePowerControlRLFW: 00h = Disabled
216 pcAveragingLev:
217 A_LEV_PC: 4 SACCH multiframes
218 W_LEV_PC: 1 SACCH multiframes
219 pcAveragingQual:
220 A_QUAL_PC: 4 SACCH multiframes
221 W_QUAL_PC: 2 SACCH multiframes
222 pcLowerThresholdLevDL: 0Fh
223 pcLowerThresholdLevUL: 0Ah
224 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
225 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
226 pcRLFThreshold: 0Ch
227 pcUpperThresholdLevDL: 14h
228 pcUpperThresholdLevUL: 0Fh
229 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
230 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
231 powerConfirm: 2 ,unit 2 SACCH multiframes
232 powerControlInterval: 2 ,unit 2 SACCH multiframes
233 powerIncrStepSize: 02h = 4 dB
234 powerRedStepSize: 01h = 2 dB
235 radioLinkTimeoutBs: 64 SACCH multiframes
236 enableBSPowerControl: 00h = disabled
237*/
238
239unsigned char msg_4[] =
240{
241 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
242 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
243 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
244 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
245};
246
247
248// Transceiver, SET TRX ATTRIBUTES (TRX 0)
249
250/*
251 Object Class: Transceiver
252 BTS relat. Number: 0
253 Tranceiver number: 0
254 Instance 3: FF
255SET TRX ATTRIBUTES
256 aRFCNList (HEX): 0001
257 txPwrMaxReduction: 00h = 0dB
258 radioMeasGran: 254 SACCH multiframes
259 radioMeasRep: 01h = enabled
260 memberOfEmergencyConfig: 01h = TRUE
261 trxArea: 00h = TRX doesn't belong to a concentric cell
262*/
263
264unsigned char msg_6[] =
265{
266 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
267 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
268};
269
270
271static void bootstrap_om(struct gsm_bts *bts)
272{
273 struct gsm_bts_trx *trx = &bts->trx[0];
274
Harald Weltead384642008-12-26 10:20:07 +0000275 fprintf(stdout, "bootstrapping OML\n");
276
Harald Welte52b1f982008-12-23 20:25:15 +0000277 /* stop sending event reports */
278 abis_nm_event_reports(bts, 0);
279
280 /* begin DB transmission */
281 abis_nm_db_transmission(bts, 1);
282
Harald Welte702d8702008-12-26 20:25:35 +0000283 /* end DB transmission */
284 abis_nm_db_transmission(bts, 0);
285
286 /* Reset BTS Site manager resource */
287 abis_nm_reset_resource(bts);
288
289 /* begin DB transmission */
290 abis_nm_db_transmission(bts, 1);
291
Harald Welte52b1f982008-12-23 20:25:15 +0000292 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
293 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
294 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
295 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
296
297 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
298 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
299 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
300
301 /* Use TEI 1 for signalling */
302 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
303 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
304#if 0
305 /* TRX 1 */
306 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
307 /* FIXME: TRX ATTRIBUTE */
308 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
309#endif
310
311 /* SET CHANNEL ATTRIBUTE TS1 */
312 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
313 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
314 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
315
316 /* SET CHANNEL ATTRIBUTE TS2 */
317 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
318 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
319 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
320
321 /* SET CHANNEL ATTRIBUTE TS3 */
322 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
323 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
324 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
325
326 /* SET CHANNEL ATTRIBUTE TS4 */
327 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
328 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
329 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
330
331 /* SET CHANNEL ATTRIBUTE TS5 */
332 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
333 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
334 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
335
336 /* SET CHANNEL ATTRIBUTE TS6 */
337 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
338 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
339 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
340
341 /* SET CHANNEL ATTRIBUTE TS7 */
342 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
343 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
344 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
345
346 /* end DB transmission */
347 abis_nm_db_transmission(bts, 0);
348
349 /* Reset BTS Site manager resource */
350 abis_nm_reset_resource(bts);
351
352 /* restart sending event reports */
353 abis_nm_event_reports(bts, 1);
354}
355
Harald Welted1252502009-01-01 01:50:32 +0000356static int shutdown_om(struct gsm_bts *bts)
357{
358 /* stop sending event reports */
359 abis_nm_event_reports(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000360
Harald Welted1252502009-01-01 01:50:32 +0000361 /* begin DB transmission */
362 abis_nm_db_transmission(bts, 1);
363
364 /* end DB transmission */
365 abis_nm_db_transmission(bts, 0);
366
367 /* Reset BTS Site manager resource */
368 abis_nm_reset_resource(bts);
369
370 return 0;
371}
372
373static int shutdown_net(struct gsm_network *net)
374{
375 int i;
376 for (i = 0; i < net->num_bts; i++) {
377 int rc;
378 rc = shutdown_om(&net->bts[i]);
379 if (rc < 0)
380 return rc;
381 }
382
383 return 0;
384}
Harald Welte52b1f982008-12-23 20:25:15 +0000385
386struct bcch_info {
387 u_int8_t type;
388 u_int8_t len;
389 const u_int8_t *data;
390};
391
392/*
393SYSTEM INFORMATION TYPE 1
394 Cell channel description
395 Format-ID bit map 0
396 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
397 RACH Control Parameters
398 maximum 7 retransmissions
399 8 slots used to spread transmission
400 cell not barred for access
401 call reestablishment not allowed
402 Access Control Class = 0000
403*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000404static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000405 /* header */0x55, 0x06, 0x19,
406 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
408 /* rach */0xD5, 0x00, 0x00,
409 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000410};
411
412/*
413 SYSTEM INFORMATION TYPE 2
414 Neighbour Cells Description
415 EXT-IND: Carries the complete BA
416 BA-IND = 0
417 Format-ID bit map 0
418 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
419 NCC permitted (NCC) = FF
420 RACH Control Parameters
421 maximum 7 retransmissions
422 8 slots used to spread transmission
423 cell not barred for access
424 call reestablishment not allowed
425 Access Control Class = 0000
426*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000427static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000428 /* header */0x59, 0x06, 0x1A,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431 /* ncc */0xFF,
432 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000433};
434
435/*
436SYSTEM INFORMATION TYPE 3
437 Cell identity = 00001 (1h)
438 Location area identification
439 Mobile Country Code (MCC): 001
440 Mobile Network Code (MNC): 01
441 Location Area Code (LAC): 00001 (1h)
442 Control Channel Description
443 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
444 0 blocks reserved for access grant
445 1 channel used for CCCH, with SDCCH
446 5 multiframes period for PAGING REQUEST
447 Time-out T3212 = 0
448 Cell Options BCCH
449 Power control indicator: not set
450 MSs shall not use uplink DTX
451 Radio link timeout = 36
452 Cell Selection Parameters
453 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000454 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000455 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
456 Half rate support (NECI): New establishment causes are not supported
457 min.RX signal level for MS = 0
458 RACH Control Parameters
459 maximum 7 retransmissions
460 8 slots used to spread transmission
461 cell not barred for access
462 call reestablishment not allowed
463 Access Control Class = 0000
464 SI 3 Rest Octets
465 Cell Bar Qualify (CBQ): 0
466 Cell Reselect Offset = 0 dB
467 Temporary Offset = 0 dB
468 Penalty Time = 20 s
469 System Information 2ter Indicator (2TI): 0 = not available
470 Early Classmark Sending Control (ECSC): 0 = forbidden
471 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
472*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000473static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000474 /* header */0x49, 0x06, 0x1B,
475 /* cell */0x00, 0x01,
476 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
477 /* desc */0x01, 0x03, 0x00,
478 /* option*/0x28,
479 /* selection*/0x62, 0x00,
480 /* rach */0xD5, 0x00, 0x00,
481 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000482};
483
484/*
485SYSTEM INFORMATION TYPE 4
486 Location area identification
487 Mobile Country Code (MCC): 001
488 Mobile Network Code (MNC): 01
489 Location Area Code (LAC): 00001 (1h)
490 Cell Selection Parameters
491 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
492 max.TX power level MS may use for CCH = 2
493 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
494 Half rate support (NECI): New establishment causes are not supported
495 min.RX signal level for MS = 0
496 RACH Control Parameters
497 maximum 7 retransmissions
498 8 slots used to spread transmission
499 cell not barred for access
500 call reestablishment not allowed
501 Access Control Class = 0000
502 Channel Description
503 Type = SDCCH/4[2]
504 Timeslot Number: 0
505 Training Sequence Code: 7h
506 ARFCN: 1
507 SI Rest Octets
508 Cell Bar Qualify (CBQ): 0
509 Cell Reselect Offset = 0 dB
510 Temporary Offset = 0 dB
511 Penalty Time = 20 s
512*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000513static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000514 /* header */0x41, 0x06, 0x1C,
515 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
516 /* sel */0x62, 0x00,
517 /* rach*/0xD5, 0x00, 0x00,
518 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000519 0x2B, 0x2B, 0x2B
520};
521
522/*
523 SYSTEM INFORMATION TYPE 5
524 Neighbour Cells Description
525 EXT-IND: Carries the complete BA
526 BA-IND = 0
527 Format-ID bit map 0
528 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
529*/
530
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000531static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000532 /* header without l2 len*/0x06, 0x1D,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000535};
536
537// SYSTEM INFORMATION TYPE 6
538
539/*
540SACCH FILLING
541 System Info Type: SYSTEM INFORMATION 6
542 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
543
544SYSTEM INFORMATION TYPE 6
545 Cell identity = 00001 (1h)
546 Location area identification
547 Mobile Country Code (MCC): 001
548 Mobile Network Code (MNC): 01
549 Location Area Code (LAC): 00001 (1h)
550 Cell Options SACCH
551 Power control indicator: not set
552 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
553 Radio link timeout = 36
554 NCC permitted (NCC) = FF
555*/
556
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000557static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000558 /* header */0x06, 0x1E,
559 /* cell id*/ 0x00, 0x01,
560 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
561 /* options */ 0x28,
562 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000563};
564
565
566
567static const struct bcch_info bcch_infos[] = {
568 {
569 .type = RSL_SYSTEM_INFO_1,
570 .len = sizeof(si1),
571 .data = si1,
572 }, {
573 .type = RSL_SYSTEM_INFO_2,
574 .len = sizeof(si2),
575 .data = si2,
576 }, {
577 .type = RSL_SYSTEM_INFO_3,
578 .len = sizeof(si3),
579 .data = si3,
580 }, {
581 .type = RSL_SYSTEM_INFO_4,
582 .len = sizeof(si4),
583 .data = si4,
584 },
585};
586
Holger Freyther24287b62008-12-28 16:32:41 +0000587static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
588static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
589static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
590static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000591static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
592static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000593
Harald Welte52b1f982008-12-23 20:25:15 +0000594/* set all system information types */
595static int set_system_infos(struct gsm_bts *bts)
596{
597 int i;
598
599 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
600 rsl_bcch_info(bts, bcch_infos[i].type,
601 bcch_infos[i].data,
602 bcch_infos[i].len);
603 }
604 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
605 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000606
607 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000608}
609
610static void activate_traffic_channels(struct gsm_bts_trx *trx)
611{
612 int i;
613
614 /* channel 0 is CCCH */
615 for (i = 1; i < 8; i++)
616 rsl_chan_activate_tch_f(&trx->ts[i]);
617}
618
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000619/*
620 * Patch the various SYSTEM INFORMATION tables to update
621 * the LAI
622 */
623static void patch_tables(struct gsm_bts *bts)
624{
625 /* covert the raw packet to the struct */
626 struct gsm48_system_information_type_3 *type_3 =
627 (struct gsm48_system_information_type_3*)&si3;
628 struct gsm48_system_information_type_4 *type_4 =
629 (struct gsm48_system_information_type_4*)&si4;
630 struct gsm48_system_information_type_6 *type_6 =
631 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000632 struct gsm48_loc_area_id lai;
633
634 gsm0408_generate_lai(&lai, bts->network->country_code,
635 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000636
637 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000638 type_3->lai = lai;
639 type_4->lai = lai;
640 type_6->lai = lai;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000641}
642
643
Harald Weltead384642008-12-26 10:20:07 +0000644static void bootstrap_rsl(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000645{
Harald Welteb84e2f42008-12-28 23:42:04 +0000646 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000647 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000648 set_system_infos(bts);
649
650 /* FIXME: defer this until the channels are used */
Harald Welte702d8702008-12-26 20:25:35 +0000651 //activate_traffic_channels(&bts->trx[0]);
Harald Welte52b1f982008-12-23 20:25:15 +0000652}
653
Harald Weltead384642008-12-26 10:20:07 +0000654static void mi_cb(int event, struct gsm_bts *bts)
655{
656 switch (event) {
657 case EVT_E1_OML_UP:
658 bootstrap_om(bts);
659 break;
660 case EVT_E1_RSL_UP:
661 bootstrap_rsl(bts);
662 break;
663 default:
664 /* FIXME: deal with TEI or L1 link loss */
665 break;
666 }
667}
668
669static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000670{
671 struct gsm_bts *bts;
672
673 /* initialize our data structures */
Holger Freytherefde7fb2008-12-28 14:14:56 +0000674 gsmnet = gsm_network_init(1, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000675 if (!gsmnet)
676 return -ENOMEM;
Harald Weltef5cbab72008-12-30 18:00:15 +0000677
678 gsmnet->name_short = "25C3";
679 gsmnet->name_long = "25C3 GSM";
Harald Welte52b1f982008-12-23 20:25:15 +0000680 bts = &gsmnet->bts[0];
681 bts->location_area_code = 1;
682 bts->trx[0].arfcn = HARDCODED_ARFCN;
Harald Weltef5cbab72008-12-30 18:00:15 +0000683#if 0
Holger Freytherb7193e42008-12-29 17:44:08 +0000684 gsmnet->update_request = bsc_hack_update_request;
Holger Freyther3186bf22008-12-29 06:23:49 +0000685 gsmnet->channel_allocated = bsc_hack_channel_allocated;
Holger Freyther88ea8322008-12-29 06:23:52 +0000686 gsmnet->channel_response = bsc_hack_channel_response;
Holger Freytherb7193e42008-12-29 17:44:08 +0000687 gsmnet->call_state_changed = bsc_hack_call_state_changed;
Harald Weltef5cbab72008-12-30 18:00:15 +0000688#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000689
Holger Freyther219518d2009-01-02 22:04:43 +0000690 telnet_init(gsmnet, 4242);
Harald Weltead384642008-12-26 10:20:07 +0000691 if (mi_setup(bts, 0, mi_cb) < 0)
692 return -EIO;
693
694 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000695}
Harald Weltef6b7a902008-12-26 00:05:11 +0000696
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000697
698static void create_pcap_file(char *file)
699{
700 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
701 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
702
703 if (fd < 0) {
704 perror("Failed to open file for pcap");
705 return;
706 }
707
708 mi_set_pcap_fd(fd);
709}
710
Holger Freytherb332f612008-12-27 12:46:51 +0000711static void print_usage()
712{
713 printf("Usage: bsc_hack\n");
714}
715
716static void print_help()
717{
718 printf(" Some useful help...\n");
719 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000720 printf(" -s --disable-color\n");
721 printf(" -n --network-code number(MNC) \n");
722 printf(" -c --country-code number (MCC) \n");
Holger Freytherbde36102008-12-28 22:51:39 +0000723 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +0000724 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freythere97f7fb2008-12-31 18:52:11 +0000725 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000726 printf(" -p --pcap file The filename of the pcap file\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000727 printf(" -h --help this text\n");
728}
729
730static void handle_options(int argc, char** argv)
731{
732 while (1) {
733 int option_index = 0, c;
734 static struct option long_options[] = {
735 {"help", 0, 0, 'h'},
736 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000737 {"disable-color", 0, 0, 's'},
738 {"network-code", 1, 0, 'n'},
739 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000740 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +0000741 {"authorize-everyone", 0, 0, 'a'},
Holger Freythere97f7fb2008-12-31 18:52:11 +0000742 {"reject-cause", 1, 0, 'r'},
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000743 {"pcap", 1, 0, 'p'},
Holger Freytherb332f612008-12-27 12:46:51 +0000744 {0, 0, 0, 0}
745 };
746
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000747 c = getopt_long(argc, argv, "hc:n:d:sar:p:",
Holger Freytherb332f612008-12-27 12:46:51 +0000748 long_options, &option_index);
749 if (c == -1)
750 break;
751
752 switch (c) {
753 case 'h':
754 print_usage();
755 print_help();
756 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000757 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000758 debug_use_color(0);
759 break;
760 case 'd':
761 debug_parse_category_mask(optarg);
762 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000763 case 'n':
764 MNC = atoi(optarg);
765 break;
766 case 'c':
767 MCC = atoi(optarg);
768 break;
Holger Freytherbde36102008-12-28 22:51:39 +0000769 case 'l':
770 database_name = strdup(optarg);
771 break;
Holger Freyther89824fc2008-12-30 16:18:18 +0000772 case 'a':
773 gsm0408_allow_everyone(1);
774 break;
Holger Freythere97f7fb2008-12-31 18:52:11 +0000775 case 'r':
776 gsm0408_set_reject_cause(atoi(optarg));
777 break;
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000778 case 'p':
779 create_pcap_file(optarg);
780 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000781 default:
782 /* ignore */
783 break;
784 }
785 }
786}
787
Harald Welte255539c2008-12-28 02:26:27 +0000788static struct timer_list pag_timer;
789
790/* handles uppercase decimal and hexadecimal */
791static u_int8_t char2bcd(char c)
792{
793 if (c <= '9')
794 return c - '0';
795 else
796 return c - 'A';
797}
798
799static int string_to_mi(u_int8_t *mi, const char *string,
800 u_int8_t type)
801{
802 u_int8_t *cur = mi+3;
803
804 mi[0] = GSM48_IE_MOBILE_ID;
805 //mi[1] = TMSI_LEN;
806 mi[2] = type & GSM_MI_TYPE_MASK;
807
808 if (strlen(string) & 0x01)
809 mi[2] |= char2bcd(*string++) << 4;
810 else
811 mi[2] |= 0xf0;
812
813 while (*string && *(string+1))
814 *cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4);
815
816 mi[1] = cur - mi;
817
818 return cur - mi;
819}
820
Holger Freyther07cc8d82008-12-29 06:23:46 +0000821/*
822 * Stations that registered and that we need to page
823 */
824struct pending_registered_station {
825 struct llist_head entry;
Harald Welte255539c2008-12-28 02:26:27 +0000826
Holger Freyther07cc8d82008-12-29 06:23:46 +0000827 /* the tmsi of the subscriber */
828 u_int32_t tmsi;
829 int last_page_group;
830};
831
832static LLIST_HEAD(pending_stations);
833
834static void pag_timer_cb(void *data);
835static struct timer_list pag_timer = {
836 .cb = pag_timer_cb,
837};
838
839/* page the tmsi and wait for the channel request */
840static void pag_timer_cb(void *data)
Harald Welte255539c2008-12-28 02:26:27 +0000841{
842 struct gsm_bts *bts = &gsmnet->bts[0];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000843 struct pending_registered_station *pending_station;
Harald Welte255539c2008-12-28 02:26:27 +0000844 u_int8_t mi[128];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000845 unsigned int mi_len;
Harald Welte255539c2008-12-28 02:26:27 +0000846
Harald Welte21768812009-01-01 00:32:49 +0000847return;
Harald Weltef5cbab72008-12-30 18:00:15 +0000848
Holger Freyther07cc8d82008-12-29 06:23:46 +0000849 if (llist_empty(&pending_stations)) {
850 DEBUGP(DPAG, "pag_timer_cb but no pending mobile stations\n");
Harald Welte255539c2008-12-28 02:26:27 +0000851 return;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000852 }
Harald Welte255539c2008-12-28 02:26:27 +0000853
Holger Freyther355701b2009-01-01 18:02:29 +0000854 /* FIXME: 05.02 6.5.2 Determination of CCCH_GROUP and PAGING_GROUP... */
Holger Freyther07cc8d82008-12-29 06:23:46 +0000855 /* get the station to page */
856 pending_station = (struct pending_registered_station*) pending_stations.next;
857 mi_len = generate_mid_from_tmsi(mi, pending_station->tmsi);
858 rsl_paging_cmd(bts, pending_station->last_page_group, mi_len, mi, RSL_CHANNEED_TCH_F);
Harald Welte255539c2008-12-28 02:26:27 +0000859
Holger Freyther07cc8d82008-12-29 06:23:46 +0000860 /* which group to page next */
861 pending_station->last_page_group = (pending_station->last_page_group+1) % 12;
862 schedule_timer(&pag_timer, 1, 0);
863}
Harald Welte255539c2008-12-28 02:26:27 +0000864
Holger Freyther07cc8d82008-12-29 06:23:46 +0000865/*
866 * initiate the a page command for the given
867 * station and retry until we get a channel request
868 */
869static void station_timer_cb(void *data)
870{
871 DEBUGP(DPAG, "Initiating paging of a channel\n");
872 pag_timer_cb(0);
873}
Harald Welte255539c2008-12-28 02:26:27 +0000874
Holger Freyther07cc8d82008-12-29 06:23:46 +0000875static struct timer_list station_timer = {
876 .cb = station_timer_cb,
877};
878
879/*
880 * schedule work
881 */
Holger Freytherb7193e42008-12-29 17:44:08 +0000882static void bsc_hack_update_request(struct gsm_bts *bts, u_int32_t tmsi, int accepted)
Holger Freyther07cc8d82008-12-29 06:23:46 +0000883{
884 struct pending_registered_station *station =
885 (struct pending_registered_station*)malloc(sizeof(*station));
Holger Freytherb7193e42008-12-29 17:44:08 +0000886
887 /*
888 * Only deal with LOCATION UPDATE REQUEST we have
889 * accepted.
890 */
891 if (!accepted)
892 return;
893
894
Holger Freyther07cc8d82008-12-29 06:23:46 +0000895 station->tmsi = tmsi;
896 station->last_page_group = 0;
897 llist_add_tail(&station->entry, &pending_stations);
898
899 if (!timer_pending(&station_timer))
900 schedule_timer(&station_timer, 1, 0);
Harald Welte255539c2008-12-28 02:26:27 +0000901}
902
Holger Freyther3186bf22008-12-29 06:23:49 +0000903static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
904 enum gsm_chreq_reason_t chreq_reason)
905{
906 struct pending_registered_station *station;
907 if (chreq_reason != GSM_CHREQ_REASON_PAG)
908 return;
909
910 if (llist_empty(&pending_stations)) {
911 DEBUGP(DPAG, "Channel allocated for pag but not waitin for it\n");
912 return;
913 }
914
915 station = (struct pending_registered_station*) pending_stations.next;
916
917 DEBUGP(DPAG, "CHAN RQD due PAG %d on %d for %u\n", chan->type, chan->nr, station->tmsi);
918
919 /* allocate some token in the chan for us */
920 chan->user_data = (void*)station->tmsi;
921 del_timer(&pag_timer);
922}
923
Holger Freyther88ea8322008-12-29 06:23:52 +0000924static void bsc_hack_channel_response(struct gsm_lchan *lchan, int ack)
Holger Freyther24893de2008-12-29 06:23:51 +0000925{
926 struct pending_registered_station *station;
927 if (llist_empty(&pending_stations)) {
Holger Freyther24893de2008-12-29 06:23:51 +0000928 return;
929 }
930
931 station = (struct pending_registered_station*) pending_stations.next;
932 if (station->tmsi != (u_int32_t)lchan->user_data) {
933 DEBUGP(DPAG, "Hmmm the channel is not allocated by the"
934 "station we wanted channel: %u us:%u\n",
935 (u_int32_t)(lchan->user_data), station->tmsi);
936 return;
937 }
938
Holger Freyther88ea8322008-12-29 06:23:52 +0000939 if (ack) {
940 DEBUGP(DPAG, "We have probably paged a channel for tmsi: %u on %d\n",
941 station->tmsi, lchan->nr);
Holger Freyther24893de2008-12-29 06:23:51 +0000942
Holger Freyther88ea8322008-12-29 06:23:52 +0000943 llist_del(&station->entry);
944 free(station);
Holger Freytherabade7a2008-12-29 06:42:15 +0000945
946 /*
947 * start a call
948 */
949 gsm48_cc_tx_setup(lchan);
Holger Freyther88ea8322008-12-29 06:23:52 +0000950 } else {
951 /*
952 * give up and go to the next channel
953 */
954 llist_del(&station->entry);
955 free(station);
956 pag_timer_cb(0);
Holger Freyther24893de2008-12-29 06:23:51 +0000957 }
Holger Freyther24893de2008-12-29 06:23:51 +0000958}
959
Holger Freytherb7193e42008-12-29 17:44:08 +0000960static void bsc_hack_call_state_changed(struct gsm_lchan *lchan,
961 enum gsm_call_state new_state)
Holger Freyther2eafef52008-12-29 06:42:17 +0000962{
963 DEBUGP(DPAG, "Call released jumping to the next...\n");
Holger Freytherb7193e42008-12-29 17:44:08 +0000964
965 /* only handle the transition back to the NULL state */
966 if (new_state != GSM_CSTATE_NULL)
967 return;
968
Holger Freyther2eafef52008-12-29 06:42:17 +0000969 rsl_chan_release(lchan);
970
971 /* next!!! */
972 pag_timer_cb(0);
973}
974
Harald Welted1252502009-01-01 01:50:32 +0000975static void signal_handler(int signal)
976{
977 fprintf(stdout, "signal %u received\n", signal);
978
979 switch (signal) {
980 case SIGHUP:
981 case SIGABRT:
982 shutdown_net(gsmnet);
983 break;
984 default:
985 break;
986 }
987}
988
Harald Weltef6b7a902008-12-26 00:05:11 +0000989int main(int argc, char **argv)
990{
Holger Freytherb332f612008-12-27 12:46:51 +0000991 /* parse options */
992 handle_options(argc, argv);
993
Holger Freytherbde36102008-12-28 22:51:39 +0000994 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +0000995 printf("DB: Failed to init database. Please check the option settings.\n");
996 return 1;
997 }
998 printf("DB: Database initialized.\n");
999
1000 if (db_prepare()) {
1001 printf("DB: Failed to prepare database.\n");
1002 return 1;
1003 }
1004 printf("DB: Database prepared.\n");
1005
Harald Weltef6b7a902008-12-26 00:05:11 +00001006 bootstrap_network();
1007
Harald Welted1252502009-01-01 01:50:32 +00001008 signal(SIGHUP, &signal_handler);
1009 signal(SIGABRT, &signal_handler);
1010
Harald Weltef6b7a902008-12-26 00:05:11 +00001011 while (1) {
1012 bsc_select_main();
1013 }
1014}