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