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