blob: 3d25ee29822ea9a1256a22661998b207f9340b4b [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001/* A hackish minimal BSC (+MSC +HLR) implementation */
2
3/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
Holger Freyther219518d2009-01-02 22:04:43 +00004 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
Harald Welte52b1f982008-12-23 20:25:15 +00005 * 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
Harald Weltef6b7a902008-12-26 00:05:11 +000023#include <unistd.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <stdarg.h>
27#include <time.h>
28#include <string.h>
Harald Weltead384642008-12-26 10:20:07 +000029#include <errno.h>
Harald Welted1252502009-01-01 01:50:32 +000030#include <signal.h>
Holger Freyther9a3ee0f2009-01-02 00:40:15 +000031#include <fcntl.h>
32#include <sys/stat.h>
Harald Welte52b1f982008-12-23 20:25:15 +000033
Holger Freytherb332f612008-12-27 12:46:51 +000034#define _GNU_SOURCE
35#include <getopt.h>
36
Harald Welte255539c2008-12-28 02:26:27 +000037#include <openbsc/db.h>
38#include <openbsc/timer.h>
Harald Welte8470bf22008-12-25 23:28:35 +000039#include <openbsc/gsm_data.h>
Harald Welte255539c2008-12-28 02:26:27 +000040#include <openbsc/gsm_04_08.h>
Harald Weltead384642008-12-26 10:20:07 +000041#include <openbsc/select.h>
Harald Welte8470bf22008-12-25 23:28:35 +000042#include <openbsc/abis_rsl.h>
43#include <openbsc/abis_nm.h>
Harald Welte702d8702008-12-26 20:25:35 +000044#include <openbsc/debug.h>
Holger Freyther5677ae32008-12-27 09:41:03 +000045#include <openbsc/misdn.h>
Holger Freyther219518d2009-01-02 22:04:43 +000046#include <openbsc/telnet_interface.h>
Harald Welte38c2f132009-01-06 23:10:57 +000047#include <openbsc/paging.h>
Harald Welte1fa60c82009-02-09 18:13:26 +000048#include <openbsc/e1_input.h>
Harald Welte52b1f982008-12-23 20:25:15 +000049
50/* global pointer to the gsm network data structure */
51static struct gsm_network *gsmnet;
52
Holger Freytherefde7fb2008-12-28 14:14:56 +000053/* MCC and MNC for the Location Area Identifier */
54static int MCC = 1;
55static int MNC = 1;
Harald Welte98981882009-01-06 18:59:11 +000056static int ARFCN = HARDCODED_ARFCN;
Harald Welte8c1d0e42009-02-15 03:38:12 +000057static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
Holger Freytherbde36102008-12-28 22:51:39 +000058static const char *database_name = "hlr.sqlite3";
Holger Freytherefde7fb2008-12-28 14:14:56 +000059
Harald Welte52b1f982008-12-23 20:25:15 +000060/* The following definitions are for OM and NM packets that we cannot yet
61 * generate by code but we just pass on */
62
63// BTS Site Manager, SET ATTRIBUTES
64
65/*
66 Object Class: BTS Site Manager
67 Instance 1: FF
68 Instance 2: FF
69 Instance 3: FF
70SET ATTRIBUTES
71 sAbisExternalTime: 2007/09/08 14:36:11
72 omLAPDRelTimer: 30sec
73 shortLAPDIntTimer: 5sec
74 emergencyTimer1: 10 minutes
75 emergencyTimer2: 0 minutes
76*/
77
78unsigned char msg_1[] =
79{
80 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
81 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
82 0x02, 0x00, 0x00
83};
84
85// BTS, SET BTS ATTRIBUTES
86
87/*
88 Object Class: BTS
89 BTS relat. Number: 0
90 Instance 2: FF
91 Instance 3: FF
92SET BTS ATTRIBUTES
93 bsIdentityCode / BSIC:
94 PLMN_colour_code: 7h
95 BS_colour_code: 7h
96 BTS Air Timer T3105: 4 ,unit 10 ms
97 btsIsHopping: FALSE
Harald Welte83282292009-02-01 16:22:19 +000098 periodCCCHLoadIndication: 1sec
Holger Freyther3b910432009-02-11 00:43:48 +000099 thresholdCCCHLoadIndication: 0%
Harald Welte52b1f982008-12-23 20:25:15 +0000100 cellAllocationNumber: 00h = GSM 900
101 enableInterferenceClass: 00h = Disabled
102 fACCHQual: 6 (FACCH stealing flags minus 1)
103 intaveParameter: 31 SACCH multiframes
104 interferenceLevelBoundaries:
105 Interference Boundary 1: 0Ah
106 Interference Boundary 2: 0Fh
107 Interference Boundary 3: 14h
108 Interference Boundary 4: 19h
109 Interference Boundary 5: 1Eh
110 mSTxPwrMax: 11
111 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
112 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
113 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
114 30=33dBm, 31=32dBm
115 ny1:
116 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
117 powerOutputThresholds:
118 Out Power Fault Threshold: -10 dB
119 Red Out Power Threshold: - 6 dB
120 Excessive Out Power Threshold: 5 dB
121 rACHBusyThreshold: -127 dBm
122 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
123 rfResourceIndicationPeriod: 125 SACCH multiframes
124 T200:
125 SDCCH: 044 in 5 ms
126 FACCH/Full rate: 031 in 5 ms
127 FACCH/Half rate: 041 in 5 ms
128 SACCH with TCH SAPI0: 090 in 10 ms
129 SACCH with SDCCH: 090 in 10 ms
130 SDCCH with SAPI3: 090 in 5 ms
131 SACCH with TCH SAPI3: 135 in 10 ms
132 tSync: 9000 units of 10 msec
133 tTrau: 9000 units of 10 msec
134 enableUmLoopTest: 00h = disabled
135 enableExcessiveDistance: 00h = Disabled
136 excessiveDistance: 64km
137 hoppingMode: 00h = baseband hopping
138 cellType: 00h = Standard Cell
139 BCCH ARFCN / bCCHFrequency: 1
140*/
141
142unsigned char msg_2[] =
143{
Harald Welte8c1d0e42009-02-15 03:38:12 +0000144 0x41, 0x01, 0x00, 0xFF, 0xFF,
145 NM_ATT_BSIC, 0x3F,
146 NM_ATT_BTS_AIR_TIMER, 0x04,
147 0x61, 0x00,
148 NM_ATT_CCCH_L_I_P, 0x01,
149 NM_ATT_CCCH_L_T, 0x00,
150 0x62, 0x00,
151 0x66, 0x00,
152 0x6E, 0x06,
153 NM_ATT_INTAVE_PARAM, 0x1F,
154 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
155 NM_ATT_CCCH_L_T, 0x23,
156 NM_ATT_GSM_TIME, 0x28, 0x00,
157 NM_ATT_ADM_STATE, 0x03,
158 NM_ATT_RACH_B_THRESH, 0x7F,
159 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
160 0x8F, 0x7D,
161 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
162 0x94, 0x23, 0x28,
163 0x95, 0x23, 0x28,
164 0x35, 0x01, 0x00,
165 0x46, 0x01, 0x00,
166 0x58, 0x01, 0x40,
167 0xC5, 0x01, 0x00,
168 0xF2, 0x01, 0x00,
169 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
Harald Welte52b1f982008-12-23 20:25:15 +0000170};
171
172// Handover Recognition, SET ATTRIBUTES
173
174/*
175Illegal Contents GSM Formatted O&M Msg
176 Object Class: Handover Recognition
177 BTS relat. Number: 0
178 Instance 2: FF
179 Instance 3: FF
180SET ATTRIBUTES
181 enableDelayPowerBudgetHO: 00h = Disabled
182 enableDistanceHO: 00h = Disabled
183 enableInternalInterCellHandover: 00h = Disabled
184 enableInternalIntraCellHandover: 00h = Disabled
185 enablePowerBudgetHO: 00h = Disabled
186 enableRXLEVHO: 00h = Disabled
187 enableRXQUALHO: 00h = Disabled
188 hoAveragingDistance: 8 SACCH multiframes
189 hoAveragingLev:
190 A_LEV_HO: 8 SACCH multiframes
191 W_LEV_HO: 1 SACCH multiframes
192 hoAveragingPowerBudget: 16 SACCH multiframes
193 hoAveragingQual:
194 A_QUAL_HO: 8 SACCH multiframes
195 W_QUAL_HO: 2 SACCH multiframes
196 hoLowerThresholdLevDL: (10 - 110) dBm
197 hoLowerThresholdLevUL: (5 - 110) dBm
198 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
199 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
200 hoThresholdLevDLintra : (20 - 110) dBm
201 hoThresholdLevULintra: (20 - 110) dBm
202 hoThresholdMsRangeMax: 20 km
203 nCell: 06h
204 timerHORequest: 3 ,unit 2 SACCH multiframes
205*/
206
207unsigned char msg_3[] =
208{
209 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
210 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
211 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
212 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
213 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
214 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
215 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
216 0x20, 0xF7, 0x01, 0x3C,
217};
218
219// Power Control, SET ATTRIBUTES
220
221/*
222 Object Class: Power Control
223 BTS relat. Number: 0
224 Instance 2: FF
225 Instance 3: FF
226SET ATTRIBUTES
227 enableMsPowerControl: 00h = Disabled
228 enablePowerControlRLFW: 00h = Disabled
229 pcAveragingLev:
230 A_LEV_PC: 4 SACCH multiframes
231 W_LEV_PC: 1 SACCH multiframes
232 pcAveragingQual:
233 A_QUAL_PC: 4 SACCH multiframes
234 W_QUAL_PC: 2 SACCH multiframes
235 pcLowerThresholdLevDL: 0Fh
236 pcLowerThresholdLevUL: 0Ah
237 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
238 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
239 pcRLFThreshold: 0Ch
240 pcUpperThresholdLevDL: 14h
241 pcUpperThresholdLevUL: 0Fh
242 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
243 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
244 powerConfirm: 2 ,unit 2 SACCH multiframes
245 powerControlInterval: 2 ,unit 2 SACCH multiframes
246 powerIncrStepSize: 02h = 4 dB
247 powerRedStepSize: 01h = 2 dB
248 radioLinkTimeoutBs: 64 SACCH multiframes
249 enableBSPowerControl: 00h = disabled
250*/
251
252unsigned char msg_4[] =
253{
254 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
255 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
256 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
257 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
258};
259
260
261// Transceiver, SET TRX ATTRIBUTES (TRX 0)
262
263/*
264 Object Class: Transceiver
265 BTS relat. Number: 0
266 Tranceiver number: 0
267 Instance 3: FF
268SET TRX ATTRIBUTES
269 aRFCNList (HEX): 0001
270 txPwrMaxReduction: 00h = 0dB
271 radioMeasGran: 254 SACCH multiframes
272 radioMeasRep: 01h = enabled
273 memberOfEmergencyConfig: 01h = TRUE
274 trxArea: 00h = TRX doesn't belong to a concentric cell
275*/
276
277unsigned char msg_6[] =
278{
279 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
280 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
281};
282
Harald Welte8c1d0e42009-02-15 03:38:12 +0000283static unsigned char nanobts_attr_bts[] = {
284 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
285 NM_ATT_INTAVE_PARAM, 0x06,
286 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
287 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
288 NM_ATT_MAX_TA, 0x3f,
289 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 0x0a,
290 NM_ATT_CCCH_L_T, 0x1e,
291 NM_ATT_CCCH_L_I_P, 0x64,
292 NM_ATT_RACH_B_THRESH, 0x0a,
293 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8,
294 NM_ATT_BTS_AIR_TIMER, 0x80,
295 NM_ATT_NY1, 0x0a,
296 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
297 NM_ATT_BSIC, 0x20,
298};
Harald Welte52b1f982008-12-23 20:25:15 +0000299
Harald Welte8c1d0e42009-02-15 03:38:12 +0000300static unsigned char nanobts_attr_radio[] = {
Harald Weltee1bd2412009-02-15 14:40:09 +0000301 NM_ATT_RF_MAXPOWR_R, 0x00,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000302 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
303};
304
Harald Welte5c1e4582009-02-15 11:57:29 +0000305static unsigned char nanobts_attr_e0[] = {
306 0x85, 0x00,
307 0x81, 0x0b, 0xbb, /* TCP PORT for RSL */
308};
309
Harald Welte8c1d0e42009-02-15 03:38:12 +0000310int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
311 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
312{
313 struct gsm_bts *bts;
314 struct gsm_bts_trx *trx;
315 struct gsm_bts_trx_ts *ts;
316
317 /* This is currently only required on nanoBTS */
318
319 switch (evt) {
320 case EVT_STATECHG_OPER:
321 switch (obj_class) {
322 case NM_OC_SITE_MANAGER:
323 bts = container_of(obj, struct gsm_bts, site_mgr);
324 if (old_state->operational != 2 && new_state->operational == 2) {
325 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
326 }
327 break;
328 case NM_OC_BTS:
329 bts = obj;
330 if (new_state->availability == 5) {
331 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
332 sizeof(nanobts_attr_bts));
333 abis_nm_opstart(bts, NM_OC_BTS,
334 bts->nr, 0xff, 0xff);
335 abis_nm_chg_adm_state(bts, NM_OC_BTS,
336 bts->nr, 0xff, 0xff,
337 NM_STATE_UNLOCKED);
338 }
339 break;
340 case NM_OC_RADIO_CARRIER:
341 trx = obj;
342 if (new_state->availability == 3) {
343 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
344 sizeof(nanobts_attr_radio));
345 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
346 trx->bts->nr, trx->nr, 0xff);
347 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
348 trx->bts->nr, trx->nr, 0xff,
349 NM_STATE_UNLOCKED);
350 }
351 break;
352 case NM_OC_CHANNEL:
353 ts = obj;
354 trx = ts->trx;
355 if (new_state->availability == 5) {
356 if (ts->nr == 0 && trx == trx->bts->c0)
Harald Weltee1bd2412009-02-15 14:40:09 +0000357 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000358 else
359 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
360 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
361 trx->bts->nr, trx->nr, ts->nr);
362 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
363 trx->bts->nr, trx->nr, ts->nr,
364 NM_STATE_UNLOCKED);
365 }
366 break;
367 case NM_OC_BASEB_TRANSC:
368 trx = container_of(obj, struct gsm_bts_trx, bb_transc);
369 if (new_state->availability == 5) {
Harald Welte5c1e4582009-02-15 11:57:29 +0000370 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
371 trx->bts->nr, trx->nr, 0xff,
372 nanobts_attr_e0, sizeof(nanobts_attr_e0));
Harald Welte8c1d0e42009-02-15 03:38:12 +0000373 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
374 trx->bts->nr, trx->nr, 0xff);
375 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
376 trx->bts->nr, trx->nr, 0xff,
377 NM_STATE_UNLOCKED);
378 }
379 break;
380 }
381 break;
382 }
383 return 0;
384}
385
386static void bootstrap_om_nanobts(struct gsm_bts *bts)
387{
Harald Weltee1bd2412009-02-15 14:40:09 +0000388 /* We don't do callback based bootstrapping, but event driven (see above) */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000389}
390
391static void bootstrap_om_bs11(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000392{
393 struct gsm_bts_trx *trx = &bts->trx[0];
394
395 /* stop sending event reports */
396 abis_nm_event_reports(bts, 0);
397
398 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000399 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000400
Harald Welte702d8702008-12-26 20:25:35 +0000401 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000402 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte702d8702008-12-26 20:25:35 +0000403
404 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000405 abis_nm_bs11_reset_resource(bts);
Harald Welte702d8702008-12-26 20:25:35 +0000406
407 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000408 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte702d8702008-12-26 20:25:35 +0000409
Harald Welte52b1f982008-12-23 20:25:15 +0000410 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
411 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
412 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
413 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
414
415 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
416 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
Harald Weltecd06bfb2009-02-10 17:33:56 +0000417 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
Harald Welte52b1f982008-12-23 20:25:15 +0000418 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
419
420 /* Use TEI 1 for signalling */
421 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
422 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
Harald Weltecd06bfb2009-02-10 17:33:56 +0000423
424#ifdef HAVE_TRX1
Harald Welte52b1f982008-12-23 20:25:15 +0000425 /* TRX 1 */
426 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
427 /* FIXME: TRX ATTRIBUTE */
428 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
429#endif
430
431 /* SET CHANNEL ATTRIBUTE TS1 */
432 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
433 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000434 set_ts_e1link(&trx->ts[1], 0, 2, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000435 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
436
437 /* SET CHANNEL ATTRIBUTE TS2 */
438 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
439 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000440 set_ts_e1link(&trx->ts[2], 0, 2, 2);
Harald Welte52b1f982008-12-23 20:25:15 +0000441 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
442
443 /* SET CHANNEL ATTRIBUTE TS3 */
444 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
445 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000446 set_ts_e1link(&trx->ts[3], 0, 2, 3);
Harald Welte52b1f982008-12-23 20:25:15 +0000447 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
448
449 /* SET CHANNEL ATTRIBUTE TS4 */
450 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
451 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000452 set_ts_e1link(&trx->ts[4], 0, 3, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000453 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
454
455 /* SET CHANNEL ATTRIBUTE TS5 */
456 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
457 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000458 set_ts_e1link(&trx->ts[5], 0, 3, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000459 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
460
461 /* SET CHANNEL ATTRIBUTE TS6 */
462 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
463 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000464 set_ts_e1link(&trx->ts[6], 0, 3, 2);
Harald Welte52b1f982008-12-23 20:25:15 +0000465 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
466
467 /* SET CHANNEL ATTRIBUTE TS7 */
468 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
469 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000470 set_ts_e1link(&trx->ts[7], 0, 3, 3);
Harald Welte52b1f982008-12-23 20:25:15 +0000471 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
472
473 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000474 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000475
476 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000477 abis_nm_bs11_reset_resource(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000478
479 /* restart sending event reports */
480 abis_nm_event_reports(bts, 1);
481}
482
Harald Welte8c1d0e42009-02-15 03:38:12 +0000483static void bootstrap_om(struct gsm_bts *bts)
484{
485 fprintf(stdout, "bootstrapping OML\n");
486
487 switch (bts->type) {
488 case GSM_BTS_TYPE_BS11:
489 bootstrap_om_bs11(bts);
490 break;
491 case GSM_BTS_TYPE_NANOBTS_900:
492 case GSM_BTS_TYPE_NANOBTS_1800:
493 bootstrap_om_nanobts(bts);
494 break;
495 default:
496 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
497 }
498}
499
Harald Welted1252502009-01-01 01:50:32 +0000500static int shutdown_om(struct gsm_bts *bts)
501{
502 /* stop sending event reports */
503 abis_nm_event_reports(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000504
Harald Welted1252502009-01-01 01:50:32 +0000505 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000506 abis_nm_bs11_db_transmission(bts, 1);
Harald Welted1252502009-01-01 01:50:32 +0000507
508 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000509 abis_nm_bs11_db_transmission(bts, 0);
Harald Welted1252502009-01-01 01:50:32 +0000510
511 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000512 abis_nm_bs11_reset_resource(bts);
Harald Welted1252502009-01-01 01:50:32 +0000513
514 return 0;
515}
516
517static int shutdown_net(struct gsm_network *net)
518{
519 int i;
520 for (i = 0; i < net->num_bts; i++) {
521 int rc;
522 rc = shutdown_om(&net->bts[i]);
523 if (rc < 0)
524 return rc;
525 }
526
527 return 0;
528}
Harald Welte52b1f982008-12-23 20:25:15 +0000529
530struct bcch_info {
531 u_int8_t type;
532 u_int8_t len;
533 const u_int8_t *data;
534};
535
536/*
537SYSTEM INFORMATION TYPE 1
538 Cell channel description
539 Format-ID bit map 0
540 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
541 RACH Control Parameters
542 maximum 7 retransmissions
543 8 slots used to spread transmission
544 cell not barred for access
545 call reestablishment not allowed
546 Access Control Class = 0000
547*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000548static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000549 /* header */0x55, 0x06, 0x19,
550 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
552 /* rach */0xD5, 0x00, 0x00,
553 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000554};
555
556/*
557 SYSTEM INFORMATION TYPE 2
558 Neighbour Cells Description
559 EXT-IND: Carries the complete BA
560 BA-IND = 0
561 Format-ID bit map 0
562 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
563 NCC permitted (NCC) = FF
564 RACH Control Parameters
565 maximum 7 retransmissions
566 8 slots used to spread transmission
567 cell not barred for access
568 call reestablishment not allowed
569 Access Control Class = 0000
570*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000571static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000572 /* header */0x59, 0x06, 0x1A,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 /* ncc */0xFF,
576 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000577};
578
579/*
580SYSTEM INFORMATION TYPE 3
581 Cell identity = 00001 (1h)
582 Location area identification
583 Mobile Country Code (MCC): 001
584 Mobile Network Code (MNC): 01
585 Location Area Code (LAC): 00001 (1h)
586 Control Channel Description
587 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
588 0 blocks reserved for access grant
589 1 channel used for CCCH, with SDCCH
590 5 multiframes period for PAGING REQUEST
591 Time-out T3212 = 0
592 Cell Options BCCH
593 Power control indicator: not set
594 MSs shall not use uplink DTX
595 Radio link timeout = 36
596 Cell Selection Parameters
597 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000598 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000599 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
600 Half rate support (NECI): New establishment causes are not supported
601 min.RX signal level for MS = 0
602 RACH Control Parameters
603 maximum 7 retransmissions
604 8 slots used to spread transmission
605 cell not barred for access
606 call reestablishment not allowed
607 Access Control Class = 0000
608 SI 3 Rest Octets
609 Cell Bar Qualify (CBQ): 0
610 Cell Reselect Offset = 0 dB
611 Temporary Offset = 0 dB
612 Penalty Time = 20 s
613 System Information 2ter Indicator (2TI): 0 = not available
614 Early Classmark Sending Control (ECSC): 0 = forbidden
615 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
616*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000617static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000618 /* header */0x49, 0x06, 0x1B,
619 /* cell */0x00, 0x01,
620 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
621 /* desc */0x01, 0x03, 0x00,
622 /* option*/0x28,
623 /* selection*/0x62, 0x00,
624 /* rach */0xD5, 0x00, 0x00,
625 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000626};
627
628/*
629SYSTEM INFORMATION TYPE 4
630 Location area identification
631 Mobile Country Code (MCC): 001
632 Mobile Network Code (MNC): 01
633 Location Area Code (LAC): 00001 (1h)
634 Cell Selection Parameters
635 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
636 max.TX power level MS may use for CCH = 2
637 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
638 Half rate support (NECI): New establishment causes are not supported
639 min.RX signal level for MS = 0
640 RACH Control Parameters
641 maximum 7 retransmissions
642 8 slots used to spread transmission
643 cell not barred for access
644 call reestablishment not allowed
645 Access Control Class = 0000
646 Channel Description
647 Type = SDCCH/4[2]
648 Timeslot Number: 0
649 Training Sequence Code: 7h
650 ARFCN: 1
651 SI Rest Octets
652 Cell Bar Qualify (CBQ): 0
653 Cell Reselect Offset = 0 dB
654 Temporary Offset = 0 dB
655 Penalty Time = 20 s
656*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000657static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000658 /* header */0x41, 0x06, 0x1C,
659 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
660 /* sel */0x62, 0x00,
661 /* rach*/0xD5, 0x00, 0x00,
662 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000663 0x2B, 0x2B, 0x2B
664};
665
666/*
667 SYSTEM INFORMATION TYPE 5
668 Neighbour Cells Description
669 EXT-IND: Carries the complete BA
670 BA-IND = 0
671 Format-ID bit map 0
672 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
673*/
674
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000675static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000676 /* header without l2 len*/0x06, 0x1D,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000679};
680
681// SYSTEM INFORMATION TYPE 6
682
683/*
684SACCH FILLING
685 System Info Type: SYSTEM INFORMATION 6
686 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
687
688SYSTEM INFORMATION TYPE 6
689 Cell identity = 00001 (1h)
690 Location area identification
691 Mobile Country Code (MCC): 001
692 Mobile Network Code (MNC): 01
693 Location Area Code (LAC): 00001 (1h)
694 Cell Options SACCH
695 Power control indicator: not set
696 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
697 Radio link timeout = 36
698 NCC permitted (NCC) = FF
699*/
700
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000701static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000702 /* header */0x06, 0x1E,
703 /* cell id*/ 0x00, 0x01,
704 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
705 /* options */ 0x28,
706 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000707};
708
709
710
711static const struct bcch_info bcch_infos[] = {
712 {
713 .type = RSL_SYSTEM_INFO_1,
714 .len = sizeof(si1),
715 .data = si1,
716 }, {
717 .type = RSL_SYSTEM_INFO_2,
718 .len = sizeof(si2),
719 .data = si2,
720 }, {
721 .type = RSL_SYSTEM_INFO_3,
722 .len = sizeof(si3),
723 .data = si3,
724 }, {
725 .type = RSL_SYSTEM_INFO_4,
726 .len = sizeof(si4),
727 .data = si4,
728 },
729};
730
Holger Freyther24287b62008-12-28 16:32:41 +0000731static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
732static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
733static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
734static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000735static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
736static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000737
Harald Welte52b1f982008-12-23 20:25:15 +0000738/* set all system information types */
Harald Weltee79769b2009-02-07 00:48:17 +0000739static int set_system_infos(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000740{
741 int i;
742
743 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
Harald Weltee79769b2009-02-07 00:48:17 +0000744 rsl_bcch_info(trx, bcch_infos[i].type,
Harald Welte52b1f982008-12-23 20:25:15 +0000745 bcch_infos[i].data,
746 bcch_infos[i].len);
747 }
Harald Weltee79769b2009-02-07 00:48:17 +0000748 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
749 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000750
751 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000752}
753
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000754/*
Harald Welte38c2f132009-01-06 23:10:57 +0000755 * Inform anyone...
756 */
757static void bsc_hack_channel_allocated(struct gsm_lchan *lchan) {
758}
759
760/*
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000761 * Patch the various SYSTEM INFORMATION tables to update
762 * the LAI
763 */
764static void patch_tables(struct gsm_bts *bts)
765{
Harald Welte98981882009-01-06 18:59:11 +0000766 u_int8_t arfcn_low = ARFCN & 0xff;
767 u_int8_t arfcn_high = (ARFCN >> 8) & 0x0f;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000768 /* covert the raw packet to the struct */
769 struct gsm48_system_information_type_3 *type_3 =
770 (struct gsm48_system_information_type_3*)&si3;
771 struct gsm48_system_information_type_4 *type_4 =
772 (struct gsm48_system_information_type_4*)&si4;
773 struct gsm48_system_information_type_6 *type_6 =
774 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000775 struct gsm48_loc_area_id lai;
776
777 gsm0408_generate_lai(&lai, bts->network->country_code,
778 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000779
780 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000781 type_3->lai = lai;
782 type_4->lai = lai;
783 type_6->lai = lai;
Harald Welte98981882009-01-06 18:59:11 +0000784
785 /* patch ARFCN */
786 msg_2[74] &= 0xf0;
787 msg_2[74] |= arfcn_high;
788 msg_2[75] = arfcn_low;
789
790 msg_6[7] &= 0xf0;
791 msg_6[7] |= arfcn_high;
792 msg_6[8] = arfcn_low;
793
794 type_4->data[2] &= 0xf0;
795 type_4->data[2] |= arfcn_high;
796 type_4->data[3] = arfcn_low;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000797
798 /* patch Control Channel Description 10.5.2.11 */
799 type_3->control_channel_desc = bts->chan_desc;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000800}
801
802
Harald Weltee79769b2009-02-07 00:48:17 +0000803static void bootstrap_rsl(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000804{
Harald Welteb84e2f42008-12-28 23:42:04 +0000805 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Harald Weltee79769b2009-02-07 00:48:17 +0000806 set_system_infos(trx);
Harald Welte52b1f982008-12-23 20:25:15 +0000807}
808
Harald Welte1fa60c82009-02-09 18:13:26 +0000809void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
Harald Weltead384642008-12-26 10:20:07 +0000810{
811 switch (event) {
Harald Welte1fa60c82009-02-09 18:13:26 +0000812 case EVT_E1_TEI_UP:
813 switch (type) {
814 case E1INP_SIGN_OML:
815 bootstrap_om(trx->bts);
816 break;
817 case E1INP_SIGN_RSL:
818 bootstrap_rsl(trx);
819 break;
820 default:
821 break;
822 }
Harald Weltead384642008-12-26 10:20:07 +0000823 break;
Harald Welte1fa60c82009-02-09 18:13:26 +0000824 case EVT_E1_TEI_DN:
825 fprintf(stderr, "Lost some E1 TEI link\n");
826 /* FIXME: deal with TEI or L1 link loss */
Harald Weltead384642008-12-26 10:20:07 +0000827 break;
828 default:
Harald Weltead384642008-12-26 10:20:07 +0000829 break;
830 }
831}
832
833static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000834{
835 struct gsm_bts *bts;
836
837 /* initialize our data structures */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000838 gsmnet = gsm_network_init(1, BTS_TYPE, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000839 if (!gsmnet)
840 return -ENOMEM;
Harald Weltef5cbab72008-12-30 18:00:15 +0000841
842 gsmnet->name_short = "25C3";
843 gsmnet->name_long = "25C3 GSM";
Harald Welte52b1f982008-12-23 20:25:15 +0000844 bts = &gsmnet->bts[0];
845 bts->location_area_code = 1;
Harald Welte98981882009-01-06 18:59:11 +0000846 bts->trx[0].arfcn = ARFCN;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000847
848 /* Control Channel Description */
849 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
850 bts->chan_desc.att = 0;
851 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
852 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
853 bts->chan_desc.t3212 = 0;
854
Harald Welte98981882009-01-06 18:59:11 +0000855 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000856
Holger Freyther1fd34142009-02-09 23:42:03 +0000857 paging_init(bts);
Holger Freytherceb59b72009-02-06 18:54:00 +0000858 bts->paging.channel_allocated = bsc_hack_channel_allocated;
Harald Welte38c2f132009-01-06 23:10:57 +0000859
Holger Freyther219518d2009-01-02 22:04:43 +0000860 telnet_init(gsmnet, 4242);
Harald Weltead384642008-12-26 10:20:07 +0000861
Harald Welte1fa60c82009-02-09 18:13:26 +0000862 /* E1 mISDN input setup */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000863 if (BTS_TYPE == GSM_BTS_TYPE_BS11)
864 return e1_config(bts);
865 else
866 return ia_config(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000867}
Harald Weltef6b7a902008-12-26 00:05:11 +0000868
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000869static void create_pcap_file(char *file)
870{
Harald Welte1fa60c82009-02-09 18:13:26 +0000871#if 0
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000872 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
873 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
874
875 if (fd < 0) {
876 perror("Failed to open file for pcap");
877 return;
878 }
879
880 mi_set_pcap_fd(fd);
Harald Welte1fa60c82009-02-09 18:13:26 +0000881#else
882 fprintf(stderr, "PCAP support currently disabled!!\n");
883#endif
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000884}
885
Holger Freytherb332f612008-12-27 12:46:51 +0000886static void print_usage()
887{
888 printf("Usage: bsc_hack\n");
889}
890
891static void print_help()
892{
893 printf(" Some useful help...\n");
894 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000895 printf(" -s --disable-color\n");
896 printf(" -n --network-code number(MNC) \n");
897 printf(" -c --country-code number (MCC) \n");
Harald Welte98981882009-01-06 18:59:11 +0000898 printf(" -f --arfcn number The frequency ARFCN\n");
Holger Freytherbde36102008-12-28 22:51:39 +0000899 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +0000900 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freythere97f7fb2008-12-31 18:52:11 +0000901 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000902 printf(" -p --pcap file The filename of the pcap file\n");
Harald Weltee1bd2412009-02-15 14:40:09 +0000903 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000904 printf(" -h --help this text\n");
905}
906
Harald Welte8c1d0e42009-02-15 03:38:12 +0000907static const char *bts_types[] = {
908 [GSM_BTS_TYPE_UNKNOWN] = "unknown",
909 [GSM_BTS_TYPE_BS11] = "bs11",
910 [GSM_BTS_TYPE_NANOBTS_900] = "nanobts900",
911 [GSM_BTS_TYPE_NANOBTS_1800] = "nanobts1800",
912};
913
914enum gsm_bts_type parse_btstype(char *arg)
915{
916 int i;
917 for (i = 0; i < ARRAY_SIZE(bts_types); i++) {
918 if (!strcmp(arg, bts_types[i]))
919 return i;
920 }
Harald Weltee1bd2412009-02-15 14:40:09 +0000921 return GSM_BTS_TYPE_BS11; /* Default: BS11 */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000922}
923
Holger Freytherb332f612008-12-27 12:46:51 +0000924static void handle_options(int argc, char** argv)
925{
926 while (1) {
927 int option_index = 0, c;
928 static struct option long_options[] = {
929 {"help", 0, 0, 'h'},
930 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000931 {"disable-color", 0, 0, 's'},
932 {"network-code", 1, 0, 'n'},
933 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000934 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +0000935 {"authorize-everyone", 0, 0, 'a'},
Holger Freythere97f7fb2008-12-31 18:52:11 +0000936 {"reject-cause", 1, 0, 'r'},
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000937 {"pcap", 1, 0, 'p'},
Harald Welte98981882009-01-06 18:59:11 +0000938 {"arfcn", 1, 0, 'f'},
Harald Welte8c1d0e42009-02-15 03:38:12 +0000939 {"bts-type", 1, 0, 't'},
Holger Freytherb332f612008-12-27 12:46:51 +0000940 {0, 0, 0, 0}
941 };
942
Harald Welte8c1d0e42009-02-15 03:38:12 +0000943 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:",
Holger Freytherb332f612008-12-27 12:46:51 +0000944 long_options, &option_index);
945 if (c == -1)
946 break;
947
948 switch (c) {
949 case 'h':
950 print_usage();
951 print_help();
952 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000953 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000954 debug_use_color(0);
955 break;
956 case 'd':
957 debug_parse_category_mask(optarg);
958 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000959 case 'n':
960 MNC = atoi(optarg);
961 break;
962 case 'c':
963 MCC = atoi(optarg);
964 break;
Harald Welte98981882009-01-06 18:59:11 +0000965 case 'f':
966 ARFCN = atoi(optarg);
967 break;
Harald Welte8965da42009-01-06 18:09:02 +0000968 case 'l':
Holger Freytherbde36102008-12-28 22:51:39 +0000969 database_name = strdup(optarg);
970 break;
Holger Freyther89824fc2008-12-30 16:18:18 +0000971 case 'a':
972 gsm0408_allow_everyone(1);
973 break;
Holger Freythere97f7fb2008-12-31 18:52:11 +0000974 case 'r':
975 gsm0408_set_reject_cause(atoi(optarg));
976 break;
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000977 case 'p':
978 create_pcap_file(optarg);
979 break;
Harald Welte8c1d0e42009-02-15 03:38:12 +0000980 case 't':
981 BTS_TYPE = parse_btstype(optarg);
982 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000983 default:
984 /* ignore */
985 break;
986 }
987 }
988}
989
Harald Welted1252502009-01-01 01:50:32 +0000990static void signal_handler(int signal)
991{
992 fprintf(stdout, "signal %u received\n", signal);
993
994 switch (signal) {
995 case SIGHUP:
996 case SIGABRT:
997 shutdown_net(gsmnet);
998 break;
999 default:
1000 break;
1001 }
1002}
1003
Harald Weltef6b7a902008-12-26 00:05:11 +00001004int main(int argc, char **argv)
1005{
Harald Welte1fa60c82009-02-09 18:13:26 +00001006 int rc;
1007
Holger Freytherb332f612008-12-27 12:46:51 +00001008 /* parse options */
1009 handle_options(argc, argv);
1010
Holger Freytherbde36102008-12-28 22:51:39 +00001011 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +00001012 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
Harald Welte1fa60c82009-02-09 18:13:26 +00001023 rc = bootstrap_network();
1024 if (rc < 0)
1025 exit(1);
Harald Weltef6b7a902008-12-26 00:05:11 +00001026
Harald Welted1252502009-01-01 01:50:32 +00001027 signal(SIGHUP, &signal_handler);
1028 signal(SIGABRT, &signal_handler);
1029
Harald Weltef6b7a902008-12-26 00:05:11 +00001030 while (1) {
1031 bsc_select_main();
1032 }
1033}