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