blob: e41b0e382ddb67c91128b4d5074a8e180f1ba55f [file] [log] [blame]
Harald Welte59b04682009-06-10 05:40:52 +08001/* A hackish minimal BSC (+MSC +HLR) implementation */
2
3/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
4 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
5 * 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
23#include <unistd.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <stdarg.h>
27#include <time.h>
28#include <string.h>
29#include <errno.h>
30#include <signal.h>
31#include <fcntl.h>
32#include <sys/stat.h>
33
34#define _GNU_SOURCE
35#include <getopt.h>
36
37#include <openbsc/db.h>
38#include <openbsc/timer.h>
39#include <openbsc/gsm_data.h>
40#include <openbsc/gsm_04_08.h>
41#include <openbsc/select.h>
42#include <openbsc/abis_rsl.h>
43#include <openbsc/abis_nm.h>
44#include <openbsc/debug.h>
45#include <openbsc/misdn.h>
46#include <openbsc/telnet_interface.h>
47#include <openbsc/paging.h>
48#include <openbsc/e1_input.h>
49#include <openbsc/signal.h>
50
51/* global pointer to the gsm network data structure */
52static struct gsm_network *gsmnet;
53
54/* MCC and MNC for the Location Area Identifier */
55static int MCC = 1;
56static int MNC = 1;
57static int LAC = 1;
58static int ARFCN = HARDCODED_ARFCN;
59static int cardnr = 0;
60static int release_l2 = 0;
61static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
62static const char *database_name = "hlr.sqlite3";
63
64/* 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,
85 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
86 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
87 0x02,
88 0x00, 0x1E,
89 NM_ATT_BS11_SH_LAPD_INT_TIMER,
90 0x01, 0x05,
91 0x42, 0x02, 0x00, 0x0A,
92 0x44, 0x02, 0x00, 0x00
93};
94
95// BTS, SET BTS ATTRIBUTES
96
97/*
98 Object Class: BTS
99 BTS relat. Number: 0
100 Instance 2: FF
101 Instance 3: FF
102SET BTS ATTRIBUTES
103 bsIdentityCode / BSIC:
104 PLMN_colour_code: 7h
105 BS_colour_code: 7h
106 BTS Air Timer T3105: 4 ,unit 10 ms
107 btsIsHopping: FALSE
108 periodCCCHLoadIndication: 1sec
109 thresholdCCCHLoadIndication: 0%
110 cellAllocationNumber: 00h = GSM 900
111 enableInterferenceClass: 00h = Disabled
112 fACCHQual: 6 (FACCH stealing flags minus 1)
113 intaveParameter: 31 SACCH multiframes
114 interferenceLevelBoundaries:
115 Interference Boundary 1: 0Ah
116 Interference Boundary 2: 0Fh
117 Interference Boundary 3: 14h
118 Interference Boundary 4: 19h
119 Interference Boundary 5: 1Eh
120 mSTxPwrMax: 11
121 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
122 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
123 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
124 30=33dBm, 31=32dBm
125 ny1:
126 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
127 powerOutputThresholds:
128 Out Power Fault Threshold: -10 dB
129 Red Out Power Threshold: - 6 dB
130 Excessive Out Power Threshold: 5 dB
131 rACHBusyThreshold: -127 dBm
132 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
133 rfResourceIndicationPeriod: 125 SACCH multiframes
134 T200:
135 SDCCH: 044 in 5 ms
136 FACCH/Full rate: 031 in 5 ms
137 FACCH/Half rate: 041 in 5 ms
138 SACCH with TCH SAPI0: 090 in 10 ms
139 SACCH with SDCCH: 090 in 10 ms
140 SDCCH with SAPI3: 090 in 5 ms
141 SACCH with TCH SAPI3: 135 in 10 ms
142 tSync: 9000 units of 10 msec
143 tTrau: 9000 units of 10 msec
144 enableUmLoopTest: 00h = disabled
145 enableExcessiveDistance: 00h = Disabled
146 excessiveDistance: 64km
147 hoppingMode: 00h = baseband hopping
148 cellType: 00h = Standard Cell
149 BCCH ARFCN / bCCHFrequency: 1
150*/
151
152unsigned char msg_2[] =
153{
154 0x41, NM_OC_BTS, 0x00, 0xFF, 0xFF,
155 NM_ATT_BSIC, HARDCODED_BSIC,
156 NM_ATT_BTS_AIR_TIMER, 0x04,
157 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
158 NM_ATT_CCCH_L_I_P, 0x01,
159 NM_ATT_CCCH_L_T, 0x00,
160 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
161 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
162 NM_ATT_BS11_FACCH_QUAL, 0x06,
163 /* interference avg. period in numbers of SACCH multifr */
164 NM_ATT_INTAVE_PARAM, 0x1F,
165 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
166 NM_ATT_CCCH_L_T, 0x23,
167 NM_ATT_GSM_TIME, 0x28, 0x00,
168 NM_ATT_ADM_STATE, 0x03,
169 NM_ATT_RACH_B_THRESH, 0x7F,
170 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
171 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
172 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
173 NM_ATT_BS11_TSYNC, 0x23, 0x28,
174 NM_ATT_BS11_TTRAU, 0x23, 0x28,
175 NM_ATT_TEST_DUR, 0x01, 0x00,
176 NM_ATT_OUTST_ALARM, 0x01, 0x00,
177 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
178 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
179 NM_ATT_BS11_PLL, 0x01, 0x00,
180 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
181};
182
183// Handover Recognition, SET ATTRIBUTES
184
185/*
186Illegal Contents GSM Formatted O&M Msg
187 Object Class: Handover Recognition
188 BTS relat. Number: 0
189 Instance 2: FF
190 Instance 3: FF
191SET ATTRIBUTES
192 enableDelayPowerBudgetHO: 00h = Disabled
193 enableDistanceHO: 00h = Disabled
194 enableInternalInterCellHandover: 00h = Disabled
195 enableInternalIntraCellHandover: 00h = Disabled
196 enablePowerBudgetHO: 00h = Disabled
197 enableRXLEVHO: 00h = Disabled
198 enableRXQUALHO: 00h = Disabled
199 hoAveragingDistance: 8 SACCH multiframes
200 hoAveragingLev:
201 A_LEV_HO: 8 SACCH multiframes
202 W_LEV_HO: 1 SACCH multiframes
203 hoAveragingPowerBudget: 16 SACCH multiframes
204 hoAveragingQual:
205 A_QUAL_HO: 8 SACCH multiframes
206 W_QUAL_HO: 2 SACCH multiframes
207 hoLowerThresholdLevDL: (10 - 110) dBm
208 hoLowerThresholdLevUL: (5 - 110) dBm
209 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
210 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
211 hoThresholdLevDLintra : (20 - 110) dBm
212 hoThresholdLevULintra: (20 - 110) dBm
213 hoThresholdMsRangeMax: 20 km
214 nCell: 06h
215 timerHORequest: 3 ,unit 2 SACCH multiframes
216*/
217
218unsigned char msg_3[] =
219{
220 0xD0, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
221 0xD0, 0x00,
222 0x64, 0x00,
223 0x67, 0x00,
224 0x68, 0x00,
225 0x6A, 0x00,
226 0x6C, 0x00,
227 0x6D, 0x00,
228 0x6F, 0x08,
229 0x70, 0x08, 0x01,
230 0x71, 0x10, 0x10, 0x10,
231 0x72, 0x08, 0x02,
232 0x73, 0x0A,
233 0x74, 0x05,
234 0x75, 0x06,
235 0x76, 0x06,
236 0x78, 0x14,
237 0x79, 0x14,
238 0x7A, 0x14,
239 0x7D, 0x06,
240 0x92, 0x03, 0x20, 0x01, 0x00,
241 0x45, 0x01, 0x00,
242 0x48, 0x01, 0x00,
243 0x5A, 0x01, 0x00,
244 0x5B, 0x01, 0x05,
245 0x5E, 0x01, 0x1A,
246 0x5F, 0x01, 0x20,
247 0x9D, 0x01, 0x00,
248 0x47, 0x01, 0x00,
249 0x5C, 0x01, 0x64,
250 0x5D, 0x01, 0x1E,
251 0x97, 0x01, 0x20,
252 0xF7, 0x01, 0x3C,
253};
254
255// Power Control, SET ATTRIBUTES
256
257/*
258 Object Class: Power Control
259 BTS relat. Number: 0
260 Instance 2: FF
261 Instance 3: FF
262SET ATTRIBUTES
263 enableMsPowerControl: 00h = Disabled
264 enablePowerControlRLFW: 00h = Disabled
265 pcAveragingLev:
266 A_LEV_PC: 4 SACCH multiframes
267 W_LEV_PC: 1 SACCH multiframes
268 pcAveragingQual:
269 A_QUAL_PC: 4 SACCH multiframes
270 W_QUAL_PC: 2 SACCH multiframes
271 pcLowerThresholdLevDL: 0Fh
272 pcLowerThresholdLevUL: 0Ah
273 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
274 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
275 pcRLFThreshold: 0Ch
276 pcUpperThresholdLevDL: 14h
277 pcUpperThresholdLevUL: 0Fh
278 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
279 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
280 powerConfirm: 2 ,unit 2 SACCH multiframes
281 powerControlInterval: 2 ,unit 2 SACCH multiframes
282 powerIncrStepSize: 02h = 4 dB
283 powerRedStepSize: 01h = 2 dB
284 radioLinkTimeoutBs: 64 SACCH multiframes
285 enableBSPowerControl: 00h = disabled
286*/
287
288unsigned char msg_4[] =
289{
290 0xD0, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
291 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
292 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
293 0x7E, 0x04, 0x01,
294 0x7F, 0x04, 0x02,
295 0x80, 0x0F,
296 0x81, 0x0A,
297 0x82, 0x05,
298 0x83, 0x05,
299 0x84, 0x0C,
300 0x85, 0x14,
301 0x86, 0x0F,
302 0x87, 0x04,
303 0x88, 0x04,
304 0x89, 0x02,
305 0x8A, 0x02,
306 0x8B, 0x02,
307 0x8C, 0x01,
308 0x8D, 0x40,
309 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
310};
311
312
313// Transceiver, SET TRX ATTRIBUTES (TRX 0)
314
315/*
316 Object Class: Transceiver
317 BTS relat. Number: 0
318 Tranceiver number: 0
319 Instance 3: FF
320SET TRX ATTRIBUTES
321 aRFCNList (HEX): 0001
322 txPwrMaxReduction: 00h = 30dB
323 radioMeasGran: 254 SACCH multiframes
324 radioMeasRep: 01h = enabled
325 memberOfEmergencyConfig: 01h = TRUE
326 trxArea: 00h = TRX doesn't belong to a concentric cell
327*/
328
329unsigned char msg_6[] =
330{
331 0x44, NM_OC_RADIO_CARRIER, 0x00, 0x00, 0xFF,
332 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
333 NM_ATT_RF_MAXPOWR_R, 0x00,
334 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
335 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
336 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
337 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
338};
339
340static unsigned char nanobts_attr_bts[] = {
341 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
342 /* interference avg. period in numbers of SACCH multifr */
343 NM_ATT_INTAVE_PARAM, 0x06,
344 /* conn fail based on SACCH error rate */
345 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
346 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
347 NM_ATT_MAX_TA, 0x3f,
348 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
349 NM_ATT_CCCH_L_T, 10, /* percent */
350 NM_ATT_CCCH_L_I_P, 1, /* seconds */
351 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
352 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
353 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
354 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
355 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
356 NM_ATT_BSIC, HARDCODED_BSIC,
357};
358
359static unsigned char nanobts_attr_radio[] = {
360 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
361 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
362};
363
364static unsigned char nanobts_attr_e0[] = {
365 0x85, 0x00,
366 0x81, 0x0b, 0xbb, /* TCP PORT for RSL */
367};
368
369/* Callback function to be called whenever we get a GSM 12.21 state change event */
370int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
371 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
372{
373 struct gsm_bts *bts;
374 struct gsm_bts_trx *trx;
375 struct gsm_bts_trx_ts *ts;
376
377 /* This is currently only required on nanoBTS */
378
379 switch (evt) {
380 case EVT_STATECHG_OPER:
381 switch (obj_class) {
382 case NM_OC_SITE_MANAGER:
383 bts = container_of(obj, struct gsm_bts, site_mgr);
384 if (old_state->operational != 2 && new_state->operational == 2) {
385 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
386 }
387 break;
388 case NM_OC_BTS:
389 bts = obj;
390 if (new_state->availability == 5) {
391 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
392 sizeof(nanobts_attr_bts));
393 abis_nm_opstart(bts, NM_OC_BTS,
394 bts->bts_nr, 0xff, 0xff);
395 abis_nm_chg_adm_state(bts, NM_OC_BTS,
396 bts->bts_nr, 0xff, 0xff,
397 NM_STATE_UNLOCKED);
398 }
399 break;
400 case NM_OC_CHANNEL:
401 ts = obj;
402 trx = ts->trx;
403 if (new_state->availability == 5) {
404 if (ts->nr == 0 && trx == trx->bts->c0)
405 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
406 else
407 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
408 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
409 trx->bts->bts_nr, trx->nr, ts->nr);
410 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
411 trx->bts->bts_nr, trx->nr, ts->nr,
412 NM_STATE_UNLOCKED);
413 }
414 break;
415 default:
416 break;
417 }
418 break;
419 default:
420 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
421 break;
422 }
423 return 0;
424}
425
426/* Callback function to be called every time we receive a 12.21 SW activated report */
427static int sw_activ_rep(struct msgb *mb)
428{
429 struct abis_om_fom_hdr *foh = msgb_l3(mb);
430 struct gsm_bts_trx *trx = mb->trx;
431
432 switch (foh->obj_class) {
433 case NM_OC_BASEB_TRANSC:
434 /* TRX software is active, tell it to initiate RSL Link */
435 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
436 trx->bts->bts_nr, trx->nr, 0xff,
437 nanobts_attr_e0, sizeof(nanobts_attr_e0));
438 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
439 trx->bts->bts_nr, trx->nr, 0xff);
440 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
441 trx->bts->bts_nr, trx->nr, 0xff,
442 NM_STATE_UNLOCKED);
443 break;
444 case NM_OC_RADIO_CARRIER:
445 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
446 sizeof(nanobts_attr_radio));
447 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
448 trx->bts->bts_nr, trx->nr, 0xff);
449 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
450 trx->bts->bts_nr, trx->nr, 0xff,
451 NM_STATE_UNLOCKED);
452 break;
453 }
454 return 0;
455}
456
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200457/* Callback function for NACK on the OML NM */
458static int oml_msg_nack(int mt)
459{
460 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
461 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
462 "Was the bts type and frequency properly specified?\n");
463 exit(-1);
464 }
465
466 return 0;
467}
468
Harald Welte59b04682009-06-10 05:40:52 +0800469/* Callback function to be called every time we receive a signal from NM */
470static int nm_sig_cb(unsigned int subsys, unsigned int signal,
471 void *handler_data, void *signal_data)
472{
473 switch (signal) {
474 case S_NM_SW_ACTIV_REP:
475 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200476 case S_NM_NACK:
477 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800478 default:
479 break;
480 }
481 return 0;
482}
483
484static void bootstrap_om_nanobts(struct gsm_bts *bts)
485{
486 /* We don't do callback based bootstrapping, but event driven (see above) */
487}
488
489static void bootstrap_om_bs11(struct gsm_bts *bts)
490{
491 struct gsm_bts_trx *trx = &bts->trx[0];
492
493 /* stop sending event reports */
494 abis_nm_event_reports(bts, 0);
495
496 /* begin DB transmission */
497 abis_nm_bs11_db_transmission(bts, 1);
498
499 /* end DB transmission */
500 abis_nm_bs11_db_transmission(bts, 0);
501
502 /* Reset BTS Site manager resource */
503 abis_nm_bs11_reset_resource(bts);
504
505 /* begin DB transmission */
506 abis_nm_bs11_db_transmission(bts, 1);
507
508 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
509 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
510 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
511 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
512
513 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
514 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
515 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
516
517 /* Use TEI 1 for signalling */
518 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
519 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
520
521#ifdef HAVE_TRX1
522 /* TRX 1 */
523 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
524 /* FIXME: TRX ATTRIBUTE */
525 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
526#endif
527
528 /* SET CHANNEL ATTRIBUTE TS1 */
529 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
530 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
531 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
532
533 /* SET CHANNEL ATTRIBUTE TS2 */
534 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
535 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
536 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
537
538 /* SET CHANNEL ATTRIBUTE TS3 */
539 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
540 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
541 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
542
543 /* SET CHANNEL ATTRIBUTE TS4 */
544 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
545 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
546 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
547
548 /* SET CHANNEL ATTRIBUTE TS5 */
549 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
550 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
551 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
552
553 /* SET CHANNEL ATTRIBUTE TS6 */
554 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
555 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
556 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
557
558 /* SET CHANNEL ATTRIBUTE TS7 */
559 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
560 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
561 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
562
563 /* end DB transmission */
564 abis_nm_bs11_db_transmission(bts, 0);
565
566 /* Reset BTS Site manager resource */
567 abis_nm_bs11_reset_resource(bts);
568
569 /* restart sending event reports */
570 abis_nm_event_reports(bts, 1);
571}
572
573static void bootstrap_om(struct gsm_bts *bts)
574{
575 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
576
577 switch (bts->type) {
578 case GSM_BTS_TYPE_BS11:
579 bootstrap_om_bs11(bts);
580 break;
581 case GSM_BTS_TYPE_NANOBTS_900:
582 case GSM_BTS_TYPE_NANOBTS_1800:
583 bootstrap_om_nanobts(bts);
584 break;
585 default:
586 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
587 }
588}
589
590static int shutdown_om(struct gsm_bts *bts)
591{
592 /* stop sending event reports */
593 abis_nm_event_reports(bts, 0);
594
595 /* begin DB transmission */
596 abis_nm_bs11_db_transmission(bts, 1);
597
598 /* end DB transmission */
599 abis_nm_bs11_db_transmission(bts, 0);
600
601 /* Reset BTS Site manager resource */
602 abis_nm_bs11_reset_resource(bts);
603
604 return 0;
605}
606
607static int shutdown_net(struct gsm_network *net)
608{
609 int i;
610 for (i = 0; i < net->num_bts; i++) {
611 int rc;
612 rc = shutdown_om(&net->bts[i]);
613 if (rc < 0)
614 return rc;
615 }
616
617 return 0;
618}
619
620struct bcch_info {
621 u_int8_t type;
622 u_int8_t len;
623 const u_int8_t *data;
624};
625
626/*
627SYSTEM INFORMATION TYPE 1
628 Cell channel description
629 Format-ID bit map 0
630 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
631 RACH Control Parameters
632 maximum 7 retransmissions
633 8 slots used to spread transmission
634 cell not barred for access
635 call reestablishment not allowed
636 Access Control Class = 0000
637*/
638static u_int8_t si1[] = {
639 /* header */0x55, 0x06, 0x19,
640 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
642 /* rach */0xD5, 0x00, 0x00,
643 /* s1 reset*/0x2B
644};
645
646/*
647 SYSTEM INFORMATION TYPE 2
648 Neighbour Cells Description
649 EXT-IND: Carries the complete BA
650 BA-IND = 0
651 Format-ID bit map 0
652 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
653 NCC permitted (NCC) = FF
654 RACH Control Parameters
655 maximum 7 retransmissions
656 8 slots used to spread transmission
657 cell not barred for access
658 call reestablishment not allowed
659 Access Control Class = 0000
660*/
661static u_int8_t si2[] = {
662 /* header */0x59, 0x06, 0x1A,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 /* ncc */0xFF,
666 /* rach*/0xD5, 0x00, 0x00
667};
668
669/*
670SYSTEM INFORMATION TYPE 3
671 Cell identity = 00001 (1h)
672 Location area identification
673 Mobile Country Code (MCC): 001
674 Mobile Network Code (MNC): 01
675 Location Area Code (LAC): 00001 (1h)
676 Control Channel Description
677 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
678 0 blocks reserved for access grant
679 1 channel used for CCCH, with SDCCH
680 5 multiframes period for PAGING REQUEST
681 Time-out T3212 = 0
682 Cell Options BCCH
683 Power control indicator: not set
684 MSs shall not use uplink DTX
685 Radio link timeout = 36
686 Cell Selection Parameters
687 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
688 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
689 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
690 Half rate support (NECI): New establishment causes are not supported
691 min.RX signal level for MS = 0
692 RACH Control Parameters
693 maximum 7 retransmissions
694 8 slots used to spread transmission
695 cell not barred for access
696 call reestablishment not allowed
697 Access Control Class = 0000
698 SI 3 Rest Octets
699 Cell Bar Qualify (CBQ): 0
700 Cell Reselect Offset = 0 dB
701 Temporary Offset = 0 dB
702 Penalty Time = 20 s
703 System Information 2ter Indicator (2TI): 0 = not available
704 Early Classmark Sending Control (ECSC): 0 = forbidden
705 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
706*/
707static u_int8_t si3[] = {
708 /* header */0x49, 0x06, 0x1B,
709 /* cell */0x00, 0x01,
710 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
711 /* desc */0x01, 0x03, 0x00,
712 /* option*/0x28,
713 /* selection*/0x62, 0x00,
714 /* rach */0xD5, 0x00, 0x00,
715 /* reset*/0x80, 0x00, 0x00, 0x2B
716};
717
718/*
719SYSTEM INFORMATION TYPE 4
720 Location area identification
721 Mobile Country Code (MCC): 001
722 Mobile Network Code (MNC): 01
723 Location Area Code (LAC): 00001 (1h)
724 Cell Selection Parameters
725 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
726 max.TX power level MS may use for CCH = 2
727 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
728 Half rate support (NECI): New establishment causes are not supported
729 min.RX signal level for MS = 0
730 RACH Control Parameters
731 maximum 7 retransmissions
732 8 slots used to spread transmission
733 cell not barred for access
734 call reestablishment not allowed
735 Access Control Class = 0000
736 Channel Description
737 Type = SDCCH/4[2]
738 Timeslot Number: 0
739 Training Sequence Code: 7h
740 ARFCN: 1
741 SI Rest Octets
742 Cell Bar Qualify (CBQ): 0
743 Cell Reselect Offset = 0 dB
744 Temporary Offset = 0 dB
745 Penalty Time = 20 s
746*/
747static u_int8_t si4[] = {
748 /* header */0x41, 0x06, 0x1C,
749 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
750 /* sel */0x62, 0x00,
751 /* rach*/0xD5, 0x00, 0x00,
752 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
753 0x2B, 0x2B, 0x2B
754};
755
756/*
757 SYSTEM INFORMATION TYPE 5
758 Neighbour Cells Description
759 EXT-IND: Carries the complete BA
760 BA-IND = 0
761 Format-ID bit map 0
762 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
763*/
764
765static u_int8_t si5[] = {
766 /* header without l2 len*/0x06, 0x1D,
767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
769};
770
771// SYSTEM INFORMATION TYPE 6
772
773/*
774SACCH FILLING
775 System Info Type: SYSTEM INFORMATION 6
776 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
777
778SYSTEM INFORMATION TYPE 6
779 Cell identity = 00001 (1h)
780 Location area identification
781 Mobile Country Code (MCC): 001
782 Mobile Network Code (MNC): 01
783 Location Area Code (LAC): 00001 (1h)
784 Cell Options SACCH
785 Power control indicator: not set
786 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
787 Radio link timeout = 36
788 NCC permitted (NCC) = FF
789*/
790
791static u_int8_t si6[] = {
792 /* header */0x06, 0x1E,
793 /* cell id*/ 0x00, 0x01,
794 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
795 /* options */ 0x28,
796 /* ncc */ 0xFF,
797};
798
799
800
801static const struct bcch_info bcch_infos[] = {
802 {
803 .type = RSL_SYSTEM_INFO_1,
804 .len = sizeof(si1),
805 .data = si1,
806 }, {
807 .type = RSL_SYSTEM_INFO_2,
808 .len = sizeof(si2),
809 .data = si2,
810 }, {
811 .type = RSL_SYSTEM_INFO_3,
812 .len = sizeof(si3),
813 .data = si3,
814 }, {
815 .type = RSL_SYSTEM_INFO_4,
816 .len = sizeof(si4),
817 .data = si4,
818 },
819};
820
821static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
822static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
823static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
824static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
825static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
826static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
827
828/* set all system information types */
829static int set_system_infos(struct gsm_bts_trx *trx)
830{
831 int i;
832
833 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
834 rsl_bcch_info(trx, bcch_infos[i].type,
835 bcch_infos[i].data,
836 bcch_infos[i].len);
837 }
838 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
839 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
840
841 return 0;
842}
843
844/*
845 * Patch the various SYSTEM INFORMATION tables to update
846 * the LAI
847 */
848static void patch_tables(struct gsm_bts *bts)
849{
850 u_int8_t arfcn_low = bts->trx[0].arfcn & 0xff;
851 u_int8_t arfcn_high = (bts->trx[0].arfcn >> 8) & 0x0f;
852 /* covert the raw packet to the struct */
853 struct gsm48_system_information_type_3 *type_3 =
854 (struct gsm48_system_information_type_3*)&si3;
855 struct gsm48_system_information_type_4 *type_4 =
856 (struct gsm48_system_information_type_4*)&si4;
857 struct gsm48_system_information_type_6 *type_6 =
858 (struct gsm48_system_information_type_6*)&si6;
859 struct gsm48_loc_area_id lai;
860
861 gsm0408_generate_lai(&lai, bts->network->country_code,
862 bts->network->network_code,
863 bts->location_area_code);
864
865 /* assign the MCC and MNC */
866 type_3->lai = lai;
867 type_4->lai = lai;
868 type_6->lai = lai;
869
870 /* patch ARFCN into BTS Attributes */
871 msg_2[74] &= 0xf0;
872 msg_2[74] |= arfcn_high;
873 msg_2[75] = arfcn_low;
874 nanobts_attr_bts[42] &= 0xf0;
875 nanobts_attr_bts[42] |= arfcn_high;
876 nanobts_attr_bts[43] = arfcn_low;
877
878 /* patch ARFCN into TRX Attributes */
879 msg_6[7] &= 0xf0;
880 msg_6[7] |= arfcn_high;
881 msg_6[8] = arfcn_low;
882 nanobts_attr_radio[5] &= 0xf0;
883 nanobts_attr_radio[5] |= arfcn_high;
884 nanobts_attr_radio[6] = arfcn_low;
885
886 type_4->data[2] &= 0xf0;
887 type_4->data[2] |= arfcn_high;
888 type_4->data[3] = arfcn_low;
889
890 /* patch Control Channel Description 10.5.2.11 */
891 type_3->control_channel_desc = bts->chan_desc;
892
893 /* patch BSIC */
894 msg_2[6] = bts->bsic;
895 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
896}
897
898
899static void bootstrap_rsl(struct gsm_bts_trx *trx)
900{
901 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
902 "using MCC=%u MNC=%u\n", trx->nr, trx->bts->nr, MCC, MNC);
903 set_system_infos(trx);
904}
905
906void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
907{
908 switch (event) {
909 case EVT_E1_TEI_UP:
910 switch (type) {
911 case E1INP_SIGN_OML:
912 bootstrap_om(trx->bts);
913 break;
914 case E1INP_SIGN_RSL:
915 bootstrap_rsl(trx);
916 break;
917 default:
918 break;
919 }
920 break;
921 case EVT_E1_TEI_DN:
922 fprintf(stderr, "Lost some E1 TEI link\n");
923 /* FIXME: deal with TEI or L1 link loss */
924 break;
925 default:
926 break;
927 }
928}
929
930static int bootstrap_bts(struct gsm_bts *bts)
931{
932 bts->location_area_code = LAC;
933 bts->trx[0].arfcn = ARFCN;
934
935 /* Control Channel Description */
936 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
937 bts->chan_desc.att = 1;
938 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
939 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
940 bts->chan_desc.t3212 = 0;
941
942 patch_tables(bts);
943
944 paging_init(bts);
945
946 if (bts->type == GSM_BTS_TYPE_BS11) {
947 struct gsm_bts_trx *trx = &bts->trx[0];
948 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
949 set_ts_e1link(&trx->ts[1], 0, 2, 1);
950 set_ts_e1link(&trx->ts[2], 0, 2, 2);
951 set_ts_e1link(&trx->ts[3], 0, 2, 3);
952 set_ts_e1link(&trx->ts[4], 0, 3, 0);
953 set_ts_e1link(&trx->ts[5], 0, 3, 1);
954 set_ts_e1link(&trx->ts[6], 0, 3, 2);
955 set_ts_e1link(&trx->ts[7], 0, 3, 3);
956#ifdef HAVE_TRX1
957 /* TRX 1 */
958 trx = &bts->trx[1];
959 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
960 set_ts_e1link(&trx->ts[1], 0, 2, 1);
961 set_ts_e1link(&trx->ts[2], 0, 2, 2);
962 set_ts_e1link(&trx->ts[3], 0, 2, 3);
963 set_ts_e1link(&trx->ts[4], 0, 3, 0);
964 set_ts_e1link(&trx->ts[5], 0, 3, 1);
965 set_ts_e1link(&trx->ts[6], 0, 3, 2);
966 set_ts_e1link(&trx->ts[7], 0, 3, 3);
967#endif
968 }
969
970 return 0;
971}
972
973static int bootstrap_network(void)
974{
975 struct gsm_bts *bts;
976
Holger Hans Peter Freytheref5f4182009-06-10 10:20:16 +0200977 switch(BTS_TYPE) {
978 case GSM_BTS_TYPE_NANOBTS_1800:
979 if (ARFCN < 512 || ARFCN > 885) {
980 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
981 return -EINVAL;
982 }
983 break;
984 case GSM_BTS_TYPE_BS11:
985 case GSM_BTS_TYPE_NANOBTS_900:
986 /* Assume we have a P-GSM900 here */
987 if (ARFCN < 1 || ARFCN > 124) {
988 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
989 return -EINVAL;
990 }
991 break;
992 case GSM_BTS_TYPE_UNKNOWN:
993 fprintf(stderr, "Unknown BTS. Please use the --bts-type switch\n");
994 return -EINVAL;
995 }
996
Harald Welte59b04682009-06-10 05:40:52 +0800997 /* initialize our data structures */
Harald Welte03740842009-06-10 23:11:52 +0800998 gsmnet = gsm_network_init(2, BTS_TYPE, MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +0800999 if (!gsmnet)
1000 return -ENOMEM;
1001
1002 gsmnet->name_long = "OpenBSC";
1003 gsmnet->name_short = "OpenBSC";
1004
1005 bts = &gsmnet->bts[0];
1006 bootstrap_bts(bts);
1007
1008 if (db_init(database_name)) {
1009 printf("DB: Failed to init database. Please check the option settings.\n");
1010 return -1;
1011 }
1012 printf("DB: Database initialized.\n");
1013
1014 if (db_prepare()) {
1015 printf("DB: Failed to prepare database.\n");
1016 return -1;
1017 }
1018 printf("DB: Database prepared.\n");
1019
1020 telnet_init(gsmnet, 4242);
1021
1022 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1023
1024 /* E1 mISDN input setup */
1025 if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
1026 gsmnet->num_bts = 1;
1027 return e1_config(bts, cardnr, release_l2);
1028 } else {
1029 /* FIXME: do this dynamic */
1030 bts->ip_access.site_id = 1801;
1031 bts->ip_access.bts_id = 0;
1032 bts = &gsmnet->bts[1];
1033 bootstrap_bts(bts);
1034 bts->ip_access.site_id = 1800;
1035 bts->ip_access.bts_id = 0;
1036 return ipaccess_setup(gsmnet);
1037 }
1038}
1039
1040static void create_pcap_file(char *file)
1041{
1042 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1043 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1044
1045 if (fd < 0) {
1046 perror("Failed to open file for pcap");
1047 return;
1048 }
1049
1050 e1_set_pcap_fd(fd);
1051}
1052
1053static void print_usage()
1054{
1055 printf("Usage: bsc_hack\n");
1056}
1057
1058static void print_help()
1059{
1060 printf(" Some useful help...\n");
1061 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1062 printf(" -s --disable-color\n");
1063 printf(" -n --network-code number(MNC) \n");
1064 printf(" -c --country-code number (MCC) \n");
1065 printf(" -L --location-area-code number (LAC) \n");
1066 printf(" -f --arfcn number The frequency ARFCN\n");
1067 printf(" -l --database db-name The database to use\n");
1068 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1069 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1070 printf(" -p --pcap file The filename of the pcap file\n");
1071 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
1072 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1073 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
1074 printf(" -h --help this text\n");
1075}
1076
1077static void handle_options(int argc, char** argv)
1078{
1079 while (1) {
1080 int option_index = 0, c;
1081 static struct option long_options[] = {
1082 {"help", 0, 0, 'h'},
1083 {"debug", 1, 0, 'd'},
1084 {"disable-color", 0, 0, 's'},
1085 {"network-code", 1, 0, 'n'},
1086 {"country-code", 1, 0, 'c'},
1087 {"location-area-code", 1, 0, 'L'},
1088 {"database", 1, 0, 'l'},
1089 {"authorize-everyone", 0, 0, 'a'},
1090 {"reject-cause", 1, 0, 'r'},
1091 {"pcap", 1, 0, 'p'},
1092 {"arfcn", 1, 0, 'f'},
1093 {"bts-type", 1, 0, 't'},
1094 {"cardnr", 1, 0, 'C'},
1095 {"release-l2", 0, 0, 'R'},
1096 {"timestamp", 0, 0, 'T'},
1097 {0, 0, 0, 0}
1098 };
1099
1100 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:T",
1101 long_options, &option_index);
1102 if (c == -1)
1103 break;
1104
1105 switch (c) {
1106 case 'h':
1107 print_usage();
1108 print_help();
1109 exit(0);
1110 case 's':
1111 debug_use_color(0);
1112 break;
1113 case 'd':
1114 debug_parse_category_mask(optarg);
1115 break;
1116 case 'n':
1117 MNC = atoi(optarg);
1118 break;
1119 case 'c':
1120 MCC = atoi(optarg);
1121 break;
1122 case 'L':
1123 LAC = atoi(optarg);
1124 break;
1125 case 'f':
1126 ARFCN = atoi(optarg);
1127 break;
1128 case 'l':
1129 database_name = strdup(optarg);
1130 break;
1131 case 'a':
1132 gsm0408_allow_everyone(1);
1133 break;
1134 case 'r':
1135 gsm0408_set_reject_cause(atoi(optarg));
1136 break;
1137 case 'p':
1138 create_pcap_file(optarg);
1139 break;
1140 case 't':
1141 BTS_TYPE = parse_btstype(optarg);
1142 break;
1143 case 'C':
1144 cardnr = atoi(optarg);
1145 break;
1146 case 'R':
1147 release_l2 = 1;
1148 break;
1149 case 'T':
1150 debug_timestamp(1);
1151 break;
1152 default:
1153 /* ignore */
1154 break;
1155 }
1156 }
1157}
1158
1159static void signal_handler(int signal)
1160{
1161 fprintf(stdout, "signal %u received\n", signal);
1162
1163 switch (signal) {
1164 case SIGHUP:
1165 case SIGABRT:
1166 shutdown_net(gsmnet);
1167 break;
1168 default:
1169 break;
1170 }
1171}
1172
1173int main(int argc, char **argv)
1174{
1175 int rc;
1176
1177 /* parse options */
1178 handle_options(argc, argv);
1179
1180 /* seed the PRNG */
1181 srand(time(NULL));
1182
1183 rc = bootstrap_network();
1184 if (rc < 0)
1185 exit(1);
1186
1187 signal(SIGHUP, &signal_handler);
1188 signal(SIGABRT, &signal_handler);
1189
1190 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001191 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001192 bsc_select_main(0);
1193 }
1194}