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