blob: 1bfb7068b45cfe108b529bc4655377e60004792a [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;
Harald Welte52281c12009-07-21 22:12:23 +020059static int TSC = HARDCODED_TSC;
60static int BSIC = HARDCODED_BSIC;
Harald Welte59b04682009-06-10 05:40:52 +080061static 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
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +020068struct nano_bts_id {
69 struct llist_head entry;
70 int site_id;
71 int bts_id;
72};
73
74static LLIST_HEAD(nanobts_ids);
75
76
Harald Welte59b04682009-06-10 05:40:52 +080077/* The following definitions are for OM and NM packets that we cannot yet
78 * generate by code but we just pass on */
79
80// BTS Site Manager, SET ATTRIBUTES
81
82/*
83 Object Class: BTS Site Manager
84 Instance 1: FF
85 Instance 2: FF
86 Instance 3: FF
87SET ATTRIBUTES
88 sAbisExternalTime: 2007/09/08 14:36:11
89 omLAPDRelTimer: 30sec
90 shortLAPDIntTimer: 5sec
91 emergencyTimer1: 10 minutes
92 emergencyTimer2: 0 minutes
93*/
94
95unsigned char msg_1[] =
96{
Harald Weltef739ae62009-06-20 10:42:17 +020097 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +080098 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
99 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
100 0x02,
101 0x00, 0x1E,
102 NM_ATT_BS11_SH_LAPD_INT_TIMER,
103 0x01, 0x05,
104 0x42, 0x02, 0x00, 0x0A,
105 0x44, 0x02, 0x00, 0x00
106};
107
108// BTS, SET BTS ATTRIBUTES
109
110/*
111 Object Class: BTS
112 BTS relat. Number: 0
113 Instance 2: FF
114 Instance 3: FF
115SET BTS ATTRIBUTES
116 bsIdentityCode / BSIC:
117 PLMN_colour_code: 7h
118 BS_colour_code: 7h
119 BTS Air Timer T3105: 4 ,unit 10 ms
120 btsIsHopping: FALSE
121 periodCCCHLoadIndication: 1sec
122 thresholdCCCHLoadIndication: 0%
123 cellAllocationNumber: 00h = GSM 900
124 enableInterferenceClass: 00h = Disabled
125 fACCHQual: 6 (FACCH stealing flags minus 1)
126 intaveParameter: 31 SACCH multiframes
127 interferenceLevelBoundaries:
128 Interference Boundary 1: 0Ah
129 Interference Boundary 2: 0Fh
130 Interference Boundary 3: 14h
131 Interference Boundary 4: 19h
132 Interference Boundary 5: 1Eh
133 mSTxPwrMax: 11
134 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
135 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
136 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
137 30=33dBm, 31=32dBm
138 ny1:
139 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
140 powerOutputThresholds:
141 Out Power Fault Threshold: -10 dB
142 Red Out Power Threshold: - 6 dB
143 Excessive Out Power Threshold: 5 dB
144 rACHBusyThreshold: -127 dBm
145 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
146 rfResourceIndicationPeriod: 125 SACCH multiframes
147 T200:
148 SDCCH: 044 in 5 ms
149 FACCH/Full rate: 031 in 5 ms
150 FACCH/Half rate: 041 in 5 ms
151 SACCH with TCH SAPI0: 090 in 10 ms
152 SACCH with SDCCH: 090 in 10 ms
153 SDCCH with SAPI3: 090 in 5 ms
154 SACCH with TCH SAPI3: 135 in 10 ms
155 tSync: 9000 units of 10 msec
156 tTrau: 9000 units of 10 msec
157 enableUmLoopTest: 00h = disabled
158 enableExcessiveDistance: 00h = Disabled
159 excessiveDistance: 64km
160 hoppingMode: 00h = baseband hopping
161 cellType: 00h = Standard Cell
162 BCCH ARFCN / bCCHFrequency: 1
163*/
164
Harald Weltef739ae62009-06-20 10:42:17 +0200165static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800166{
Harald Welte59b04682009-06-10 05:40:52 +0800167 NM_ATT_BSIC, HARDCODED_BSIC,
168 NM_ATT_BTS_AIR_TIMER, 0x04,
169 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
170 NM_ATT_CCCH_L_I_P, 0x01,
171 NM_ATT_CCCH_L_T, 0x00,
172 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
173 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
174 NM_ATT_BS11_FACCH_QUAL, 0x06,
175 /* interference avg. period in numbers of SACCH multifr */
176 NM_ATT_INTAVE_PARAM, 0x1F,
177 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
178 NM_ATT_CCCH_L_T, 0x23,
179 NM_ATT_GSM_TIME, 0x28, 0x00,
180 NM_ATT_ADM_STATE, 0x03,
181 NM_ATT_RACH_B_THRESH, 0x7F,
182 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
183 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
184 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
185 NM_ATT_BS11_TSYNC, 0x23, 0x28,
186 NM_ATT_BS11_TTRAU, 0x23, 0x28,
187 NM_ATT_TEST_DUR, 0x01, 0x00,
188 NM_ATT_OUTST_ALARM, 0x01, 0x00,
189 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
190 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
191 NM_ATT_BS11_PLL, 0x01, 0x00,
192 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
193};
194
195// Handover Recognition, SET ATTRIBUTES
196
197/*
198Illegal Contents GSM Formatted O&M Msg
199 Object Class: Handover Recognition
200 BTS relat. Number: 0
201 Instance 2: FF
202 Instance 3: FF
203SET ATTRIBUTES
204 enableDelayPowerBudgetHO: 00h = Disabled
205 enableDistanceHO: 00h = Disabled
206 enableInternalInterCellHandover: 00h = Disabled
207 enableInternalIntraCellHandover: 00h = Disabled
208 enablePowerBudgetHO: 00h = Disabled
209 enableRXLEVHO: 00h = Disabled
210 enableRXQUALHO: 00h = Disabled
211 hoAveragingDistance: 8 SACCH multiframes
212 hoAveragingLev:
213 A_LEV_HO: 8 SACCH multiframes
214 W_LEV_HO: 1 SACCH multiframes
215 hoAveragingPowerBudget: 16 SACCH multiframes
216 hoAveragingQual:
217 A_QUAL_HO: 8 SACCH multiframes
218 W_QUAL_HO: 2 SACCH multiframes
219 hoLowerThresholdLevDL: (10 - 110) dBm
220 hoLowerThresholdLevUL: (5 - 110) dBm
221 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
222 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
223 hoThresholdLevDLintra : (20 - 110) dBm
224 hoThresholdLevULintra: (20 - 110) dBm
225 hoThresholdMsRangeMax: 20 km
226 nCell: 06h
227 timerHORequest: 3 ,unit 2 SACCH multiframes
228*/
229
230unsigned char msg_3[] =
231{
Harald Weltef739ae62009-06-20 10:42:17 +0200232 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Weltec7d75062009-07-18 16:18:11 +0200233 0xD0, 0x00, /* enableDelayPowerBudgetHO */
234 0x64, 0x00, /* enableDistanceHO */
235 0x67, 0x00, /* enableInternalInterCellHandover */
236 0x68, 0x00, /* enableInternalInterCellHandover */
237 0x6A, 0x00, /* enablePowerBudgetHO */
238 0x6C, 0x00, /* enableRXLEVHO */
239 0x6D, 0x00, /* enableRXQUALHO */
240 0x6F, 0x08, /* hoAveragingDistance */
241 0x70, 0x08, 0x01, /* hoAveragingLev */
Harald Welte59b04682009-06-10 05:40:52 +0800242 0x71, 0x10, 0x10, 0x10,
Harald Weltec7d75062009-07-18 16:18:11 +0200243 0x72, 0x08, 0x02, /* hoAveragingQual */
244 0x73, 0x0A, /* hoLowerThresholdLevDL */
245 0x74, 0x05, /* hoLowerThresholdLevUL */
246 0x75, 0x06, /* hoLowerThresholdQualDL */
247 0x76, 0x06, /* hoLowerThresholdQualUL */
248 0x78, 0x14, /* hoThresholdLevDLintra */
249 0x79, 0x14, /* hoThresholdLevULintra */
250 0x7A, 0x14, /* hoThresholdMsRangeMax */
251 0x7D, 0x06, /* nCell */
252 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
253 0x20, 0x01, 0x00,
Harald Welte59b04682009-06-10 05:40:52 +0800254 0x45, 0x01, 0x00,
255 0x48, 0x01, 0x00,
256 0x5A, 0x01, 0x00,
257 0x5B, 0x01, 0x05,
258 0x5E, 0x01, 0x1A,
259 0x5F, 0x01, 0x20,
260 0x9D, 0x01, 0x00,
261 0x47, 0x01, 0x00,
262 0x5C, 0x01, 0x64,
263 0x5D, 0x01, 0x1E,
264 0x97, 0x01, 0x20,
265 0xF7, 0x01, 0x3C,
266};
267
268// Power Control, SET ATTRIBUTES
269
270/*
271 Object Class: Power Control
272 BTS relat. Number: 0
273 Instance 2: FF
274 Instance 3: FF
275SET ATTRIBUTES
276 enableMsPowerControl: 00h = Disabled
277 enablePowerControlRLFW: 00h = Disabled
278 pcAveragingLev:
279 A_LEV_PC: 4 SACCH multiframes
280 W_LEV_PC: 1 SACCH multiframes
281 pcAveragingQual:
282 A_QUAL_PC: 4 SACCH multiframes
283 W_QUAL_PC: 2 SACCH multiframes
284 pcLowerThresholdLevDL: 0Fh
285 pcLowerThresholdLevUL: 0Ah
286 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
287 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
288 pcRLFThreshold: 0Ch
289 pcUpperThresholdLevDL: 14h
290 pcUpperThresholdLevUL: 0Fh
291 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
292 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
293 powerConfirm: 2 ,unit 2 SACCH multiframes
294 powerControlInterval: 2 ,unit 2 SACCH multiframes
295 powerIncrStepSize: 02h = 4 dB
296 powerRedStepSize: 01h = 2 dB
297 radioLinkTimeoutBs: 64 SACCH multiframes
298 enableBSPowerControl: 00h = disabled
299*/
300
301unsigned char msg_4[] =
302{
Harald Weltef739ae62009-06-20 10:42:17 +0200303 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800304 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
305 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Weltec7d75062009-07-18 16:18:11 +0200306 0x7E, 0x04, 0x01, /* pcAveragingLev */
307 0x7F, 0x04, 0x02, /* pcAveragingQual */
308 0x80, 0x0F, /* pcLowerThresholdLevDL */
309 0x81, 0x0A, /* pcLowerThresholdLevUL */
310 0x82, 0x05, /* pcLowerThresholdQualDL */
311 0x83, 0x05, /* pcLowerThresholdQualUL */
312 0x84, 0x0C, /* pcRLFThreshold */
313 0x85, 0x14, /* pcUpperThresholdLevDL */
314 0x86, 0x0F, /* pcUpperThresholdLevUL */
315 0x87, 0x04, /* pcUpperThresholdQualDL */
316 0x88, 0x04, /* pcUpperThresholdQualUL */
317 0x89, 0x02, /* powerConfirm */
318 0x8A, 0x02, /* powerConfirmInterval */
319 0x8B, 0x02, /* powerIncrStepSize */
320 0x8C, 0x01, /* powerRedStepSize */
321 0x8D, 0x40, /* radioLinkTimeoutBs */
Harald Welte59b04682009-06-10 05:40:52 +0800322 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
323};
324
325
326// Transceiver, SET TRX ATTRIBUTES (TRX 0)
327
328/*
329 Object Class: Transceiver
330 BTS relat. Number: 0
331 Tranceiver number: 0
332 Instance 3: FF
333SET TRX ATTRIBUTES
334 aRFCNList (HEX): 0001
335 txPwrMaxReduction: 00h = 30dB
336 radioMeasGran: 254 SACCH multiframes
337 radioMeasRep: 01h = enabled
338 memberOfEmergencyConfig: 01h = TRUE
339 trxArea: 00h = TRX doesn't belong to a concentric cell
340*/
341
Harald Weltef739ae62009-06-20 10:42:17 +0200342static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800343{
Harald Welte59b04682009-06-10 05:40:52 +0800344 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
345 NM_ATT_RF_MAXPOWR_R, 0x00,
346 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
347 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
348 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
349 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
350};
351
352static unsigned char nanobts_attr_bts[] = {
353 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
354 /* interference avg. period in numbers of SACCH multifr */
355 NM_ATT_INTAVE_PARAM, 0x06,
356 /* conn fail based on SACCH error rate */
357 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
358 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
359 NM_ATT_MAX_TA, 0x3f,
360 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
361 NM_ATT_CCCH_L_T, 10, /* percent */
362 NM_ATT_CCCH_L_I_P, 1, /* seconds */
363 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
364 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
365 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
366 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
367 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
368 NM_ATT_BSIC, HARDCODED_BSIC,
369};
370
371static unsigned char nanobts_attr_radio[] = {
372 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
373 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
374};
375
376static unsigned char nanobts_attr_e0[] = {
Harald Welte4206d982009-07-12 09:33:54 +0200377 NM_ATT_IPACC_STREAM_ID, 0x00,
378 NM_ATT_IPACC_DST_IP_PORT, 0x0b, 0xbb, /* TCP PORT for RSL */
Harald Welte59b04682009-06-10 05:40:52 +0800379};
380
381/* Callback function to be called whenever we get a GSM 12.21 state change event */
382int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
383 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
384{
385 struct gsm_bts *bts;
386 struct gsm_bts_trx *trx;
387 struct gsm_bts_trx_ts *ts;
388
389 /* This is currently only required on nanoBTS */
390
391 switch (evt) {
392 case EVT_STATECHG_OPER:
393 switch (obj_class) {
394 case NM_OC_SITE_MANAGER:
395 bts = container_of(obj, struct gsm_bts, site_mgr);
396 if (old_state->operational != 2 && new_state->operational == 2) {
397 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
398 }
399 break;
400 case NM_OC_BTS:
401 bts = obj;
402 if (new_state->availability == 5) {
403 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
404 sizeof(nanobts_attr_bts));
405 abis_nm_opstart(bts, NM_OC_BTS,
406 bts->bts_nr, 0xff, 0xff);
407 abis_nm_chg_adm_state(bts, NM_OC_BTS,
408 bts->bts_nr, 0xff, 0xff,
409 NM_STATE_UNLOCKED);
410 }
411 break;
412 case NM_OC_CHANNEL:
413 ts = obj;
414 trx = ts->trx;
415 if (new_state->availability == 5) {
416 if (ts->nr == 0 && trx == trx->bts->c0)
417 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
418 else
419 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
420 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
421 trx->bts->bts_nr, trx->nr, ts->nr);
422 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
423 trx->bts->bts_nr, trx->nr, ts->nr,
424 NM_STATE_UNLOCKED);
425 }
426 break;
427 default:
428 break;
429 }
430 break;
431 default:
432 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
433 break;
434 }
435 return 0;
436}
437
438/* Callback function to be called every time we receive a 12.21 SW activated report */
439static int sw_activ_rep(struct msgb *mb)
440{
441 struct abis_om_fom_hdr *foh = msgb_l3(mb);
442 struct gsm_bts_trx *trx = mb->trx;
443
444 switch (foh->obj_class) {
445 case NM_OC_BASEB_TRANSC:
446 /* TRX software is active, tell it to initiate RSL Link */
447 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
448 trx->bts->bts_nr, trx->nr, 0xff,
449 nanobts_attr_e0, sizeof(nanobts_attr_e0));
450 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
451 trx->bts->bts_nr, trx->nr, 0xff);
452 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
453 trx->bts->bts_nr, trx->nr, 0xff,
454 NM_STATE_UNLOCKED);
455 break;
456 case NM_OC_RADIO_CARRIER:
457 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
458 sizeof(nanobts_attr_radio));
459 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
460 trx->bts->bts_nr, trx->nr, 0xff);
461 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
462 trx->bts->bts_nr, trx->nr, 0xff,
463 NM_STATE_UNLOCKED);
464 break;
465 }
466 return 0;
467}
468
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200469/* Callback function for NACK on the OML NM */
470static int oml_msg_nack(int mt)
471{
472 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
473 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
474 "Was the bts type and frequency properly specified?\n");
475 exit(-1);
476 }
477
478 return 0;
479}
480
Harald Welte59b04682009-06-10 05:40:52 +0800481/* Callback function to be called every time we receive a signal from NM */
482static int nm_sig_cb(unsigned int subsys, unsigned int signal,
483 void *handler_data, void *signal_data)
484{
485 switch (signal) {
486 case S_NM_SW_ACTIV_REP:
487 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200488 case S_NM_NACK:
489 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800490 default:
491 break;
492 }
493 return 0;
494}
495
496static void bootstrap_om_nanobts(struct gsm_bts *bts)
497{
498 /* We don't do callback based bootstrapping, but event driven (see above) */
499}
500
501static void bootstrap_om_bs11(struct gsm_bts *bts)
502{
Harald Weltee712a5f2009-06-21 16:17:15 +0200503 struct gsm_bts_trx *trx = bts->c0;
Harald Welte59b04682009-06-10 05:40:52 +0800504
505 /* stop sending event reports */
506 abis_nm_event_reports(bts, 0);
507
508 /* begin DB transmission */
509 abis_nm_bs11_db_transmission(bts, 1);
510
511 /* end DB transmission */
512 abis_nm_bs11_db_transmission(bts, 0);
513
514 /* Reset BTS Site manager resource */
515 abis_nm_bs11_reset_resource(bts);
516
517 /* begin DB transmission */
518 abis_nm_bs11_db_transmission(bts, 1);
519
520 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltef739ae62009-06-20 10:42:17 +0200521 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800522 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
523 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
524
525 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
526 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
Harald Weltef739ae62009-06-20 10:42:17 +0200527 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800528
529 /* Use TEI 1 for signalling */
530 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
531 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
532
533#ifdef HAVE_TRX1
534 /* TRX 1 */
535 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
536 /* FIXME: TRX ATTRIBUTE */
537 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
538#endif
539
540 /* SET CHANNEL ATTRIBUTE TS1 */
541 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
542 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
543 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
544
545 /* SET CHANNEL ATTRIBUTE TS2 */
546 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
547 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
548 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
549
550 /* SET CHANNEL ATTRIBUTE TS3 */
551 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
552 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
553 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
554
555 /* SET CHANNEL ATTRIBUTE TS4 */
556 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
557 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
558 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
559
560 /* SET CHANNEL ATTRIBUTE TS5 */
561 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
562 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
563 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
564
565 /* SET CHANNEL ATTRIBUTE TS6 */
566 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
567 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
568 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
569
570 /* SET CHANNEL ATTRIBUTE TS7 */
571 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
572 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
573 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
574
575 /* end DB transmission */
576 abis_nm_bs11_db_transmission(bts, 0);
577
578 /* Reset BTS Site manager resource */
579 abis_nm_bs11_reset_resource(bts);
580
581 /* restart sending event reports */
582 abis_nm_event_reports(bts, 1);
583}
584
585static void bootstrap_om(struct gsm_bts *bts)
586{
587 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
588
589 switch (bts->type) {
590 case GSM_BTS_TYPE_BS11:
591 bootstrap_om_bs11(bts);
592 break;
593 case GSM_BTS_TYPE_NANOBTS_900:
594 case GSM_BTS_TYPE_NANOBTS_1800:
595 bootstrap_om_nanobts(bts);
596 break;
597 default:
598 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
599 }
600}
601
602static int shutdown_om(struct gsm_bts *bts)
603{
604 /* stop sending event reports */
605 abis_nm_event_reports(bts, 0);
606
607 /* begin DB transmission */
608 abis_nm_bs11_db_transmission(bts, 1);
609
610 /* end DB transmission */
611 abis_nm_bs11_db_transmission(bts, 0);
612
613 /* Reset BTS Site manager resource */
614 abis_nm_bs11_reset_resource(bts);
615
616 return 0;
617}
618
619static int shutdown_net(struct gsm_network *net)
620{
Harald Weltee712a5f2009-06-21 16:17:15 +0200621 struct gsm_bts *bts;
622
623 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welte59b04682009-06-10 05:40:52 +0800624 int rc;
Harald Weltee712a5f2009-06-21 16:17:15 +0200625 rc = shutdown_om(bts);
Harald Welte59b04682009-06-10 05:40:52 +0800626 if (rc < 0)
627 return rc;
628 }
629
630 return 0;
631}
632
633struct bcch_info {
634 u_int8_t type;
635 u_int8_t len;
636 const u_int8_t *data;
637};
638
639/*
640SYSTEM INFORMATION TYPE 1
641 Cell channel description
642 Format-ID bit map 0
643 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
644 RACH Control Parameters
645 maximum 7 retransmissions
646 8 slots used to spread transmission
647 cell not barred for access
648 call reestablishment not allowed
649 Access Control Class = 0000
650*/
651static u_int8_t si1[] = {
652 /* header */0x55, 0x06, 0x19,
653 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
655 /* rach */0xD5, 0x00, 0x00,
656 /* s1 reset*/0x2B
657};
658
659/*
660 SYSTEM INFORMATION TYPE 2
661 Neighbour Cells Description
662 EXT-IND: Carries the complete BA
663 BA-IND = 0
664 Format-ID bit map 0
665 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
666 NCC permitted (NCC) = FF
667 RACH Control Parameters
668 maximum 7 retransmissions
669 8 slots used to spread transmission
670 cell not barred for access
671 call reestablishment not allowed
672 Access Control Class = 0000
673*/
674static u_int8_t si2[] = {
675 /* header */0x59, 0x06, 0x1A,
676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 /* ncc */0xFF,
679 /* rach*/0xD5, 0x00, 0x00
680};
681
682/*
683SYSTEM INFORMATION TYPE 3
684 Cell identity = 00001 (1h)
685 Location area identification
686 Mobile Country Code (MCC): 001
687 Mobile Network Code (MNC): 01
688 Location Area Code (LAC): 00001 (1h)
689 Control Channel Description
690 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
691 0 blocks reserved for access grant
692 1 channel used for CCCH, with SDCCH
693 5 multiframes period for PAGING REQUEST
694 Time-out T3212 = 0
695 Cell Options BCCH
696 Power control indicator: not set
697 MSs shall not use uplink DTX
698 Radio link timeout = 36
699 Cell Selection Parameters
700 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
701 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
702 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
703 Half rate support (NECI): New establishment causes are not supported
704 min.RX signal level for MS = 0
705 RACH Control Parameters
706 maximum 7 retransmissions
707 8 slots used to spread transmission
708 cell not barred for access
709 call reestablishment not allowed
710 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200711 SI 3 Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800712*/
713static u_int8_t si3[] = {
714 /* header */0x49, 0x06, 0x1B,
715 /* cell */0x00, 0x01,
716 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
717 /* desc */0x01, 0x03, 0x00,
718 /* option*/0x28,
719 /* selection*/0x62, 0x00,
720 /* rach */0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200721 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800722};
723
724/*
725SYSTEM INFORMATION TYPE 4
726 Location area identification
727 Mobile Country Code (MCC): 001
728 Mobile Network Code (MNC): 01
729 Location Area Code (LAC): 00001 (1h)
730 Cell Selection Parameters
731 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
732 max.TX power level MS may use for CCH = 2
733 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
734 Half rate support (NECI): New establishment causes are not supported
735 min.RX signal level for MS = 0
736 RACH Control Parameters
737 maximum 7 retransmissions
738 8 slots used to spread transmission
739 cell not barred for access
740 call reestablishment not allowed
741 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200742 CBCH Channel Description
Harald Welte59b04682009-06-10 05:40:52 +0800743 Type = SDCCH/4[2]
744 Timeslot Number: 0
745 Training Sequence Code: 7h
746 ARFCN: 1
Harald Weltec1c4a952009-07-05 13:41:40 +0200747 SI Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800748*/
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,
Harald Weltec1c4a952009-07-05 13:41:40 +0200754 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
755 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800756};
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{
Harald Weltee712a5f2009-06-21 16:17:15 +0200852 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
853 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Harald Welte59b04682009-06-10 05:40:52 +0800854 /* 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;
Harald Welte52281c12009-07-21 22:12:23 +0200898
899 /* patch TSC */
900 si4[15] &= ~0xe0;
901 si4[15] |= (bts->tsc & 7) << 5;
Harald Welte59b04682009-06-10 05:40:52 +0800902}
903
904
905static void bootstrap_rsl(struct gsm_bts_trx *trx)
906{
907 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte52281c12009-07-21 22:12:23 +0200908 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
909 trx->nr, trx->bts->nr, MCC, MNC, BSIC, TSC);
Harald Welte59b04682009-06-10 05:40:52 +0800910 set_system_infos(trx);
911}
912
913void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
914{
915 switch (event) {
916 case EVT_E1_TEI_UP:
917 switch (type) {
918 case E1INP_SIGN_OML:
919 bootstrap_om(trx->bts);
920 break;
921 case E1INP_SIGN_RSL:
922 bootstrap_rsl(trx);
923 break;
924 default:
925 break;
926 }
927 break;
928 case EVT_E1_TEI_DN:
929 fprintf(stderr, "Lost some E1 TEI link\n");
930 /* FIXME: deal with TEI or L1 link loss */
931 break;
932 default:
933 break;
934 }
935}
936
937static int bootstrap_bts(struct gsm_bts *bts)
938{
Harald Welte91afe4c2009-06-20 18:15:19 +0200939 bts->band = BAND;
Harald Welte59b04682009-06-10 05:40:52 +0800940 bts->location_area_code = LAC;
Harald Weltee712a5f2009-06-21 16:17:15 +0200941 bts->c0->arfcn = ARFCN;
Harald Welte59b04682009-06-10 05:40:52 +0800942
943 /* Control Channel Description */
944 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
945 bts->chan_desc.att = 1;
946 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
947 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
948 bts->chan_desc.t3212 = 0;
949
950 patch_tables(bts);
951
952 paging_init(bts);
953
954 if (bts->type == GSM_BTS_TYPE_BS11) {
Harald Weltee712a5f2009-06-21 16:17:15 +0200955 struct gsm_bts_trx *trx = bts->c0;
Harald Welte59b04682009-06-10 05:40:52 +0800956 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
957 set_ts_e1link(&trx->ts[1], 0, 2, 1);
958 set_ts_e1link(&trx->ts[2], 0, 2, 2);
959 set_ts_e1link(&trx->ts[3], 0, 2, 3);
960 set_ts_e1link(&trx->ts[4], 0, 3, 0);
961 set_ts_e1link(&trx->ts[5], 0, 3, 1);
962 set_ts_e1link(&trx->ts[6], 0, 3, 2);
963 set_ts_e1link(&trx->ts[7], 0, 3, 3);
964#ifdef HAVE_TRX1
965 /* TRX 1 */
966 trx = &bts->trx[1];
967 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
968 set_ts_e1link(&trx->ts[1], 0, 2, 1);
969 set_ts_e1link(&trx->ts[2], 0, 2, 2);
970 set_ts_e1link(&trx->ts[3], 0, 2, 3);
971 set_ts_e1link(&trx->ts[4], 0, 3, 0);
972 set_ts_e1link(&trx->ts[5], 0, 3, 1);
973 set_ts_e1link(&trx->ts[6], 0, 3, 2);
974 set_ts_e1link(&trx->ts[7], 0, 3, 3);
975#endif
976 }
977
978 return 0;
979}
980
981static int bootstrap_network(void)
982{
Holger Hans Peter Freytheref5f4182009-06-10 10:20:16 +0200983 switch(BTS_TYPE) {
984 case GSM_BTS_TYPE_NANOBTS_1800:
985 if (ARFCN < 512 || ARFCN > 885) {
986 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
987 return -EINVAL;
988 }
989 break;
990 case GSM_BTS_TYPE_BS11:
991 case GSM_BTS_TYPE_NANOBTS_900:
992 /* Assume we have a P-GSM900 here */
993 if (ARFCN < 1 || ARFCN > 124) {
994 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
995 return -EINVAL;
996 }
997 break;
998 case GSM_BTS_TYPE_UNKNOWN:
999 fprintf(stderr, "Unknown BTS. Please use the --bts-type switch\n");
1000 return -EINVAL;
1001 }
1002
Harald Welte59b04682009-06-10 05:40:52 +08001003 /* initialize our data structures */
Harald Weltee712a5f2009-06-21 16:17:15 +02001004 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +08001005 if (!gsmnet)
1006 return -ENOMEM;
1007
1008 gsmnet->name_long = "OpenBSC";
1009 gsmnet->name_short = "OpenBSC";
1010
Harald Welte59b04682009-06-10 05:40:52 +08001011 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) {
Harald Welte52281c12009-07-21 22:12:23 +02001029 struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001030 bootstrap_bts(bts);
1031
Harald Welte59b04682009-06-10 05:40:52 +08001032 gsmnet->num_bts = 1;
1033 return e1_config(bts, cardnr, release_l2);
1034 } else {
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001035 struct nano_bts_id *bts_id;
1036 struct gsm_bts *bts;
Harald Welte91afe4c2009-06-20 18:15:19 +02001037
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001038 if (llist_empty(&nanobts_ids)) {
1039 fprintf(stderr, "You need to specify -i DEVICE_1 -i DEVICE_2 for nanoBTS.\n");
1040 return -EINVAL;
1041 }
1042
1043 llist_for_each_entry(bts_id, &nanobts_ids, entry) {
Harald Welte52281c12009-07-21 22:12:23 +02001044 bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001045 bootstrap_bts(bts);
1046 bts->ip_access.site_id = bts_id->site_id;
1047 bts->ip_access.bts_id = 0;
1048 }
1049
Harald Welte59b04682009-06-10 05:40:52 +08001050 return ipaccess_setup(gsmnet);
1051 }
1052}
1053
1054static void create_pcap_file(char *file)
1055{
1056 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1057 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1058
1059 if (fd < 0) {
1060 perror("Failed to open file for pcap");
1061 return;
1062 }
1063
1064 e1_set_pcap_fd(fd);
1065}
1066
1067static void print_usage()
1068{
1069 printf("Usage: bsc_hack\n");
1070}
1071
1072static void print_help()
1073{
1074 printf(" Some useful help...\n");
1075 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1076 printf(" -s --disable-color\n");
1077 printf(" -n --network-code number(MNC) \n");
1078 printf(" -c --country-code number (MCC) \n");
1079 printf(" -L --location-area-code number (LAC) \n");
1080 printf(" -f --arfcn number The frequency ARFCN\n");
1081 printf(" -l --database db-name The database to use\n");
1082 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1083 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1084 printf(" -p --pcap file The filename of the pcap file\n");
1085 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001086 printf(" -i --bts-id=NUMBER The known nanoBTS device numbers. Can be specified multiple times.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001087 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1088 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
1089 printf(" -h --help this text\n");
1090}
1091
1092static void handle_options(int argc, char** argv)
1093{
1094 while (1) {
Harald Weltea8379772009-06-20 22:36:41 +02001095 int option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001096 static struct option long_options[] = {
1097 {"help", 0, 0, 'h'},
1098 {"debug", 1, 0, 'd'},
1099 {"disable-color", 0, 0, 's'},
1100 {"network-code", 1, 0, 'n'},
1101 {"country-code", 1, 0, 'c'},
1102 {"location-area-code", 1, 0, 'L'},
1103 {"database", 1, 0, 'l'},
1104 {"authorize-everyone", 0, 0, 'a'},
1105 {"reject-cause", 1, 0, 'r'},
1106 {"pcap", 1, 0, 'p'},
1107 {"arfcn", 1, 0, 'f'},
1108 {"bts-type", 1, 0, 't'},
1109 {"cardnr", 1, 0, 'C'},
1110 {"release-l2", 0, 0, 'R'},
1111 {"timestamp", 0, 0, 'T'},
Harald Welte91afe4c2009-06-20 18:15:19 +02001112 {"band", 0, 0, 'b'},
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001113 {"bts-id", 1, 0, 'i'},
Harald Welte52281c12009-07-21 22:12:23 +02001114 {"tsc", 1, 0, 'S'},
1115 {"bsic", 1, 0, 'B'},
Harald Welte59b04682009-06-10 05:40:52 +08001116 {0, 0, 0, 0}
1117 };
1118
Harald Welte52281c12009-07-21 22:12:23 +02001119 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:",
Harald Welte59b04682009-06-10 05:40:52 +08001120 long_options, &option_index);
1121 if (c == -1)
1122 break;
1123
1124 switch (c) {
1125 case 'h':
1126 print_usage();
1127 print_help();
1128 exit(0);
1129 case 's':
1130 debug_use_color(0);
1131 break;
1132 case 'd':
1133 debug_parse_category_mask(optarg);
1134 break;
1135 case 'n':
1136 MNC = atoi(optarg);
1137 break;
1138 case 'c':
1139 MCC = atoi(optarg);
1140 break;
1141 case 'L':
1142 LAC = atoi(optarg);
1143 break;
1144 case 'f':
1145 ARFCN = atoi(optarg);
1146 break;
1147 case 'l':
1148 database_name = strdup(optarg);
1149 break;
1150 case 'a':
1151 gsm0408_allow_everyone(1);
1152 break;
1153 case 'r':
1154 gsm0408_set_reject_cause(atoi(optarg));
1155 break;
1156 case 'p':
1157 create_pcap_file(optarg);
1158 break;
1159 case 't':
1160 BTS_TYPE = parse_btstype(optarg);
1161 break;
1162 case 'C':
1163 cardnr = atoi(optarg);
1164 break;
1165 case 'R':
1166 release_l2 = 1;
1167 break;
1168 case 'T':
1169 debug_timestamp(1);
1170 break;
Harald Welte91afe4c2009-06-20 18:15:19 +02001171 case 'b':
1172 BAND = gsm_band_parse(atoi(optarg));
1173 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001174 case 'i': {
1175 struct nano_bts_id *bts_id = talloc_zero(tall_bsc_ctx, struct nano_bts_id);
1176 if (!bts_id) {
1177 fprintf(stderr, "Failed to allocate bts id\n");
1178 exit(-1);
1179 }
1180
1181 bts_id->site_id = atoi(optarg);
1182 llist_add(&bts_id->entry, &nanobts_ids);
1183 break;
Harald Welte52281c12009-07-21 22:12:23 +02001184 case 'S':
1185 TSC = atoi(optarg);
1186 break;
1187 case 'B':
1188 BSIC = atoi(optarg);
1189 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001190 }
Harald Welte59b04682009-06-10 05:40:52 +08001191 default:
1192 /* ignore */
1193 break;
1194 }
1195 }
1196}
1197
1198static void signal_handler(int signal)
1199{
1200 fprintf(stdout, "signal %u received\n", signal);
1201
1202 switch (signal) {
1203 case SIGHUP:
1204 case SIGABRT:
1205 shutdown_net(gsmnet);
1206 break;
Harald Weltea8379772009-06-20 22:36:41 +02001207 case SIGUSR1:
1208 talloc_report_full(tall_bsc_ctx, stderr);
1209 break;
Harald Welte59b04682009-06-10 05:40:52 +08001210 default:
1211 break;
1212 }
1213}
1214
1215int main(int argc, char **argv)
1216{
1217 int rc;
1218
Harald Weltea8379772009-06-20 22:36:41 +02001219 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1220
Harald Welte59b04682009-06-10 05:40:52 +08001221 /* parse options */
1222 handle_options(argc, argv);
1223
1224 /* seed the PRNG */
1225 srand(time(NULL));
1226
1227 rc = bootstrap_network();
1228 if (rc < 0)
1229 exit(1);
1230
1231 signal(SIGHUP, &signal_handler);
1232 signal(SIGABRT, &signal_handler);
Harald Weltea8379772009-06-20 22:36:41 +02001233 signal(SIGUSR1, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001234
1235 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001236 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001237 bsc_select_main(0);
1238 }
1239}