blob: 43f1011c71cc44ce9abc8927400d69ce16cb4c42 [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;
Harald Welte1d50e082009-06-20 18:15:19 +020062static enum gsm_band BAND = GSM_BAND_900;
Harald Welte59b04682009-06-10 05:40:52 +080063static const char *database_name = "hlr.sqlite3";
64
65/* The following definitions are for OM and NM packets that we cannot yet
66 * generate by code but we just pass on */
67
68// BTS Site Manager, SET ATTRIBUTES
69
70/*
71 Object Class: BTS Site Manager
72 Instance 1: FF
73 Instance 2: FF
74 Instance 3: FF
75SET ATTRIBUTES
76 sAbisExternalTime: 2007/09/08 14:36:11
77 omLAPDRelTimer: 30sec
78 shortLAPDIntTimer: 5sec
79 emergencyTimer1: 10 minutes
80 emergencyTimer2: 0 minutes
81*/
82
83unsigned char msg_1[] =
84{
Harald Weltea4b54d82009-06-20 10:42:17 +020085 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +080086 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
87 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
88 0x02,
89 0x00, 0x1E,
90 NM_ATT_BS11_SH_LAPD_INT_TIMER,
91 0x01, 0x05,
92 0x42, 0x02, 0x00, 0x0A,
93 0x44, 0x02, 0x00, 0x00
94};
95
96// BTS, SET BTS ATTRIBUTES
97
98/*
99 Object Class: BTS
100 BTS relat. Number: 0
101 Instance 2: FF
102 Instance 3: FF
103SET BTS ATTRIBUTES
104 bsIdentityCode / BSIC:
105 PLMN_colour_code: 7h
106 BS_colour_code: 7h
107 BTS Air Timer T3105: 4 ,unit 10 ms
108 btsIsHopping: FALSE
109 periodCCCHLoadIndication: 1sec
110 thresholdCCCHLoadIndication: 0%
111 cellAllocationNumber: 00h = GSM 900
112 enableInterferenceClass: 00h = Disabled
113 fACCHQual: 6 (FACCH stealing flags minus 1)
114 intaveParameter: 31 SACCH multiframes
115 interferenceLevelBoundaries:
116 Interference Boundary 1: 0Ah
117 Interference Boundary 2: 0Fh
118 Interference Boundary 3: 14h
119 Interference Boundary 4: 19h
120 Interference Boundary 5: 1Eh
121 mSTxPwrMax: 11
122 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
123 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
124 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
125 30=33dBm, 31=32dBm
126 ny1:
127 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
128 powerOutputThresholds:
129 Out Power Fault Threshold: -10 dB
130 Red Out Power Threshold: - 6 dB
131 Excessive Out Power Threshold: 5 dB
132 rACHBusyThreshold: -127 dBm
133 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
134 rfResourceIndicationPeriod: 125 SACCH multiframes
135 T200:
136 SDCCH: 044 in 5 ms
137 FACCH/Full rate: 031 in 5 ms
138 FACCH/Half rate: 041 in 5 ms
139 SACCH with TCH SAPI0: 090 in 10 ms
140 SACCH with SDCCH: 090 in 10 ms
141 SDCCH with SAPI3: 090 in 5 ms
142 SACCH with TCH SAPI3: 135 in 10 ms
143 tSync: 9000 units of 10 msec
144 tTrau: 9000 units of 10 msec
145 enableUmLoopTest: 00h = disabled
146 enableExcessiveDistance: 00h = Disabled
147 excessiveDistance: 64km
148 hoppingMode: 00h = baseband hopping
149 cellType: 00h = Standard Cell
150 BCCH ARFCN / bCCHFrequency: 1
151*/
152
Harald Weltea4b54d82009-06-20 10:42:17 +0200153static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800154{
Harald Welte59b04682009-06-10 05:40:52 +0800155 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{
Harald Weltea4b54d82009-06-20 10:42:17 +0200220 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800221 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{
Harald Weltea4b54d82009-06-20 10:42:17 +0200290 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800291 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
Harald Weltea4b54d82009-06-20 10:42:17 +0200329static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800330{
Harald Welte59b04682009-06-10 05:40:52 +0800331 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
332 NM_ATT_RF_MAXPOWR_R, 0x00,
333 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
334 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
335 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
336 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
337};
338
339static unsigned char nanobts_attr_bts[] = {
340 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
341 /* interference avg. period in numbers of SACCH multifr */
342 NM_ATT_INTAVE_PARAM, 0x06,
343 /* conn fail based on SACCH error rate */
344 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
345 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
346 NM_ATT_MAX_TA, 0x3f,
347 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
348 NM_ATT_CCCH_L_T, 10, /* percent */
349 NM_ATT_CCCH_L_I_P, 1, /* seconds */
350 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
351 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
352 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
353 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
354 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
355 NM_ATT_BSIC, HARDCODED_BSIC,
356};
357
358static unsigned char nanobts_attr_radio[] = {
359 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
360 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
361};
362
363static unsigned char nanobts_attr_e0[] = {
364 0x85, 0x00,
365 0x81, 0x0b, 0xbb, /* TCP PORT for RSL */
366};
367
368/* Callback function to be called whenever we get a GSM 12.21 state change event */
369int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
370 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
371{
372 struct gsm_bts *bts;
373 struct gsm_bts_trx *trx;
374 struct gsm_bts_trx_ts *ts;
375
376 /* This is currently only required on nanoBTS */
377
378 switch (evt) {
379 case EVT_STATECHG_OPER:
380 switch (obj_class) {
381 case NM_OC_SITE_MANAGER:
382 bts = container_of(obj, struct gsm_bts, site_mgr);
383 if (old_state->operational != 2 && new_state->operational == 2) {
384 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
385 }
386 break;
387 case NM_OC_BTS:
388 bts = obj;
389 if (new_state->availability == 5) {
390 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
391 sizeof(nanobts_attr_bts));
392 abis_nm_opstart(bts, NM_OC_BTS,
393 bts->bts_nr, 0xff, 0xff);
394 abis_nm_chg_adm_state(bts, NM_OC_BTS,
395 bts->bts_nr, 0xff, 0xff,
396 NM_STATE_UNLOCKED);
397 }
398 break;
399 case NM_OC_CHANNEL:
400 ts = obj;
401 trx = ts->trx;
402 if (new_state->availability == 5) {
403 if (ts->nr == 0 && trx == trx->bts->c0)
404 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
405 else
406 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
407 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
408 trx->bts->bts_nr, trx->nr, ts->nr);
409 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
410 trx->bts->bts_nr, trx->nr, ts->nr,
411 NM_STATE_UNLOCKED);
412 }
413 break;
414 default:
415 break;
416 }
417 break;
418 default:
419 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
420 break;
421 }
422 return 0;
423}
424
425/* Callback function to be called every time we receive a 12.21 SW activated report */
426static int sw_activ_rep(struct msgb *mb)
427{
428 struct abis_om_fom_hdr *foh = msgb_l3(mb);
429 struct gsm_bts_trx *trx = mb->trx;
430
431 switch (foh->obj_class) {
432 case NM_OC_BASEB_TRANSC:
433 /* TRX software is active, tell it to initiate RSL Link */
434 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
435 trx->bts->bts_nr, trx->nr, 0xff,
436 nanobts_attr_e0, sizeof(nanobts_attr_e0));
437 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
438 trx->bts->bts_nr, trx->nr, 0xff);
439 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
440 trx->bts->bts_nr, trx->nr, 0xff,
441 NM_STATE_UNLOCKED);
442 break;
443 case NM_OC_RADIO_CARRIER:
444 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
445 sizeof(nanobts_attr_radio));
446 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
447 trx->bts->bts_nr, trx->nr, 0xff);
448 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
449 trx->bts->bts_nr, trx->nr, 0xff,
450 NM_STATE_UNLOCKED);
451 break;
452 }
453 return 0;
454}
455
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200456/* Callback function for NACK on the OML NM */
457static int oml_msg_nack(int mt)
458{
459 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
460 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
461 "Was the bts type and frequency properly specified?\n");
462 exit(-1);
463 }
464
465 return 0;
466}
467
Harald Welte59b04682009-06-10 05:40:52 +0800468/* Callback function to be called every time we receive a signal from NM */
469static int nm_sig_cb(unsigned int subsys, unsigned int signal,
470 void *handler_data, void *signal_data)
471{
472 switch (signal) {
473 case S_NM_SW_ACTIV_REP:
474 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200475 case S_NM_NACK:
476 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800477 default:
478 break;
479 }
480 return 0;
481}
482
483static void bootstrap_om_nanobts(struct gsm_bts *bts)
484{
485 /* We don't do callback based bootstrapping, but event driven (see above) */
486}
487
488static void bootstrap_om_bs11(struct gsm_bts *bts)
489{
490 struct gsm_bts_trx *trx = &bts->trx[0];
491
492 /* stop sending event reports */
493 abis_nm_event_reports(bts, 0);
494
495 /* begin DB transmission */
496 abis_nm_bs11_db_transmission(bts, 1);
497
498 /* end DB transmission */
499 abis_nm_bs11_db_transmission(bts, 0);
500
501 /* Reset BTS Site manager resource */
502 abis_nm_bs11_reset_resource(bts);
503
504 /* begin DB transmission */
505 abis_nm_bs11_db_transmission(bts, 1);
506
507 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltea4b54d82009-06-20 10:42:17 +0200508 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800509 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
510 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
511
512 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
513 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
Harald Weltea4b54d82009-06-20 10:42:17 +0200514 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800515
516 /* Use TEI 1 for signalling */
517 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
518 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
519
520#ifdef HAVE_TRX1
521 /* TRX 1 */
522 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
523 /* FIXME: TRX ATTRIBUTE */
524 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
525#endif
526
527 /* SET CHANNEL ATTRIBUTE TS1 */
528 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
529 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
530 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
531
532 /* SET CHANNEL ATTRIBUTE TS2 */
533 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
534 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
535 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
536
537 /* SET CHANNEL ATTRIBUTE TS3 */
538 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
539 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
540 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
541
542 /* SET CHANNEL ATTRIBUTE TS4 */
543 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
544 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
545 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
546
547 /* SET CHANNEL ATTRIBUTE TS5 */
548 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
549 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
550 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
551
552 /* SET CHANNEL ATTRIBUTE TS6 */
553 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
554 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
555 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
556
557 /* SET CHANNEL ATTRIBUTE TS7 */
558 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
559 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
560 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
561
562 /* end DB transmission */
563 abis_nm_bs11_db_transmission(bts, 0);
564
565 /* Reset BTS Site manager resource */
566 abis_nm_bs11_reset_resource(bts);
567
568 /* restart sending event reports */
569 abis_nm_event_reports(bts, 1);
570}
571
572static void bootstrap_om(struct gsm_bts *bts)
573{
574 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
575
576 switch (bts->type) {
577 case GSM_BTS_TYPE_BS11:
578 bootstrap_om_bs11(bts);
579 break;
580 case GSM_BTS_TYPE_NANOBTS_900:
581 case GSM_BTS_TYPE_NANOBTS_1800:
582 bootstrap_om_nanobts(bts);
583 break;
584 default:
585 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
586 }
587}
588
589static int shutdown_om(struct gsm_bts *bts)
590{
591 /* stop sending event reports */
592 abis_nm_event_reports(bts, 0);
593
594 /* begin DB transmission */
595 abis_nm_bs11_db_transmission(bts, 1);
596
597 /* end DB transmission */
598 abis_nm_bs11_db_transmission(bts, 0);
599
600 /* Reset BTS Site manager resource */
601 abis_nm_bs11_reset_resource(bts);
602
603 return 0;
604}
605
606static int shutdown_net(struct gsm_network *net)
607{
608 int i;
609 for (i = 0; i < net->num_bts; i++) {
610 int rc;
611 rc = shutdown_om(&net->bts[i]);
612 if (rc < 0)
613 return rc;
614 }
615
616 return 0;
617}
618
619struct bcch_info {
620 u_int8_t type;
621 u_int8_t len;
622 const u_int8_t *data;
623};
624
625/*
626SYSTEM INFORMATION TYPE 1
627 Cell channel description
628 Format-ID bit map 0
629 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
630 RACH Control Parameters
631 maximum 7 retransmissions
632 8 slots used to spread transmission
633 cell not barred for access
634 call reestablishment not allowed
635 Access Control Class = 0000
636*/
637static u_int8_t si1[] = {
638 /* header */0x55, 0x06, 0x19,
639 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
641 /* rach */0xD5, 0x00, 0x00,
642 /* s1 reset*/0x2B
643};
644
645/*
646 SYSTEM INFORMATION TYPE 2
647 Neighbour Cells Description
648 EXT-IND: Carries the complete BA
649 BA-IND = 0
650 Format-ID bit map 0
651 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
652 NCC permitted (NCC) = FF
653 RACH Control Parameters
654 maximum 7 retransmissions
655 8 slots used to spread transmission
656 cell not barred for access
657 call reestablishment not allowed
658 Access Control Class = 0000
659*/
660static u_int8_t si2[] = {
661 /* header */0x59, 0x06, 0x1A,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 /* ncc */0xFF,
665 /* rach*/0xD5, 0x00, 0x00
666};
667
668/*
669SYSTEM INFORMATION TYPE 3
670 Cell identity = 00001 (1h)
671 Location area identification
672 Mobile Country Code (MCC): 001
673 Mobile Network Code (MNC): 01
674 Location Area Code (LAC): 00001 (1h)
675 Control Channel Description
676 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
677 0 blocks reserved for access grant
678 1 channel used for CCCH, with SDCCH
679 5 multiframes period for PAGING REQUEST
680 Time-out T3212 = 0
681 Cell Options BCCH
682 Power control indicator: not set
683 MSs shall not use uplink DTX
684 Radio link timeout = 36
685 Cell Selection Parameters
686 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
687 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
688 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
689 Half rate support (NECI): New establishment causes are not supported
690 min.RX signal level for MS = 0
691 RACH Control Parameters
692 maximum 7 retransmissions
693 8 slots used to spread transmission
694 cell not barred for access
695 call reestablishment not allowed
696 Access Control Class = 0000
697 SI 3 Rest Octets
698 Cell Bar Qualify (CBQ): 0
699 Cell Reselect Offset = 0 dB
700 Temporary Offset = 0 dB
701 Penalty Time = 20 s
702 System Information 2ter Indicator (2TI): 0 = not available
703 Early Classmark Sending Control (ECSC): 0 = forbidden
704 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
705*/
706static u_int8_t si3[] = {
707 /* header */0x49, 0x06, 0x1B,
708 /* cell */0x00, 0x01,
709 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
710 /* desc */0x01, 0x03, 0x00,
711 /* option*/0x28,
712 /* selection*/0x62, 0x00,
713 /* rach */0xD5, 0x00, 0x00,
714 /* reset*/0x80, 0x00, 0x00, 0x2B
715};
716
717/*
718SYSTEM INFORMATION TYPE 4
719 Location area identification
720 Mobile Country Code (MCC): 001
721 Mobile Network Code (MNC): 01
722 Location Area Code (LAC): 00001 (1h)
723 Cell Selection Parameters
724 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
725 max.TX power level MS may use for CCH = 2
726 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
727 Half rate support (NECI): New establishment causes are not supported
728 min.RX signal level for MS = 0
729 RACH Control Parameters
730 maximum 7 retransmissions
731 8 slots used to spread transmission
732 cell not barred for access
733 call reestablishment not allowed
734 Access Control Class = 0000
735 Channel Description
736 Type = SDCCH/4[2]
737 Timeslot Number: 0
738 Training Sequence Code: 7h
739 ARFCN: 1
740 SI Rest Octets
741 Cell Bar Qualify (CBQ): 0
742 Cell Reselect Offset = 0 dB
743 Temporary Offset = 0 dB
744 Penalty Time = 20 s
745*/
746static u_int8_t si4[] = {
747 /* header */0x41, 0x06, 0x1C,
748 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
749 /* sel */0x62, 0x00,
750 /* rach*/0xD5, 0x00, 0x00,
751 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
752 0x2B, 0x2B, 0x2B
753};
754
755/*
756 SYSTEM INFORMATION TYPE 5
757 Neighbour Cells Description
758 EXT-IND: Carries the complete BA
759 BA-IND = 0
760 Format-ID bit map 0
761 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
762*/
763
764static u_int8_t si5[] = {
765 /* header without l2 len*/0x06, 0x1D,
766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768};
769
770// SYSTEM INFORMATION TYPE 6
771
772/*
773SACCH FILLING
774 System Info Type: SYSTEM INFORMATION 6
775 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
776
777SYSTEM INFORMATION TYPE 6
778 Cell identity = 00001 (1h)
779 Location area identification
780 Mobile Country Code (MCC): 001
781 Mobile Network Code (MNC): 01
782 Location Area Code (LAC): 00001 (1h)
783 Cell Options SACCH
784 Power control indicator: not set
785 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
786 Radio link timeout = 36
787 NCC permitted (NCC) = FF
788*/
789
790static u_int8_t si6[] = {
791 /* header */0x06, 0x1E,
792 /* cell id*/ 0x00, 0x01,
793 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
794 /* options */ 0x28,
795 /* ncc */ 0xFF,
796};
797
798
799
800static const struct bcch_info bcch_infos[] = {
801 {
802 .type = RSL_SYSTEM_INFO_1,
803 .len = sizeof(si1),
804 .data = si1,
805 }, {
806 .type = RSL_SYSTEM_INFO_2,
807 .len = sizeof(si2),
808 .data = si2,
809 }, {
810 .type = RSL_SYSTEM_INFO_3,
811 .len = sizeof(si3),
812 .data = si3,
813 }, {
814 .type = RSL_SYSTEM_INFO_4,
815 .len = sizeof(si4),
816 .data = si4,
817 },
818};
819
820static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
821static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
822static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
823static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
824static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
825static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
826
827/* set all system information types */
828static int set_system_infos(struct gsm_bts_trx *trx)
829{
830 int i;
831
832 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
833 rsl_bcch_info(trx, bcch_infos[i].type,
834 bcch_infos[i].data,
835 bcch_infos[i].len);
836 }
837 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
838 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
839
840 return 0;
841}
842
843/*
844 * Patch the various SYSTEM INFORMATION tables to update
845 * the LAI
846 */
847static void patch_tables(struct gsm_bts *bts)
848{
849 u_int8_t arfcn_low = bts->trx[0].arfcn & 0xff;
850 u_int8_t arfcn_high = (bts->trx[0].arfcn >> 8) & 0x0f;
851 /* covert the raw packet to the struct */
852 struct gsm48_system_information_type_3 *type_3 =
853 (struct gsm48_system_information_type_3*)&si3;
854 struct gsm48_system_information_type_4 *type_4 =
855 (struct gsm48_system_information_type_4*)&si4;
856 struct gsm48_system_information_type_6 *type_6 =
857 (struct gsm48_system_information_type_6*)&si6;
858 struct gsm48_loc_area_id lai;
859
860 gsm0408_generate_lai(&lai, bts->network->country_code,
861 bts->network->network_code,
862 bts->location_area_code);
863
864 /* assign the MCC and MNC */
865 type_3->lai = lai;
866 type_4->lai = lai;
867 type_6->lai = lai;
868
869 /* patch ARFCN into BTS Attributes */
Harald Weltea4b54d82009-06-20 10:42:17 +0200870 bs11_attr_bts[69] &= 0xf0;
871 bs11_attr_bts[69] |= arfcn_high;
872 bs11_attr_bts[70] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800873 nanobts_attr_bts[42] &= 0xf0;
874 nanobts_attr_bts[42] |= arfcn_high;
875 nanobts_attr_bts[43] = arfcn_low;
876
877 /* patch ARFCN into TRX Attributes */
Harald Weltea4b54d82009-06-20 10:42:17 +0200878 bs11_attr_radio[2] &= 0xf0;
879 bs11_attr_radio[2] |= arfcn_high;
880 bs11_attr_radio[3] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800881 nanobts_attr_radio[5] &= 0xf0;
882 nanobts_attr_radio[5] |= arfcn_high;
883 nanobts_attr_radio[6] = arfcn_low;
884
885 type_4->data[2] &= 0xf0;
886 type_4->data[2] |= arfcn_high;
887 type_4->data[3] = arfcn_low;
888
889 /* patch Control Channel Description 10.5.2.11 */
890 type_3->control_channel_desc = bts->chan_desc;
891
892 /* patch BSIC */
Harald Weltea4b54d82009-06-20 10:42:17 +0200893 bs11_attr_bts[1] = bts->bsic;
Harald Welte59b04682009-06-10 05:40:52 +0800894 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
895}
896
897
898static void bootstrap_rsl(struct gsm_bts_trx *trx)
899{
900 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
901 "using MCC=%u MNC=%u\n", trx->nr, trx->bts->nr, MCC, MNC);
902 set_system_infos(trx);
903}
904
905void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
906{
907 switch (event) {
908 case EVT_E1_TEI_UP:
909 switch (type) {
910 case E1INP_SIGN_OML:
911 bootstrap_om(trx->bts);
912 break;
913 case E1INP_SIGN_RSL:
914 bootstrap_rsl(trx);
915 break;
916 default:
917 break;
918 }
919 break;
920 case EVT_E1_TEI_DN:
921 fprintf(stderr, "Lost some E1 TEI link\n");
922 /* FIXME: deal with TEI or L1 link loss */
923 break;
924 default:
925 break;
926 }
927}
928
929static int bootstrap_bts(struct gsm_bts *bts)
930{
Harald Welte1d50e082009-06-20 18:15:19 +0200931 bts->band = BAND;
Harald Welte59b04682009-06-10 05:40:52 +0800932 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;
Harald Welte1d50e082009-06-20 18:15:19 +02001032
Harald Welte59b04682009-06-10 05:40:52 +08001033 bts = &gsmnet->bts[1];
1034 bootstrap_bts(bts);
1035 bts->ip_access.site_id = 1800;
1036 bts->ip_access.bts_id = 0;
1037 return ipaccess_setup(gsmnet);
1038 }
1039}
1040
1041static void create_pcap_file(char *file)
1042{
1043 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1044 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1045
1046 if (fd < 0) {
1047 perror("Failed to open file for pcap");
1048 return;
1049 }
1050
1051 e1_set_pcap_fd(fd);
1052}
1053
1054static void print_usage()
1055{
1056 printf("Usage: bsc_hack\n");
1057}
1058
1059static void print_help()
1060{
1061 printf(" Some useful help...\n");
1062 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1063 printf(" -s --disable-color\n");
1064 printf(" -n --network-code number(MNC) \n");
1065 printf(" -c --country-code number (MCC) \n");
1066 printf(" -L --location-area-code number (LAC) \n");
1067 printf(" -f --arfcn number The frequency ARFCN\n");
1068 printf(" -l --database db-name The database to use\n");
1069 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1070 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1071 printf(" -p --pcap file The filename of the pcap file\n");
1072 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
1073 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1074 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
1075 printf(" -h --help this text\n");
1076}
1077
1078static void handle_options(int argc, char** argv)
1079{
1080 while (1) {
Harald Welte1d50e082009-06-20 18:15:19 +02001081 int tmp, option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001082 static struct option long_options[] = {
1083 {"help", 0, 0, 'h'},
1084 {"debug", 1, 0, 'd'},
1085 {"disable-color", 0, 0, 's'},
1086 {"network-code", 1, 0, 'n'},
1087 {"country-code", 1, 0, 'c'},
1088 {"location-area-code", 1, 0, 'L'},
1089 {"database", 1, 0, 'l'},
1090 {"authorize-everyone", 0, 0, 'a'},
1091 {"reject-cause", 1, 0, 'r'},
1092 {"pcap", 1, 0, 'p'},
1093 {"arfcn", 1, 0, 'f'},
1094 {"bts-type", 1, 0, 't'},
1095 {"cardnr", 1, 0, 'C'},
1096 {"release-l2", 0, 0, 'R'},
1097 {"timestamp", 0, 0, 'T'},
Harald Welte1d50e082009-06-20 18:15:19 +02001098 {"band", 0, 0, 'b'},
Harald Welte59b04682009-06-10 05:40:52 +08001099 {0, 0, 0, 0}
1100 };
1101
Harald Welte1d50e082009-06-20 18:15:19 +02001102 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:",
Harald Welte59b04682009-06-10 05:40:52 +08001103 long_options, &option_index);
1104 if (c == -1)
1105 break;
1106
1107 switch (c) {
1108 case 'h':
1109 print_usage();
1110 print_help();
1111 exit(0);
1112 case 's':
1113 debug_use_color(0);
1114 break;
1115 case 'd':
1116 debug_parse_category_mask(optarg);
1117 break;
1118 case 'n':
1119 MNC = atoi(optarg);
1120 break;
1121 case 'c':
1122 MCC = atoi(optarg);
1123 break;
1124 case 'L':
1125 LAC = atoi(optarg);
1126 break;
1127 case 'f':
1128 ARFCN = atoi(optarg);
1129 break;
1130 case 'l':
1131 database_name = strdup(optarg);
1132 break;
1133 case 'a':
1134 gsm0408_allow_everyone(1);
1135 break;
1136 case 'r':
1137 gsm0408_set_reject_cause(atoi(optarg));
1138 break;
1139 case 'p':
1140 create_pcap_file(optarg);
1141 break;
1142 case 't':
1143 BTS_TYPE = parse_btstype(optarg);
1144 break;
1145 case 'C':
1146 cardnr = atoi(optarg);
1147 break;
1148 case 'R':
1149 release_l2 = 1;
1150 break;
1151 case 'T':
1152 debug_timestamp(1);
1153 break;
Harald Welte1d50e082009-06-20 18:15:19 +02001154 case 'b':
1155 BAND = gsm_band_parse(atoi(optarg));
1156 break;
Harald Welte59b04682009-06-10 05:40:52 +08001157 default:
1158 /* ignore */
1159 break;
1160 }
1161 }
1162}
1163
1164static void signal_handler(int signal)
1165{
1166 fprintf(stdout, "signal %u received\n", signal);
1167
1168 switch (signal) {
1169 case SIGHUP:
1170 case SIGABRT:
1171 shutdown_net(gsmnet);
1172 break;
1173 default:
1174 break;
1175 }
1176}
1177
1178int main(int argc, char **argv)
1179{
1180 int rc;
1181
1182 /* parse options */
1183 handle_options(argc, argv);
1184
1185 /* seed the PRNG */
1186 srand(time(NULL));
1187
1188 rc = bootstrap_network();
1189 if (rc < 0)
1190 exit(1);
1191
1192 signal(SIGHUP, &signal_handler);
1193 signal(SIGABRT, &signal_handler);
1194
1195 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001196 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001197 bsc_select_main(0);
1198 }
1199}