blob: 797c627836d171c211ed04d73445ec04831bdb23 [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001/* A hackish minimal BSC (+MSC +HLR) implementation */
2
Harald Welte32201c12009-03-10 12:15:10 +00003/* (C) 2008-2009 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 Welteb4630602009-05-01 15:43:22 +000049#include <openbsc/signal.h>
Harald Welte52b1f982008-12-23 20:25:15 +000050
51/* global pointer to the gsm network data structure */
Harald Welte879c85a2009-05-01 15:00:20 +000052static struct gsm_network *gsmnet;
Harald Welte52b1f982008-12-23 20:25:15 +000053
Holger Freytherefde7fb2008-12-28 14:14:56 +000054/* MCC and MNC for the Location Area Identifier */
55static int MCC = 1;
56static int MNC = 1;
Holger Freyther0a173bf2009-04-22 22:07:07 +000057static int LAC = 1;
Harald Welte98981882009-01-06 18:59:11 +000058static int ARFCN = HARDCODED_ARFCN;
Holger Freytherdda22c12009-04-22 22:07:31 +000059static int cardnr = 0;
Holger Freytherb5c00f52009-04-22 22:08:07 +000060static int release_l2 = 0;
Harald Welte8c1d0e42009-02-15 03:38:12 +000061static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
Holger Freytherbde36102008-12-28 22:51:39 +000062static const char *database_name = "hlr.sqlite3";
Holger Freytherefde7fb2008-12-28 14:14:56 +000063
Harald Welte52b1f982008-12-23 20:25:15 +000064/* The following definitions are for OM and NM packets that we cannot yet
65 * generate by code but we just pass on */
66
67// BTS Site Manager, SET ATTRIBUTES
68
69/*
70 Object Class: BTS Site Manager
71 Instance 1: FF
72 Instance 2: FF
73 Instance 3: FF
74SET ATTRIBUTES
75 sAbisExternalTime: 2007/09/08 14:36:11
76 omLAPDRelTimer: 30sec
77 shortLAPDIntTimer: 5sec
78 emergencyTimer1: 10 minutes
79 emergencyTimer2: 0 minutes
80*/
81
82unsigned char msg_1[] =
83{
Harald Weltecd993872009-02-15 16:16:28 +000084 0xD0, 0x00, 0xFF, 0xFF, 0xFF,
85 NM_ATT_BS11_ABIS_EXT_TIME, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
86 0x02, 0x00, 0x1E,
87 0xE8, 0x01, 0x05,
88 0x42, 0x02, 0x00, 0x0A,
89 0x44, 0x02, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +000090};
91
92// BTS, SET BTS ATTRIBUTES
93
94/*
95 Object Class: BTS
96 BTS relat. Number: 0
97 Instance 2: FF
98 Instance 3: FF
99SET BTS ATTRIBUTES
100 bsIdentityCode / BSIC:
101 PLMN_colour_code: 7h
102 BS_colour_code: 7h
103 BTS Air Timer T3105: 4 ,unit 10 ms
104 btsIsHopping: FALSE
Harald Welte83282292009-02-01 16:22:19 +0000105 periodCCCHLoadIndication: 1sec
Holger Freyther3b910432009-02-11 00:43:48 +0000106 thresholdCCCHLoadIndication: 0%
Harald Welte52b1f982008-12-23 20:25:15 +0000107 cellAllocationNumber: 00h = GSM 900
108 enableInterferenceClass: 00h = Disabled
109 fACCHQual: 6 (FACCH stealing flags minus 1)
110 intaveParameter: 31 SACCH multiframes
111 interferenceLevelBoundaries:
112 Interference Boundary 1: 0Ah
113 Interference Boundary 2: 0Fh
114 Interference Boundary 3: 14h
115 Interference Boundary 4: 19h
116 Interference Boundary 5: 1Eh
117 mSTxPwrMax: 11
118 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
119 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
120 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
121 30=33dBm, 31=32dBm
122 ny1:
123 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
124 powerOutputThresholds:
125 Out Power Fault Threshold: -10 dB
126 Red Out Power Threshold: - 6 dB
127 Excessive Out Power Threshold: 5 dB
128 rACHBusyThreshold: -127 dBm
129 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
130 rfResourceIndicationPeriod: 125 SACCH multiframes
131 T200:
132 SDCCH: 044 in 5 ms
133 FACCH/Full rate: 031 in 5 ms
134 FACCH/Half rate: 041 in 5 ms
135 SACCH with TCH SAPI0: 090 in 10 ms
136 SACCH with SDCCH: 090 in 10 ms
137 SDCCH with SAPI3: 090 in 5 ms
138 SACCH with TCH SAPI3: 135 in 10 ms
139 tSync: 9000 units of 10 msec
140 tTrau: 9000 units of 10 msec
141 enableUmLoopTest: 00h = disabled
142 enableExcessiveDistance: 00h = Disabled
143 excessiveDistance: 64km
144 hoppingMode: 00h = baseband hopping
145 cellType: 00h = Standard Cell
146 BCCH ARFCN / bCCHFrequency: 1
147*/
148
149unsigned char msg_2[] =
150{
Harald Welte8c1d0e42009-02-15 03:38:12 +0000151 0x41, 0x01, 0x00, 0xFF, 0xFF,
152 NM_ATT_BSIC, 0x3F,
153 NM_ATT_BTS_AIR_TIMER, 0x04,
Harald Weltecd993872009-02-15 16:16:28 +0000154 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000155 NM_ATT_CCCH_L_I_P, 0x01,
156 NM_ATT_CCCH_L_T, 0x00,
Harald Weltecd993872009-02-15 16:16:28 +0000157 NM_ATT_BS11_CELL_ALLOC_NR, 0x00,
158 NM_ATT_BS11_ENA_INTERF_CLASS, 0x00,
159 NM_ATT_BS11_FACCH_QUAL, 0x06,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000160 NM_ATT_INTAVE_PARAM, 0x1F,
161 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
162 NM_ATT_CCCH_L_T, 0x23,
163 NM_ATT_GSM_TIME, 0x28, 0x00,
164 NM_ATT_ADM_STATE, 0x03,
165 NM_ATT_RACH_B_THRESH, 0x7F,
166 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
Harald Weltecd993872009-02-15 16:16:28 +0000167 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000168 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
Harald Weltecd993872009-02-15 16:16:28 +0000169 NM_ATT_BS11_TSYNC, 0x23, 0x28,
170 NM_ATT_BS11_TTRAU, 0x23, 0x28,
171 NM_ATT_TEST_DUR, 0x01, 0x00,
172 NM_ATT_OUTST_ALARM, 0x01, 0x00,
173 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
174 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
175 NM_ATT_BS11_PLL, 0x01, 0x00,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000176 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
Harald Welte52b1f982008-12-23 20:25:15 +0000177};
178
179// Handover Recognition, SET ATTRIBUTES
180
181/*
182Illegal Contents GSM Formatted O&M Msg
183 Object Class: Handover Recognition
184 BTS relat. Number: 0
185 Instance 2: FF
186 Instance 3: FF
187SET ATTRIBUTES
188 enableDelayPowerBudgetHO: 00h = Disabled
189 enableDistanceHO: 00h = Disabled
190 enableInternalInterCellHandover: 00h = Disabled
191 enableInternalIntraCellHandover: 00h = Disabled
192 enablePowerBudgetHO: 00h = Disabled
193 enableRXLEVHO: 00h = Disabled
194 enableRXQUALHO: 00h = Disabled
195 hoAveragingDistance: 8 SACCH multiframes
196 hoAveragingLev:
197 A_LEV_HO: 8 SACCH multiframes
198 W_LEV_HO: 1 SACCH multiframes
199 hoAveragingPowerBudget: 16 SACCH multiframes
200 hoAveragingQual:
201 A_QUAL_HO: 8 SACCH multiframes
202 W_QUAL_HO: 2 SACCH multiframes
203 hoLowerThresholdLevDL: (10 - 110) dBm
204 hoLowerThresholdLevUL: (5 - 110) dBm
205 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
206 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
207 hoThresholdLevDLintra : (20 - 110) dBm
208 hoThresholdLevULintra: (20 - 110) dBm
209 hoThresholdMsRangeMax: 20 km
210 nCell: 06h
211 timerHORequest: 3 ,unit 2 SACCH multiframes
212*/
213
214unsigned char msg_3[] =
215{
Harald Weltecd993872009-02-15 16:16:28 +0000216 0xD0, 0xA1, 0x00, 0xFF, 0xFF,
217 0xD0, 0x00,
218 0x64, 0x00,
219 0x67, 0x00,
220 0x68, 0x00,
221 0x6A, 0x00,
222 0x6C, 0x00,
223 0x6D, 0x00,
224 0x6F, 0x08,
225 0x70, 0x08, 0x01,
226 0x71, 0x10, 0x10, 0x10,
227 0x72, 0x08, 0x02,
228 0x73, 0x0A,
229 0x74, 0x05,
230 0x75, 0x06,
231 0x76, 0x06,
232 0x78, 0x14,
233 0x79, 0x14,
234 0x7A, 0x14,
235 0x7D, 0x06,
236 0x92, 0x03, 0x20, 0x01, 0x00,
237 0x45, 0x01, 0x00,
238 0x48, 0x01, 0x00,
239 0x5A, 0x01, 0x00,
240 0x5B, 0x01, 0x05,
241 0x5E, 0x01, 0x1A,
242 0x5F, 0x01, 0x20,
243 0x9D, 0x01, 0x00,
244 0x47, 0x01, 0x00,
245 0x5C, 0x01, 0x64,
246 0x5D, 0x01, 0x1E,
247 0x97, 0x01, 0x20,
248 0xF7, 0x01, 0x3C,
Harald Welte52b1f982008-12-23 20:25:15 +0000249};
250
251// Power Control, SET ATTRIBUTES
252
253/*
254 Object Class: Power Control
255 BTS relat. Number: 0
256 Instance 2: FF
257 Instance 3: FF
258SET ATTRIBUTES
259 enableMsPowerControl: 00h = Disabled
260 enablePowerControlRLFW: 00h = Disabled
261 pcAveragingLev:
262 A_LEV_PC: 4 SACCH multiframes
263 W_LEV_PC: 1 SACCH multiframes
264 pcAveragingQual:
265 A_QUAL_PC: 4 SACCH multiframes
266 W_QUAL_PC: 2 SACCH multiframes
267 pcLowerThresholdLevDL: 0Fh
268 pcLowerThresholdLevUL: 0Ah
269 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
270 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
271 pcRLFThreshold: 0Ch
272 pcUpperThresholdLevDL: 14h
273 pcUpperThresholdLevUL: 0Fh
274 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
275 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
276 powerConfirm: 2 ,unit 2 SACCH multiframes
277 powerControlInterval: 2 ,unit 2 SACCH multiframes
278 powerIncrStepSize: 02h = 4 dB
279 powerRedStepSize: 01h = 2 dB
280 radioLinkTimeoutBs: 64 SACCH multiframes
281 enableBSPowerControl: 00h = disabled
282*/
283
284unsigned char msg_4[] =
285{
Harald Weltecd993872009-02-15 16:16:28 +0000286 0xD0, 0xA2, 0x00, 0xFF, 0xFF,
287 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
288 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
289 0x7E, 0x04, 0x01,
290 0x7F, 0x04, 0x02,
291 0x80, 0x0F,
292 0x81, 0x0A,
293 0x82, 0x05,
294 0x83, 0x05,
295 0x84, 0x0C,
296 0x85, 0x14,
297 0x86, 0x0F,
298 0x87, 0x04,
299 0x88, 0x04,
300 0x89, 0x02,
301 0x8A, 0x02,
302 0x8B, 0x02,
303 0x8C, 0x01,
304 0x8D, 0x40,
305 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
Harald Welte52b1f982008-12-23 20:25:15 +0000306};
307
308
309// Transceiver, SET TRX ATTRIBUTES (TRX 0)
310
311/*
312 Object Class: Transceiver
313 BTS relat. Number: 0
314 Tranceiver number: 0
315 Instance 3: FF
316SET TRX ATTRIBUTES
317 aRFCNList (HEX): 0001
Harald Weltecd993872009-02-15 16:16:28 +0000318 txPwrMaxReduction: 00h = 30dB
Harald Welte52b1f982008-12-23 20:25:15 +0000319 radioMeasGran: 254 SACCH multiframes
320 radioMeasRep: 01h = enabled
321 memberOfEmergencyConfig: 01h = TRUE
322 trxArea: 00h = TRX doesn't belong to a concentric cell
323*/
324
325unsigned char msg_6[] =
326{
Harald Weltecd993872009-02-15 16:16:28 +0000327 0x44, 0x02, 0x00, 0x00, 0xFF,
328 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
Harald Welte311d0cf2009-02-17 17:45:59 +0000329 NM_ATT_RF_MAXPOWR_R, 0x00,
Harald Weltecd993872009-02-15 16:16:28 +0000330 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
331 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
332 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
333 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000334};
335
Harald Welte8c1d0e42009-02-15 03:38:12 +0000336static unsigned char nanobts_attr_bts[] = {
337 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
338 NM_ATT_INTAVE_PARAM, 0x06,
339 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
340 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
341 NM_ATT_MAX_TA, 0x3f,
Harald Welte311d0cf2009-02-17 17:45:59 +0000342 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
343 NM_ATT_CCCH_L_T, 10, /* percent */
344 NM_ATT_CCCH_L_I_P, 1, /* seconds */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000345 NM_ATT_RACH_B_THRESH, 0x0a,
346 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8,
347 NM_ATT_BTS_AIR_TIMER, 0x80,
348 NM_ATT_NY1, 0x0a,
349 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
350 NM_ATT_BSIC, 0x20,
351};
Harald Welte52b1f982008-12-23 20:25:15 +0000352
Harald Welte8c1d0e42009-02-15 03:38:12 +0000353static unsigned char nanobts_attr_radio[] = {
Harald Welte311d0cf2009-02-17 17:45:59 +0000354 NM_ATT_RF_MAXPOWR_R, 0x0c,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000355 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
356};
357
Harald Welte5c1e4582009-02-15 11:57:29 +0000358static unsigned char nanobts_attr_e0[] = {
359 0x85, 0x00,
360 0x81, 0x0b, 0xbb, /* TCP PORT for RSL */
361};
362
Harald Welteb4630602009-05-01 15:43:22 +0000363/* Callback function to be called whenever we get a GSM 12.21 state change event */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000364int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
365 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
366{
367 struct gsm_bts *bts;
368 struct gsm_bts_trx *trx;
369 struct gsm_bts_trx_ts *ts;
370
371 /* This is currently only required on nanoBTS */
372
373 switch (evt) {
374 case EVT_STATECHG_OPER:
375 switch (obj_class) {
376 case NM_OC_SITE_MANAGER:
377 bts = container_of(obj, struct gsm_bts, site_mgr);
378 if (old_state->operational != 2 && new_state->operational == 2) {
379 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
380 }
381 break;
382 case NM_OC_BTS:
383 bts = obj;
384 if (new_state->availability == 5) {
385 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
386 sizeof(nanobts_attr_bts));
387 abis_nm_opstart(bts, NM_OC_BTS,
Harald Welte191280d2009-05-01 13:20:04 +0000388 bts->bts_nr, 0xff, 0xff);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000389 abis_nm_chg_adm_state(bts, NM_OC_BTS,
Harald Welte191280d2009-05-01 13:20:04 +0000390 bts->bts_nr, 0xff, 0xff,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000391 NM_STATE_UNLOCKED);
392 }
393 break;
Harald Welte8c1d0e42009-02-15 03:38:12 +0000394 case NM_OC_CHANNEL:
395 ts = obj;
396 trx = ts->trx;
397 if (new_state->availability == 5) {
398 if (ts->nr == 0 && trx == trx->bts->c0)
Harald Weltee1bd2412009-02-15 14:40:09 +0000399 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000400 else
401 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
402 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
Harald Welte191280d2009-05-01 13:20:04 +0000403 trx->bts->bts_nr, trx->nr, ts->nr);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000404 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
Harald Welte191280d2009-05-01 13:20:04 +0000405 trx->bts->bts_nr, trx->nr, ts->nr,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000406 NM_STATE_UNLOCKED);
407 }
408 break;
Harald Weltea994a482009-05-01 15:54:23 +0000409 default:
Harald Welte8c1d0e42009-02-15 03:38:12 +0000410 break;
411 }
412 break;
Harald Weltea994a482009-05-01 15:54:23 +0000413 default:
414 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
Holger Freytherff9592f2009-03-09 16:17:14 +0000415 break;
Harald Welte8c1d0e42009-02-15 03:38:12 +0000416 }
417 return 0;
418}
419
Harald Welteb4630602009-05-01 15:43:22 +0000420/* Callback function to be called every time we receive a 12.21 SW activated report */
421static int sw_activ_rep(struct msgb *mb)
422{
423 struct abis_om_fom_hdr *foh = msgb_l3(mb);
424 struct gsm_bts_trx *trx = mb->trx;
425
426 switch (foh->obj_class) {
427 case NM_OC_BASEB_TRANSC:
428 /* TRX software is active, tell it to initiate RSL Link */
429 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
430 trx->bts->bts_nr, trx->nr, 0xff,
431 nanobts_attr_e0, sizeof(nanobts_attr_e0));
432 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
433 trx->bts->bts_nr, trx->nr, 0xff);
434 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
435 trx->bts->bts_nr, trx->nr, 0xff,
436 NM_STATE_UNLOCKED);
437 break;
438 case NM_OC_RADIO_CARRIER:
439 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
440 sizeof(nanobts_attr_radio));
441 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
442 trx->bts->bts_nr, trx->nr, 0xff);
443 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
444 trx->bts->bts_nr, trx->nr, 0xff,
445 NM_STATE_UNLOCKED);
446 break;
447 }
448 return 0;
449}
450
451/* Callback function to be called every time we receive a signal from NM */
452static int nm_sig_cb(unsigned int subsys, unsigned int signal,
453 void *handler_data, void *signal_data)
454{
455 switch (signal) {
456 case S_NM_SW_ACTIV_REP:
457 return sw_activ_rep(signal_data);
458 default:
459 break;
460 }
461 return 0;
462}
463
Harald Welte8c1d0e42009-02-15 03:38:12 +0000464static void bootstrap_om_nanobts(struct gsm_bts *bts)
465{
Harald Weltee1bd2412009-02-15 14:40:09 +0000466 /* We don't do callback based bootstrapping, but event driven (see above) */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000467}
468
469static void bootstrap_om_bs11(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000470{
471 struct gsm_bts_trx *trx = &bts->trx[0];
472
473 /* stop sending event reports */
474 abis_nm_event_reports(bts, 0);
475
476 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000477 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000478
Harald Welte702d8702008-12-26 20:25:35 +0000479 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000480 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte702d8702008-12-26 20:25:35 +0000481
482 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000483 abis_nm_bs11_reset_resource(bts);
Harald Welte702d8702008-12-26 20:25:35 +0000484
485 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000486 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte702d8702008-12-26 20:25:35 +0000487
Harald Welte52b1f982008-12-23 20:25:15 +0000488 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
489 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
490 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
491 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
492
493 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
494 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
Harald Weltecd06bfb2009-02-10 17:33:56 +0000495 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
Harald Welte52b1f982008-12-23 20:25:15 +0000496 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
497
498 /* Use TEI 1 for signalling */
499 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
500 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
Harald Weltecd06bfb2009-02-10 17:33:56 +0000501
502#ifdef HAVE_TRX1
Harald Welte52b1f982008-12-23 20:25:15 +0000503 /* TRX 1 */
504 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
505 /* FIXME: TRX ATTRIBUTE */
506 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
507#endif
508
509 /* SET CHANNEL ATTRIBUTE TS1 */
Harald Welte23887b62009-02-18 03:37:20 +0000510 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
Harald Welte52b1f982008-12-23 20:25:15 +0000511 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000512 set_ts_e1link(&trx->ts[1], 0, 2, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000513 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
514
515 /* SET CHANNEL ATTRIBUTE TS2 */
Harald Welte23887b62009-02-18 03:37:20 +0000516 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
Harald Welte52b1f982008-12-23 20:25:15 +0000517 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000518 set_ts_e1link(&trx->ts[2], 0, 2, 2);
Harald Welte52b1f982008-12-23 20:25:15 +0000519 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
520
521 /* SET CHANNEL ATTRIBUTE TS3 */
Harald Welte23887b62009-02-18 03:37:20 +0000522 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
Harald Welte52b1f982008-12-23 20:25:15 +0000523 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000524 set_ts_e1link(&trx->ts[3], 0, 2, 3);
Harald Welte52b1f982008-12-23 20:25:15 +0000525 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
526
527 /* SET CHANNEL ATTRIBUTE TS4 */
Harald Welte23887b62009-02-18 03:37:20 +0000528 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
Harald Welte52b1f982008-12-23 20:25:15 +0000529 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000530 set_ts_e1link(&trx->ts[4], 0, 3, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000531 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
532
533 /* SET CHANNEL ATTRIBUTE TS5 */
Harald Welte23887b62009-02-18 03:37:20 +0000534 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
Harald Welte52b1f982008-12-23 20:25:15 +0000535 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000536 set_ts_e1link(&trx->ts[5], 0, 3, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000537 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
538
539 /* SET CHANNEL ATTRIBUTE TS6 */
Harald Welte23887b62009-02-18 03:37:20 +0000540 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
Harald Welte52b1f982008-12-23 20:25:15 +0000541 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000542 set_ts_e1link(&trx->ts[6], 0, 3, 2);
Harald Welte52b1f982008-12-23 20:25:15 +0000543 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
544
545 /* SET CHANNEL ATTRIBUTE TS7 */
Harald Welte23887b62009-02-18 03:37:20 +0000546 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
Harald Welte52b1f982008-12-23 20:25:15 +0000547 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecd06bfb2009-02-10 17:33:56 +0000548 set_ts_e1link(&trx->ts[7], 0, 3, 3);
Harald Welte52b1f982008-12-23 20:25:15 +0000549 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
550
551 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000552 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000553
554 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000555 abis_nm_bs11_reset_resource(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000556
557 /* restart sending event reports */
558 abis_nm_event_reports(bts, 1);
559}
560
Harald Welte8c1d0e42009-02-15 03:38:12 +0000561static void bootstrap_om(struct gsm_bts *bts)
562{
Harald Welteedb37782009-05-01 14:59:07 +0000563 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000564
565 switch (bts->type) {
566 case GSM_BTS_TYPE_BS11:
567 bootstrap_om_bs11(bts);
568 break;
569 case GSM_BTS_TYPE_NANOBTS_900:
570 case GSM_BTS_TYPE_NANOBTS_1800:
571 bootstrap_om_nanobts(bts);
572 break;
573 default:
574 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
575 }
576}
577
Harald Welted1252502009-01-01 01:50:32 +0000578static int shutdown_om(struct gsm_bts *bts)
579{
580 /* stop sending event reports */
581 abis_nm_event_reports(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000582
Harald Welted1252502009-01-01 01:50:32 +0000583 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000584 abis_nm_bs11_db_transmission(bts, 1);
Harald Welted1252502009-01-01 01:50:32 +0000585
586 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000587 abis_nm_bs11_db_transmission(bts, 0);
Harald Welted1252502009-01-01 01:50:32 +0000588
589 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000590 abis_nm_bs11_reset_resource(bts);
Harald Welted1252502009-01-01 01:50:32 +0000591
592 return 0;
593}
594
595static int shutdown_net(struct gsm_network *net)
596{
597 int i;
598 for (i = 0; i < net->num_bts; i++) {
599 int rc;
600 rc = shutdown_om(&net->bts[i]);
601 if (rc < 0)
602 return rc;
603 }
604
605 return 0;
606}
Harald Welte52b1f982008-12-23 20:25:15 +0000607
608struct bcch_info {
609 u_int8_t type;
610 u_int8_t len;
611 const u_int8_t *data;
612};
613
614/*
615SYSTEM INFORMATION TYPE 1
616 Cell channel description
617 Format-ID bit map 0
618 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
619 RACH Control Parameters
620 maximum 7 retransmissions
621 8 slots used to spread transmission
622 cell not barred for access
623 call reestablishment not allowed
624 Access Control Class = 0000
625*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000626static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000627 /* header */0x55, 0x06, 0x19,
628 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
630 /* rach */0xD5, 0x00, 0x00,
631 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000632};
633
634/*
635 SYSTEM INFORMATION TYPE 2
636 Neighbour Cells Description
637 EXT-IND: Carries the complete BA
638 BA-IND = 0
639 Format-ID bit map 0
640 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
641 NCC permitted (NCC) = FF
642 RACH Control Parameters
643 maximum 7 retransmissions
644 8 slots used to spread transmission
645 cell not barred for access
646 call reestablishment not allowed
647 Access Control Class = 0000
648*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000649static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000650 /* header */0x59, 0x06, 0x1A,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 /* ncc */0xFF,
654 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000655};
656
657/*
658SYSTEM INFORMATION TYPE 3
659 Cell identity = 00001 (1h)
660 Location area identification
661 Mobile Country Code (MCC): 001
662 Mobile Network Code (MNC): 01
663 Location Area Code (LAC): 00001 (1h)
664 Control Channel Description
665 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
666 0 blocks reserved for access grant
667 1 channel used for CCCH, with SDCCH
668 5 multiframes period for PAGING REQUEST
669 Time-out T3212 = 0
670 Cell Options BCCH
671 Power control indicator: not set
672 MSs shall not use uplink DTX
673 Radio link timeout = 36
674 Cell Selection Parameters
675 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000676 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000677 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
678 Half rate support (NECI): New establishment causes are not supported
679 min.RX signal level for MS = 0
680 RACH Control Parameters
681 maximum 7 retransmissions
682 8 slots used to spread transmission
683 cell not barred for access
684 call reestablishment not allowed
685 Access Control Class = 0000
686 SI 3 Rest Octets
687 Cell Bar Qualify (CBQ): 0
688 Cell Reselect Offset = 0 dB
689 Temporary Offset = 0 dB
690 Penalty Time = 20 s
691 System Information 2ter Indicator (2TI): 0 = not available
692 Early Classmark Sending Control (ECSC): 0 = forbidden
693 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
694*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000695static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000696 /* header */0x49, 0x06, 0x1B,
697 /* cell */0x00, 0x01,
698 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
699 /* desc */0x01, 0x03, 0x00,
700 /* option*/0x28,
701 /* selection*/0x62, 0x00,
702 /* rach */0xD5, 0x00, 0x00,
703 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000704};
705
706/*
707SYSTEM INFORMATION TYPE 4
708 Location area identification
709 Mobile Country Code (MCC): 001
710 Mobile Network Code (MNC): 01
711 Location Area Code (LAC): 00001 (1h)
712 Cell Selection Parameters
713 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
714 max.TX power level MS may use for CCH = 2
715 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
716 Half rate support (NECI): New establishment causes are not supported
717 min.RX signal level for MS = 0
718 RACH Control Parameters
719 maximum 7 retransmissions
720 8 slots used to spread transmission
721 cell not barred for access
722 call reestablishment not allowed
723 Access Control Class = 0000
724 Channel Description
725 Type = SDCCH/4[2]
726 Timeslot Number: 0
727 Training Sequence Code: 7h
728 ARFCN: 1
729 SI Rest Octets
730 Cell Bar Qualify (CBQ): 0
731 Cell Reselect Offset = 0 dB
732 Temporary Offset = 0 dB
733 Penalty Time = 20 s
734*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000735static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000736 /* header */0x41, 0x06, 0x1C,
737 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
738 /* sel */0x62, 0x00,
739 /* rach*/0xD5, 0x00, 0x00,
740 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000741 0x2B, 0x2B, 0x2B
742};
743
744/*
745 SYSTEM INFORMATION TYPE 5
746 Neighbour Cells Description
747 EXT-IND: Carries the complete BA
748 BA-IND = 0
749 Format-ID bit map 0
750 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
751*/
752
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000753static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000754 /* header without l2 len*/0x06, 0x1D,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000757};
758
759// SYSTEM INFORMATION TYPE 6
760
761/*
762SACCH FILLING
763 System Info Type: SYSTEM INFORMATION 6
764 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
765
766SYSTEM INFORMATION TYPE 6
767 Cell identity = 00001 (1h)
768 Location area identification
769 Mobile Country Code (MCC): 001
770 Mobile Network Code (MNC): 01
771 Location Area Code (LAC): 00001 (1h)
772 Cell Options SACCH
773 Power control indicator: not set
774 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
775 Radio link timeout = 36
776 NCC permitted (NCC) = FF
777*/
778
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000779static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000780 /* header */0x06, 0x1E,
781 /* cell id*/ 0x00, 0x01,
782 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
783 /* options */ 0x28,
784 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000785};
786
787
788
789static const struct bcch_info bcch_infos[] = {
790 {
791 .type = RSL_SYSTEM_INFO_1,
792 .len = sizeof(si1),
793 .data = si1,
794 }, {
795 .type = RSL_SYSTEM_INFO_2,
796 .len = sizeof(si2),
797 .data = si2,
798 }, {
799 .type = RSL_SYSTEM_INFO_3,
800 .len = sizeof(si3),
801 .data = si3,
802 }, {
803 .type = RSL_SYSTEM_INFO_4,
804 .len = sizeof(si4),
805 .data = si4,
806 },
807};
808
Holger Freyther24287b62008-12-28 16:32:41 +0000809static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
810static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
811static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
812static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000813static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
814static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000815
Harald Welte52b1f982008-12-23 20:25:15 +0000816/* set all system information types */
Harald Weltee79769b2009-02-07 00:48:17 +0000817static int set_system_infos(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000818{
819 int i;
820
821 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
Harald Weltee79769b2009-02-07 00:48:17 +0000822 rsl_bcch_info(trx, bcch_infos[i].type,
Harald Welte52b1f982008-12-23 20:25:15 +0000823 bcch_infos[i].data,
824 bcch_infos[i].len);
825 }
Harald Weltee79769b2009-02-07 00:48:17 +0000826 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
827 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000828
829 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000830}
831
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000832/*
833 * Patch the various SYSTEM INFORMATION tables to update
834 * the LAI
835 */
836static void patch_tables(struct gsm_bts *bts)
837{
Harald Welte98981882009-01-06 18:59:11 +0000838 u_int8_t arfcn_low = ARFCN & 0xff;
839 u_int8_t arfcn_high = (ARFCN >> 8) & 0x0f;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000840 /* covert the raw packet to the struct */
841 struct gsm48_system_information_type_3 *type_3 =
842 (struct gsm48_system_information_type_3*)&si3;
843 struct gsm48_system_information_type_4 *type_4 =
844 (struct gsm48_system_information_type_4*)&si4;
845 struct gsm48_system_information_type_6 *type_6 =
846 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000847 struct gsm48_loc_area_id lai;
848
849 gsm0408_generate_lai(&lai, bts->network->country_code,
850 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000851
852 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000853 type_3->lai = lai;
854 type_4->lai = lai;
855 type_6->lai = lai;
Harald Welte98981882009-01-06 18:59:11 +0000856
Harald Welte94009322009-02-15 15:38:42 +0000857 /* patch ARFCN into BTS Attributes */
Harald Welte98981882009-01-06 18:59:11 +0000858 msg_2[74] &= 0xf0;
859 msg_2[74] |= arfcn_high;
860 msg_2[75] = arfcn_low;
Harald Welte94009322009-02-15 15:38:42 +0000861 nanobts_attr_bts[42] &= 0xf0;
862 nanobts_attr_bts[42] |= arfcn_high;
863 nanobts_attr_bts[43] = arfcn_low;
Harald Welte98981882009-01-06 18:59:11 +0000864
Harald Welte94009322009-02-15 15:38:42 +0000865 /* patch ARFCN into TRX Attributes */
Harald Welte98981882009-01-06 18:59:11 +0000866 msg_6[7] &= 0xf0;
867 msg_6[7] |= arfcn_high;
868 msg_6[8] = arfcn_low;
Harald Welte94009322009-02-15 15:38:42 +0000869 nanobts_attr_radio[5] &= 0xf0;
870 nanobts_attr_radio[5] |= arfcn_high;
871 nanobts_attr_radio[6] = arfcn_low;
Harald Welte98981882009-01-06 18:59:11 +0000872
873 type_4->data[2] &= 0xf0;
874 type_4->data[2] |= arfcn_high;
875 type_4->data[3] = arfcn_low;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000876
877 /* patch Control Channel Description 10.5.2.11 */
878 type_3->control_channel_desc = bts->chan_desc;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000879}
880
881
Harald Weltee79769b2009-02-07 00:48:17 +0000882static void bootstrap_rsl(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000883{
Harald Welteedb37782009-05-01 14:59:07 +0000884 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
885 "using MCC=%u MNC=%u\n", trx->nr, trx->bts->nr, MCC, MNC);
Harald Weltee79769b2009-02-07 00:48:17 +0000886 set_system_infos(trx);
Harald Welte52b1f982008-12-23 20:25:15 +0000887}
888
Harald Welte1fa60c82009-02-09 18:13:26 +0000889void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
Harald Weltead384642008-12-26 10:20:07 +0000890{
891 switch (event) {
Harald Welte1fa60c82009-02-09 18:13:26 +0000892 case EVT_E1_TEI_UP:
893 switch (type) {
894 case E1INP_SIGN_OML:
895 bootstrap_om(trx->bts);
896 break;
897 case E1INP_SIGN_RSL:
898 bootstrap_rsl(trx);
899 break;
900 default:
901 break;
902 }
Harald Weltead384642008-12-26 10:20:07 +0000903 break;
Harald Welte1fa60c82009-02-09 18:13:26 +0000904 case EVT_E1_TEI_DN:
905 fprintf(stderr, "Lost some E1 TEI link\n");
906 /* FIXME: deal with TEI or L1 link loss */
Harald Weltead384642008-12-26 10:20:07 +0000907 break;
908 default:
Harald Weltead384642008-12-26 10:20:07 +0000909 break;
910 }
911}
912
Harald Welteedb37782009-05-01 14:59:07 +0000913static int bootstrap_bts(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000914{
Holger Freyther0a173bf2009-04-22 22:07:07 +0000915 bts->location_area_code = LAC;
Harald Welte98981882009-01-06 18:59:11 +0000916 bts->trx[0].arfcn = ARFCN;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000917
918 /* Control Channel Description */
919 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
Harald Welte41fbf442009-02-24 22:34:22 +0000920 bts->chan_desc.att = 1;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000921 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
922 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
923 bts->chan_desc.t3212 = 0;
924
Harald Welte98981882009-01-06 18:59:11 +0000925 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000926
Holger Freyther1fd34142009-02-09 23:42:03 +0000927 paging_init(bts);
Harald Welte38c2f132009-01-06 23:10:57 +0000928
Harald Welteedb37782009-05-01 14:59:07 +0000929 return 0;
930}
931
932static int bootstrap_network(void)
933{
934 struct gsm_bts *bts;
935
936 /* initialize our data structures */
937 gsmnet = gsm_network_init(2, BTS_TYPE, MCC, MNC);
938 if (!gsmnet)
939 return -ENOMEM;
940
941 gsmnet->name_long = "OpenBSC";
942 gsmnet->name_short = "OpenBSC";
943
944 bts = &gsmnet->bts[0];
945 bootstrap_bts(bts);
946
Holger Freyther36650b82009-04-19 06:35:16 +0000947 if (db_init(database_name, gsmnet)) {
Holger Freytheref7f7ce2009-04-19 06:35:12 +0000948 printf("DB: Failed to init database. Please check the option settings.\n");
949 return -1;
950 }
951 printf("DB: Database initialized.\n");
952
953 if (db_prepare()) {
954 printf("DB: Failed to prepare database.\n");
955 return -1;
956 }
957 printf("DB: Database prepared.\n");
958
Holger Freyther219518d2009-01-02 22:04:43 +0000959 telnet_init(gsmnet, 4242);
Harald Weltead384642008-12-26 10:20:07 +0000960
Harald Welteb4630602009-05-01 15:43:22 +0000961 register_signal_handler(SS_NM, nm_sig_cb, NULL);
962
Harald Welte1fa60c82009-02-09 18:13:26 +0000963 /* E1 mISDN input setup */
Harald Welteedb37782009-05-01 14:59:07 +0000964 if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
965 gsmnet->num_bts = 1;
Holger Freytherb5c00f52009-04-22 22:08:07 +0000966 return e1_config(bts, cardnr, release_l2);
Harald Welteedb37782009-05-01 14:59:07 +0000967 } else {
968 /* FIXME: do this dynamic */
969 bts->ip_access.site_id = 1801;
970 bts->ip_access.bts_id = 0;
971 bts = &gsmnet->bts[1];
972 bootstrap_bts(bts);
973 bts->ip_access.site_id = 1800;
974 bts->ip_access.bts_id = 0;
Harald Weltecf559782009-05-01 15:43:49 +0000975 return ipaccess_setup(gsmnet);
Harald Welteedb37782009-05-01 14:59:07 +0000976 }
Harald Welte52b1f982008-12-23 20:25:15 +0000977}
Harald Weltef6b7a902008-12-26 00:05:11 +0000978
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000979static void create_pcap_file(char *file)
980{
981 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
982 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
983
984 if (fd < 0) {
985 perror("Failed to open file for pcap");
986 return;
987 }
988
Holger Freyther0469cf62009-03-31 12:14:16 +0000989 e1_set_pcap_fd(fd);
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000990}
991
Holger Freytherb332f612008-12-27 12:46:51 +0000992static void print_usage()
993{
994 printf("Usage: bsc_hack\n");
995}
996
997static void print_help()
998{
999 printf(" Some useful help...\n");
1000 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +00001001 printf(" -s --disable-color\n");
1002 printf(" -n --network-code number(MNC) \n");
1003 printf(" -c --country-code number (MCC) \n");
Holger Freyther0a173bf2009-04-22 22:07:07 +00001004 printf(" -L --location-area-code number (LAC) \n");
Harald Welte98981882009-01-06 18:59:11 +00001005 printf(" -f --arfcn number The frequency ARFCN\n");
Holger Freytherbde36102008-12-28 22:51:39 +00001006 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +00001007 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freythere97f7fb2008-12-31 18:52:11 +00001008 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001009 printf(" -p --pcap file The filename of the pcap file\n");
Harald Weltee1bd2412009-02-15 14:40:09 +00001010 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
Holger Freytherdda22c12009-04-22 22:07:31 +00001011 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
Holger Freytherb5c00f52009-04-22 22:08:07 +00001012 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
Holger Freytherb332f612008-12-27 12:46:51 +00001013 printf(" -h --help this text\n");
1014}
1015
1016static void handle_options(int argc, char** argv)
1017{
1018 while (1) {
1019 int option_index = 0, c;
1020 static struct option long_options[] = {
1021 {"help", 0, 0, 'h'},
1022 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +00001023 {"disable-color", 0, 0, 's'},
1024 {"network-code", 1, 0, 'n'},
1025 {"country-code", 1, 0, 'c'},
Holger Freyther0a173bf2009-04-22 22:07:07 +00001026 {"location-area-code", 1, 0, 'L'},
Holger Freytherbde36102008-12-28 22:51:39 +00001027 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +00001028 {"authorize-everyone", 0, 0, 'a'},
Holger Freythere97f7fb2008-12-31 18:52:11 +00001029 {"reject-cause", 1, 0, 'r'},
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001030 {"pcap", 1, 0, 'p'},
Harald Welte98981882009-01-06 18:59:11 +00001031 {"arfcn", 1, 0, 'f'},
Harald Welte8c1d0e42009-02-15 03:38:12 +00001032 {"bts-type", 1, 0, 't'},
Holger Freytherdda22c12009-04-22 22:07:31 +00001033 {"cardnr", 1, 0, 'C'},
Holger Freytherb5c00f52009-04-22 22:08:07 +00001034 {"release-l2", 0, 0, 'R'},
Holger Freytherb332f612008-12-27 12:46:51 +00001035 {0, 0, 0, 0}
1036 };
1037
Holger Freytherb5c00f52009-04-22 22:08:07 +00001038 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:",
Holger Freytherb332f612008-12-27 12:46:51 +00001039 long_options, &option_index);
1040 if (c == -1)
1041 break;
1042
1043 switch (c) {
1044 case 'h':
1045 print_usage();
1046 print_help();
1047 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +00001048 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +00001049 debug_use_color(0);
1050 break;
1051 case 'd':
1052 debug_parse_category_mask(optarg);
1053 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +00001054 case 'n':
1055 MNC = atoi(optarg);
1056 break;
1057 case 'c':
1058 MCC = atoi(optarg);
1059 break;
Holger Freyther0a173bf2009-04-22 22:07:07 +00001060 case 'L':
1061 LAC = atoi(optarg);
1062 break;
Harald Welte98981882009-01-06 18:59:11 +00001063 case 'f':
1064 ARFCN = atoi(optarg);
1065 break;
Harald Welte8965da42009-01-06 18:09:02 +00001066 case 'l':
Holger Freytherbde36102008-12-28 22:51:39 +00001067 database_name = strdup(optarg);
1068 break;
Holger Freyther89824fc2008-12-30 16:18:18 +00001069 case 'a':
1070 gsm0408_allow_everyone(1);
1071 break;
Holger Freythere97f7fb2008-12-31 18:52:11 +00001072 case 'r':
1073 gsm0408_set_reject_cause(atoi(optarg));
1074 break;
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001075 case 'p':
1076 create_pcap_file(optarg);
1077 break;
Harald Welte8c1d0e42009-02-15 03:38:12 +00001078 case 't':
1079 BTS_TYPE = parse_btstype(optarg);
1080 break;
Holger Freytherdda22c12009-04-22 22:07:31 +00001081 case 'C':
1082 cardnr = atoi(optarg);
1083 break;
Holger Freytherb5c00f52009-04-22 22:08:07 +00001084 case 'R':
1085 release_l2 = 1;
1086 break;
Holger Freytherb332f612008-12-27 12:46:51 +00001087 default:
1088 /* ignore */
1089 break;
1090 }
1091 }
1092}
1093
Harald Welted1252502009-01-01 01:50:32 +00001094static void signal_handler(int signal)
1095{
1096 fprintf(stdout, "signal %u received\n", signal);
1097
1098 switch (signal) {
1099 case SIGHUP:
1100 case SIGABRT:
1101 shutdown_net(gsmnet);
1102 break;
1103 default:
1104 break;
1105 }
1106}
1107
Harald Weltef6b7a902008-12-26 00:05:11 +00001108int main(int argc, char **argv)
1109{
Harald Welte1fa60c82009-02-09 18:13:26 +00001110 int rc;
1111
Holger Freytherb332f612008-12-27 12:46:51 +00001112 /* parse options */
1113 handle_options(argc, argv);
1114
Harald Welte65ccf882009-02-24 22:36:20 +00001115 /* seed the PRNG */
1116 srand(time(NULL));
1117
Harald Welte1fa60c82009-02-09 18:13:26 +00001118 rc = bootstrap_network();
1119 if (rc < 0)
1120 exit(1);
Harald Weltef6b7a902008-12-26 00:05:11 +00001121
Harald Welted1252502009-01-01 01:50:32 +00001122 signal(SIGHUP, &signal_handler);
1123 signal(SIGABRT, &signal_handler);
1124
Harald Weltef6b7a902008-12-26 00:05:11 +00001125 while (1) {
Harald Welte04d3c922009-05-23 06:07:04 +00001126 bsc_select_main(0);
Harald Weltef6b7a902008-12-26 00:05:11 +00001127 }
1128}