blob: 27c2c25367eee32f88a5bc6ca3281e25b3be9802 [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;
Harald Welte25b70c52009-07-29 16:42:16 +020064static int bs11_has_trx1 = 0;
Harald Welte59b04682009-06-10 05:40:52 +080065static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
Harald Welte91afe4c2009-06-20 18:15:19 +020066static enum gsm_band BAND = GSM_BAND_900;
Harald Welte59b04682009-06-10 05:40:52 +080067static const char *database_name = "hlr.sqlite3";
Harald Welte3c062072009-07-28 18:25:29 +020068extern int ipacc_rtp_direct;
Harald Welte59b04682009-06-10 05:40:52 +080069
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +020070struct nano_bts_id {
71 struct llist_head entry;
72 int site_id;
73 int bts_id;
74};
75
76static LLIST_HEAD(nanobts_ids);
77
78
Harald Welte59b04682009-06-10 05:40:52 +080079/* The following definitions are for OM and NM packets that we cannot yet
80 * generate by code but we just pass on */
81
82// BTS Site Manager, SET ATTRIBUTES
83
84/*
85 Object Class: BTS Site Manager
86 Instance 1: FF
87 Instance 2: FF
88 Instance 3: FF
89SET ATTRIBUTES
90 sAbisExternalTime: 2007/09/08 14:36:11
91 omLAPDRelTimer: 30sec
92 shortLAPDIntTimer: 5sec
93 emergencyTimer1: 10 minutes
94 emergencyTimer2: 0 minutes
95*/
96
97unsigned char msg_1[] =
98{
Harald Weltef739ae62009-06-20 10:42:17 +020099 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800100 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
101 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
102 0x02,
103 0x00, 0x1E,
104 NM_ATT_BS11_SH_LAPD_INT_TIMER,
105 0x01, 0x05,
106 0x42, 0x02, 0x00, 0x0A,
107 0x44, 0x02, 0x00, 0x00
108};
109
110// BTS, SET BTS ATTRIBUTES
111
112/*
113 Object Class: BTS
114 BTS relat. Number: 0
115 Instance 2: FF
116 Instance 3: FF
117SET BTS ATTRIBUTES
118 bsIdentityCode / BSIC:
119 PLMN_colour_code: 7h
120 BS_colour_code: 7h
121 BTS Air Timer T3105: 4 ,unit 10 ms
122 btsIsHopping: FALSE
123 periodCCCHLoadIndication: 1sec
124 thresholdCCCHLoadIndication: 0%
125 cellAllocationNumber: 00h = GSM 900
126 enableInterferenceClass: 00h = Disabled
127 fACCHQual: 6 (FACCH stealing flags minus 1)
128 intaveParameter: 31 SACCH multiframes
129 interferenceLevelBoundaries:
130 Interference Boundary 1: 0Ah
131 Interference Boundary 2: 0Fh
132 Interference Boundary 3: 14h
133 Interference Boundary 4: 19h
134 Interference Boundary 5: 1Eh
135 mSTxPwrMax: 11
136 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
137 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
138 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
139 30=33dBm, 31=32dBm
140 ny1:
141 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
142 powerOutputThresholds:
143 Out Power Fault Threshold: -10 dB
144 Red Out Power Threshold: - 6 dB
145 Excessive Out Power Threshold: 5 dB
146 rACHBusyThreshold: -127 dBm
147 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
148 rfResourceIndicationPeriod: 125 SACCH multiframes
149 T200:
150 SDCCH: 044 in 5 ms
151 FACCH/Full rate: 031 in 5 ms
152 FACCH/Half rate: 041 in 5 ms
153 SACCH with TCH SAPI0: 090 in 10 ms
154 SACCH with SDCCH: 090 in 10 ms
155 SDCCH with SAPI3: 090 in 5 ms
156 SACCH with TCH SAPI3: 135 in 10 ms
157 tSync: 9000 units of 10 msec
158 tTrau: 9000 units of 10 msec
159 enableUmLoopTest: 00h = disabled
160 enableExcessiveDistance: 00h = Disabled
161 excessiveDistance: 64km
162 hoppingMode: 00h = baseband hopping
163 cellType: 00h = Standard Cell
164 BCCH ARFCN / bCCHFrequency: 1
165*/
166
Harald Weltef739ae62009-06-20 10:42:17 +0200167static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800168{
Harald Welte59b04682009-06-10 05:40:52 +0800169 NM_ATT_BSIC, HARDCODED_BSIC,
170 NM_ATT_BTS_AIR_TIMER, 0x04,
171 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
172 NM_ATT_CCCH_L_I_P, 0x01,
173 NM_ATT_CCCH_L_T, 0x00,
174 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
175 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
176 NM_ATT_BS11_FACCH_QUAL, 0x06,
177 /* interference avg. period in numbers of SACCH multifr */
178 NM_ATT_INTAVE_PARAM, 0x1F,
179 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
180 NM_ATT_CCCH_L_T, 0x23,
181 NM_ATT_GSM_TIME, 0x28, 0x00,
182 NM_ATT_ADM_STATE, 0x03,
183 NM_ATT_RACH_B_THRESH, 0x7F,
184 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
185 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
186 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
187 NM_ATT_BS11_TSYNC, 0x23, 0x28,
188 NM_ATT_BS11_TTRAU, 0x23, 0x28,
189 NM_ATT_TEST_DUR, 0x01, 0x00,
190 NM_ATT_OUTST_ALARM, 0x01, 0x00,
191 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
192 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
193 NM_ATT_BS11_PLL, 0x01, 0x00,
194 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
195};
196
197// Handover Recognition, SET ATTRIBUTES
198
199/*
200Illegal Contents GSM Formatted O&M Msg
201 Object Class: Handover Recognition
202 BTS relat. Number: 0
203 Instance 2: FF
204 Instance 3: FF
205SET ATTRIBUTES
206 enableDelayPowerBudgetHO: 00h = Disabled
207 enableDistanceHO: 00h = Disabled
208 enableInternalInterCellHandover: 00h = Disabled
209 enableInternalIntraCellHandover: 00h = Disabled
210 enablePowerBudgetHO: 00h = Disabled
211 enableRXLEVHO: 00h = Disabled
212 enableRXQUALHO: 00h = Disabled
213 hoAveragingDistance: 8 SACCH multiframes
214 hoAveragingLev:
215 A_LEV_HO: 8 SACCH multiframes
216 W_LEV_HO: 1 SACCH multiframes
217 hoAveragingPowerBudget: 16 SACCH multiframes
218 hoAveragingQual:
219 A_QUAL_HO: 8 SACCH multiframes
220 W_QUAL_HO: 2 SACCH multiframes
221 hoLowerThresholdLevDL: (10 - 110) dBm
222 hoLowerThresholdLevUL: (5 - 110) dBm
223 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
224 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
225 hoThresholdLevDLintra : (20 - 110) dBm
226 hoThresholdLevULintra: (20 - 110) dBm
227 hoThresholdMsRangeMax: 20 km
228 nCell: 06h
229 timerHORequest: 3 ,unit 2 SACCH multiframes
230*/
231
232unsigned char msg_3[] =
233{
Harald Weltef739ae62009-06-20 10:42:17 +0200234 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Weltec7d75062009-07-18 16:18:11 +0200235 0xD0, 0x00, /* enableDelayPowerBudgetHO */
236 0x64, 0x00, /* enableDistanceHO */
237 0x67, 0x00, /* enableInternalInterCellHandover */
238 0x68, 0x00, /* enableInternalInterCellHandover */
239 0x6A, 0x00, /* enablePowerBudgetHO */
240 0x6C, 0x00, /* enableRXLEVHO */
241 0x6D, 0x00, /* enableRXQUALHO */
242 0x6F, 0x08, /* hoAveragingDistance */
243 0x70, 0x08, 0x01, /* hoAveragingLev */
Harald Welte59b04682009-06-10 05:40:52 +0800244 0x71, 0x10, 0x10, 0x10,
Harald Weltec7d75062009-07-18 16:18:11 +0200245 0x72, 0x08, 0x02, /* hoAveragingQual */
246 0x73, 0x0A, /* hoLowerThresholdLevDL */
247 0x74, 0x05, /* hoLowerThresholdLevUL */
248 0x75, 0x06, /* hoLowerThresholdQualDL */
249 0x76, 0x06, /* hoLowerThresholdQualUL */
250 0x78, 0x14, /* hoThresholdLevDLintra */
251 0x79, 0x14, /* hoThresholdLevULintra */
252 0x7A, 0x14, /* hoThresholdMsRangeMax */
253 0x7D, 0x06, /* nCell */
254 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
255 0x20, 0x01, 0x00,
Harald Welte59b04682009-06-10 05:40:52 +0800256 0x45, 0x01, 0x00,
257 0x48, 0x01, 0x00,
258 0x5A, 0x01, 0x00,
259 0x5B, 0x01, 0x05,
260 0x5E, 0x01, 0x1A,
261 0x5F, 0x01, 0x20,
262 0x9D, 0x01, 0x00,
263 0x47, 0x01, 0x00,
264 0x5C, 0x01, 0x64,
265 0x5D, 0x01, 0x1E,
266 0x97, 0x01, 0x20,
267 0xF7, 0x01, 0x3C,
268};
269
270// Power Control, SET ATTRIBUTES
271
272/*
273 Object Class: Power Control
274 BTS relat. Number: 0
275 Instance 2: FF
276 Instance 3: FF
277SET ATTRIBUTES
278 enableMsPowerControl: 00h = Disabled
279 enablePowerControlRLFW: 00h = Disabled
280 pcAveragingLev:
281 A_LEV_PC: 4 SACCH multiframes
282 W_LEV_PC: 1 SACCH multiframes
283 pcAveragingQual:
284 A_QUAL_PC: 4 SACCH multiframes
285 W_QUAL_PC: 2 SACCH multiframes
286 pcLowerThresholdLevDL: 0Fh
287 pcLowerThresholdLevUL: 0Ah
288 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
289 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
290 pcRLFThreshold: 0Ch
291 pcUpperThresholdLevDL: 14h
292 pcUpperThresholdLevUL: 0Fh
293 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
294 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
295 powerConfirm: 2 ,unit 2 SACCH multiframes
296 powerControlInterval: 2 ,unit 2 SACCH multiframes
297 powerIncrStepSize: 02h = 4 dB
298 powerRedStepSize: 01h = 2 dB
299 radioLinkTimeoutBs: 64 SACCH multiframes
300 enableBSPowerControl: 00h = disabled
301*/
302
303unsigned char msg_4[] =
304{
Harald Weltef739ae62009-06-20 10:42:17 +0200305 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800306 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
307 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Weltec7d75062009-07-18 16:18:11 +0200308 0x7E, 0x04, 0x01, /* pcAveragingLev */
309 0x7F, 0x04, 0x02, /* pcAveragingQual */
310 0x80, 0x0F, /* pcLowerThresholdLevDL */
311 0x81, 0x0A, /* pcLowerThresholdLevUL */
312 0x82, 0x05, /* pcLowerThresholdQualDL */
313 0x83, 0x05, /* pcLowerThresholdQualUL */
314 0x84, 0x0C, /* pcRLFThreshold */
315 0x85, 0x14, /* pcUpperThresholdLevDL */
316 0x86, 0x0F, /* pcUpperThresholdLevUL */
317 0x87, 0x04, /* pcUpperThresholdQualDL */
318 0x88, 0x04, /* pcUpperThresholdQualUL */
319 0x89, 0x02, /* powerConfirm */
320 0x8A, 0x02, /* powerConfirmInterval */
321 0x8B, 0x02, /* powerIncrStepSize */
322 0x8C, 0x01, /* powerRedStepSize */
323 0x8D, 0x40, /* radioLinkTimeoutBs */
Harald Welte59b04682009-06-10 05:40:52 +0800324 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
325};
326
327
328// Transceiver, SET TRX ATTRIBUTES (TRX 0)
329
330/*
331 Object Class: Transceiver
332 BTS relat. Number: 0
333 Tranceiver number: 0
334 Instance 3: FF
335SET TRX ATTRIBUTES
336 aRFCNList (HEX): 0001
337 txPwrMaxReduction: 00h = 30dB
338 radioMeasGran: 254 SACCH multiframes
339 radioMeasRep: 01h = enabled
340 memberOfEmergencyConfig: 01h = TRUE
341 trxArea: 00h = TRX doesn't belong to a concentric cell
342*/
343
Harald Weltef739ae62009-06-20 10:42:17 +0200344static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800345{
Harald Welte59b04682009-06-10 05:40:52 +0800346 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
347 NM_ATT_RF_MAXPOWR_R, 0x00,
348 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
349 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
350 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
351 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
352};
353
354static unsigned char nanobts_attr_bts[] = {
355 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
356 /* interference avg. period in numbers of SACCH multifr */
357 NM_ATT_INTAVE_PARAM, 0x06,
358 /* conn fail based on SACCH error rate */
359 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
360 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
361 NM_ATT_MAX_TA, 0x3f,
362 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
363 NM_ATT_CCCH_L_T, 10, /* percent */
364 NM_ATT_CCCH_L_I_P, 1, /* seconds */
365 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
366 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
367 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
368 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
369 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
370 NM_ATT_BSIC, HARDCODED_BSIC,
371};
372
373static unsigned char nanobts_attr_radio[] = {
374 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
375 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
376};
377
378static unsigned char nanobts_attr_e0[] = {
Harald Welte4206d982009-07-12 09:33:54 +0200379 NM_ATT_IPACC_STREAM_ID, 0x00,
380 NM_ATT_IPACC_DST_IP_PORT, 0x0b, 0xbb, /* TCP PORT for RSL */
Harald Welte59b04682009-06-10 05:40:52 +0800381};
382
383/* Callback function to be called whenever we get a GSM 12.21 state change event */
384int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
385 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
386{
387 struct gsm_bts *bts;
388 struct gsm_bts_trx *trx;
389 struct gsm_bts_trx_ts *ts;
390
391 /* This is currently only required on nanoBTS */
392
393 switch (evt) {
394 case EVT_STATECHG_OPER:
395 switch (obj_class) {
396 case NM_OC_SITE_MANAGER:
397 bts = container_of(obj, struct gsm_bts, site_mgr);
398 if (old_state->operational != 2 && new_state->operational == 2) {
399 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
400 }
401 break;
402 case NM_OC_BTS:
403 bts = obj;
404 if (new_state->availability == 5) {
405 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
406 sizeof(nanobts_attr_bts));
407 abis_nm_opstart(bts, NM_OC_BTS,
408 bts->bts_nr, 0xff, 0xff);
409 abis_nm_chg_adm_state(bts, NM_OC_BTS,
410 bts->bts_nr, 0xff, 0xff,
411 NM_STATE_UNLOCKED);
412 }
413 break;
414 case NM_OC_CHANNEL:
415 ts = obj;
416 trx = ts->trx;
417 if (new_state->availability == 5) {
418 if (ts->nr == 0 && trx == trx->bts->c0)
419 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
420 else
421 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
422 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
423 trx->bts->bts_nr, trx->nr, ts->nr);
424 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
425 trx->bts->bts_nr, trx->nr, ts->nr,
426 NM_STATE_UNLOCKED);
427 }
428 break;
429 default:
430 break;
431 }
432 break;
433 default:
434 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
435 break;
436 }
437 return 0;
438}
439
440/* Callback function to be called every time we receive a 12.21 SW activated report */
441static int sw_activ_rep(struct msgb *mb)
442{
443 struct abis_om_fom_hdr *foh = msgb_l3(mb);
444 struct gsm_bts_trx *trx = mb->trx;
445
446 switch (foh->obj_class) {
447 case NM_OC_BASEB_TRANSC:
448 /* TRX software is active, tell it to initiate RSL Link */
449 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
450 trx->bts->bts_nr, trx->nr, 0xff,
451 nanobts_attr_e0, sizeof(nanobts_attr_e0));
452 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
453 trx->bts->bts_nr, trx->nr, 0xff);
454 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
455 trx->bts->bts_nr, trx->nr, 0xff,
456 NM_STATE_UNLOCKED);
457 break;
458 case NM_OC_RADIO_CARRIER:
459 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
460 sizeof(nanobts_attr_radio));
461 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
462 trx->bts->bts_nr, trx->nr, 0xff);
463 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
464 trx->bts->bts_nr, trx->nr, 0xff,
465 NM_STATE_UNLOCKED);
466 break;
467 }
468 return 0;
469}
470
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200471/* Callback function for NACK on the OML NM */
472static int oml_msg_nack(int mt)
473{
474 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
475 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
476 "Was the bts type and frequency properly specified?\n");
477 exit(-1);
478 }
479
480 return 0;
481}
482
Harald Welte59b04682009-06-10 05:40:52 +0800483/* Callback function to be called every time we receive a signal from NM */
484static int nm_sig_cb(unsigned int subsys, unsigned int signal,
485 void *handler_data, void *signal_data)
486{
487 switch (signal) {
488 case S_NM_SW_ACTIV_REP:
489 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200490 case S_NM_NACK:
491 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800492 default:
493 break;
494 }
495 return 0;
496}
497
498static void bootstrap_om_nanobts(struct gsm_bts *bts)
499{
500 /* We don't do callback based bootstrapping, but event driven (see above) */
501}
502
503static void bootstrap_om_bs11(struct gsm_bts *bts)
504{
Harald Weltee712a5f2009-06-21 16:17:15 +0200505 struct gsm_bts_trx *trx = bts->c0;
Harald Weltecf833cd2009-08-06 17:40:24 +0200506 int base_ts;
507
508 switch (bts->nr) {
509 case 0:
510 /* First BTS uses E1 TS 01,02,03,04,05 */
511 base_ts = HARDCODED_BTS0_TS - 1;
512 break;
513 case 1:
514 /* Second BTS uses E1 TS 06,07,08,09,10 */
515 base_ts = HARDCODED_BTS1_TS - 1;
516 break;
517 case 2:
518 /* Third BTS uses E1 TS 11,12,13,14,15 */
519 base_ts = HARDCODED_BTS2_TS - 1;
520 default:
521 return;
522 }
Harald Welte59b04682009-06-10 05:40:52 +0800523
524 /* stop sending event reports */
525 abis_nm_event_reports(bts, 0);
526
527 /* begin DB transmission */
528 abis_nm_bs11_db_transmission(bts, 1);
529
530 /* end DB transmission */
531 abis_nm_bs11_db_transmission(bts, 0);
532
533 /* Reset BTS Site manager resource */
534 abis_nm_bs11_reset_resource(bts);
535
536 /* begin DB transmission */
537 abis_nm_bs11_db_transmission(bts, 1);
538
539 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltef739ae62009-06-20 10:42:17 +0200540 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800541 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
542 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
543
544 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200545 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Weltef739ae62009-06-20 10:42:17 +0200546 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800547
548 /* Use TEI 1 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200549 abis_nm_establish_tei(bts, 0, 0, base_ts+1, 0xff, 0x01);
Harald Welte59b04682009-06-10 05:40:52 +0800550 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
551
Harald Welte59b04682009-06-10 05:40:52 +0800552 /* SET CHANNEL ATTRIBUTE TS1 */
553 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
554 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200555 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+2, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800556
557 /* SET CHANNEL ATTRIBUTE TS2 */
558 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
559 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200560 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+2, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800561
562 /* SET CHANNEL ATTRIBUTE TS3 */
563 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
564 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200565 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+2, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800566
567 /* SET CHANNEL ATTRIBUTE TS4 */
568 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
569 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200570 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+3, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800571
572 /* SET CHANNEL ATTRIBUTE TS5 */
573 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
574 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200575 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+3, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800576
577 /* SET CHANNEL ATTRIBUTE TS6 */
578 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
579 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200580 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+3, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800581
582 /* SET CHANNEL ATTRIBUTE TS7 */
583 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
584 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200585 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+3, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800586
Harald Welte25b70c52009-07-29 16:42:16 +0200587 trx = gsm_bts_trx_num(bts, 1);
588 if (trx) {
589 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
590 u_int8_t arfcn_low = trx->arfcn & 0xff;
591 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
592 memcpy(trx1_attr_radio, bs11_attr_radio,
593 sizeof(trx1_attr_radio));
594
595 /* patch ARFCN into TRX Attributes */
596 trx1_attr_radio[2] &= 0xf0;
597 trx1_attr_radio[2] |= arfcn_high;
598 trx1_attr_radio[3] = arfcn_low;
599
600 /* Connect signalling of TRX1 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200601 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Welte25b70c52009-07-29 16:42:16 +0200602 /* FIXME: TRX ATTRIBUTE */
603 abis_nm_set_radio_attr(trx, trx1_attr_radio,
604 sizeof(trx1_attr_radio));
605
606 /* Use TEI 2 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200607 abis_nm_establish_tei(bts, 1, 0, base_ts+1, 0xff, 0x02);
Harald Welte25b70c52009-07-29 16:42:16 +0200608
Harald Welte1a503162009-08-04 01:31:53 +0200609 /* SET CHANNEL ATTRIBUTE TS0 */
610 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_TCHFull);
611 /* Connect traffic of bts0/trx0/ts0 to e1_0/ts4/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200612 abis_nm_conn_terr_traf(&trx->ts[0], 0, base_ts+4, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200613
614 /* SET CHANNEL ATTRIBUTE TS1 */
615 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
616 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200617 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+4, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200618
619 /* SET CHANNEL ATTRIBUTE TS2 */
620 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
621 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200622 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+4, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200623
624 /* SET CHANNEL ATTRIBUTE TS3 */
625 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
626 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200627 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+4, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200628
629 /* SET CHANNEL ATTRIBUTE TS4 */
630 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
631 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200632 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+5, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200633
634 /* SET CHANNEL ATTRIBUTE TS5 */
635 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
636 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200637 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+5, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200638
639 /* SET CHANNEL ATTRIBUTE TS6 */
640 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
641 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200642 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+5, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200643
644 /* SET CHANNEL ATTRIBUTE TS7 */
645 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
646 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200647 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+5, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200648 }
649
Harald Welte59b04682009-06-10 05:40:52 +0800650 /* end DB transmission */
651 abis_nm_bs11_db_transmission(bts, 0);
652
653 /* Reset BTS Site manager resource */
654 abis_nm_bs11_reset_resource(bts);
655
656 /* restart sending event reports */
657 abis_nm_event_reports(bts, 1);
658}
659
660static void bootstrap_om(struct gsm_bts *bts)
661{
662 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
663
664 switch (bts->type) {
665 case GSM_BTS_TYPE_BS11:
666 bootstrap_om_bs11(bts);
667 break;
668 case GSM_BTS_TYPE_NANOBTS_900:
669 case GSM_BTS_TYPE_NANOBTS_1800:
670 bootstrap_om_nanobts(bts);
671 break;
672 default:
673 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
674 }
675}
676
677static int shutdown_om(struct gsm_bts *bts)
678{
Harald Welte3b714502009-08-06 17:43:50 +0200679 fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
680
Harald Welte59b04682009-06-10 05:40:52 +0800681 /* stop sending event reports */
682 abis_nm_event_reports(bts, 0);
683
684 /* begin DB transmission */
685 abis_nm_bs11_db_transmission(bts, 1);
686
687 /* end DB transmission */
688 abis_nm_bs11_db_transmission(bts, 0);
689
690 /* Reset BTS Site manager resource */
691 abis_nm_bs11_reset_resource(bts);
692
693 return 0;
694}
695
696static int shutdown_net(struct gsm_network *net)
697{
Harald Weltee712a5f2009-06-21 16:17:15 +0200698 struct gsm_bts *bts;
699
700 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welte59b04682009-06-10 05:40:52 +0800701 int rc;
Harald Weltee712a5f2009-06-21 16:17:15 +0200702 rc = shutdown_om(bts);
Harald Welte59b04682009-06-10 05:40:52 +0800703 if (rc < 0)
704 return rc;
705 }
706
707 return 0;
708}
709
710struct bcch_info {
711 u_int8_t type;
712 u_int8_t len;
713 const u_int8_t *data;
714};
715
716/*
717SYSTEM INFORMATION TYPE 1
718 Cell channel description
719 Format-ID bit map 0
720 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
721 RACH Control Parameters
722 maximum 7 retransmissions
723 8 slots used to spread transmission
724 cell not barred for access
725 call reestablishment not allowed
726 Access Control Class = 0000
727*/
728static u_int8_t si1[] = {
729 /* header */0x55, 0x06, 0x19,
730 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
732 /* rach */0xD5, 0x00, 0x00,
733 /* s1 reset*/0x2B
734};
735
736/*
737 SYSTEM INFORMATION TYPE 2
738 Neighbour Cells Description
739 EXT-IND: Carries the complete BA
740 BA-IND = 0
741 Format-ID bit map 0
742 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
743 NCC permitted (NCC) = FF
744 RACH Control Parameters
745 maximum 7 retransmissions
746 8 slots used to spread transmission
747 cell not barred for access
748 call reestablishment not allowed
749 Access Control Class = 0000
750*/
751static u_int8_t si2[] = {
752 /* header */0x59, 0x06, 0x1A,
753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 /* ncc */0xFF,
756 /* rach*/0xD5, 0x00, 0x00
757};
758
759/*
760SYSTEM INFORMATION TYPE 3
761 Cell identity = 00001 (1h)
762 Location area identification
763 Mobile Country Code (MCC): 001
764 Mobile Network Code (MNC): 01
765 Location Area Code (LAC): 00001 (1h)
766 Control Channel Description
767 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
768 0 blocks reserved for access grant
769 1 channel used for CCCH, with SDCCH
770 5 multiframes period for PAGING REQUEST
771 Time-out T3212 = 0
772 Cell Options BCCH
773 Power control indicator: not set
774 MSs shall not use uplink DTX
775 Radio link timeout = 36
776 Cell Selection Parameters
777 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
778 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
779 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
780 Half rate support (NECI): New establishment causes are not supported
781 min.RX signal level for MS = 0
782 RACH Control Parameters
783 maximum 7 retransmissions
784 8 slots used to spread transmission
785 cell not barred for access
786 call reestablishment not allowed
787 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200788 SI 3 Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800789*/
790static u_int8_t si3[] = {
791 /* header */0x49, 0x06, 0x1B,
792 /* cell */0x00, 0x01,
793 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
794 /* desc */0x01, 0x03, 0x00,
795 /* option*/0x28,
796 /* selection*/0x62, 0x00,
797 /* rach */0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200798 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800799};
800
801/*
802SYSTEM INFORMATION TYPE 4
803 Location area identification
804 Mobile Country Code (MCC): 001
805 Mobile Network Code (MNC): 01
806 Location Area Code (LAC): 00001 (1h)
807 Cell Selection Parameters
808 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
809 max.TX power level MS may use for CCH = 2
810 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
811 Half rate support (NECI): New establishment causes are not supported
812 min.RX signal level for MS = 0
813 RACH Control Parameters
814 maximum 7 retransmissions
815 8 slots used to spread transmission
816 cell not barred for access
817 call reestablishment not allowed
818 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200819 CBCH Channel Description
Harald Welte59b04682009-06-10 05:40:52 +0800820 Type = SDCCH/4[2]
821 Timeslot Number: 0
822 Training Sequence Code: 7h
823 ARFCN: 1
Harald Weltec1c4a952009-07-05 13:41:40 +0200824 SI Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800825*/
826static u_int8_t si4[] = {
827 /* header */0x41, 0x06, 0x1C,
828 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
829 /* sel */0x62, 0x00,
830 /* rach*/0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200831 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
832 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800833};
834
835/*
836 SYSTEM INFORMATION TYPE 5
837 Neighbour Cells Description
838 EXT-IND: Carries the complete BA
839 BA-IND = 0
840 Format-ID bit map 0
841 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
842*/
843
844static u_int8_t si5[] = {
845 /* header without l2 len*/0x06, 0x1D,
846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848};
849
850// SYSTEM INFORMATION TYPE 6
851
852/*
853SACCH FILLING
854 System Info Type: SYSTEM INFORMATION 6
855 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
856
857SYSTEM INFORMATION TYPE 6
858 Cell identity = 00001 (1h)
859 Location area identification
860 Mobile Country Code (MCC): 001
861 Mobile Network Code (MNC): 01
862 Location Area Code (LAC): 00001 (1h)
863 Cell Options SACCH
864 Power control indicator: not set
865 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
866 Radio link timeout = 36
867 NCC permitted (NCC) = FF
868*/
869
870static u_int8_t si6[] = {
871 /* header */0x06, 0x1E,
872 /* cell id*/ 0x00, 0x01,
873 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
874 /* options */ 0x28,
875 /* ncc */ 0xFF,
876};
877
878
879
880static const struct bcch_info bcch_infos[] = {
881 {
882 .type = RSL_SYSTEM_INFO_1,
883 .len = sizeof(si1),
884 .data = si1,
885 }, {
886 .type = RSL_SYSTEM_INFO_2,
887 .len = sizeof(si2),
888 .data = si2,
889 }, {
890 .type = RSL_SYSTEM_INFO_3,
891 .len = sizeof(si3),
892 .data = si3,
893 }, {
894 .type = RSL_SYSTEM_INFO_4,
895 .len = sizeof(si4),
896 .data = si4,
897 },
898};
899
900static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
901static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
902static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
903static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
904static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
905static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
906
907/* set all system information types */
908static int set_system_infos(struct gsm_bts_trx *trx)
909{
910 int i;
911
Harald Welte6ab22d22009-08-06 17:41:19 +0200912 if (trx == trx->bts->c0) {
913 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
914 rsl_bcch_info(trx, bcch_infos[i].type,
915 bcch_infos[i].data,
916 bcch_infos[i].len);
917 }
Harald Welte59b04682009-06-10 05:40:52 +0800918 }
919 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
920 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
921
922 return 0;
923}
924
925/*
926 * Patch the various SYSTEM INFORMATION tables to update
927 * the LAI
928 */
929static void patch_tables(struct gsm_bts *bts)
930{
Harald Weltee712a5f2009-06-21 16:17:15 +0200931 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
932 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Harald Welte59b04682009-06-10 05:40:52 +0800933 /* covert the raw packet to the struct */
934 struct gsm48_system_information_type_3 *type_3 =
935 (struct gsm48_system_information_type_3*)&si3;
936 struct gsm48_system_information_type_4 *type_4 =
937 (struct gsm48_system_information_type_4*)&si4;
938 struct gsm48_system_information_type_6 *type_6 =
939 (struct gsm48_system_information_type_6*)&si6;
940 struct gsm48_loc_area_id lai;
941
942 gsm0408_generate_lai(&lai, bts->network->country_code,
943 bts->network->network_code,
944 bts->location_area_code);
945
946 /* assign the MCC and MNC */
947 type_3->lai = lai;
948 type_4->lai = lai;
949 type_6->lai = lai;
950
951 /* patch ARFCN into BTS Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200952 bs11_attr_bts[69] &= 0xf0;
953 bs11_attr_bts[69] |= arfcn_high;
954 bs11_attr_bts[70] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800955 nanobts_attr_bts[42] &= 0xf0;
956 nanobts_attr_bts[42] |= arfcn_high;
957 nanobts_attr_bts[43] = arfcn_low;
958
959 /* patch ARFCN into TRX Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200960 bs11_attr_radio[2] &= 0xf0;
961 bs11_attr_radio[2] |= arfcn_high;
962 bs11_attr_radio[3] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800963 nanobts_attr_radio[5] &= 0xf0;
964 nanobts_attr_radio[5] |= arfcn_high;
965 nanobts_attr_radio[6] = arfcn_low;
966
967 type_4->data[2] &= 0xf0;
968 type_4->data[2] |= arfcn_high;
969 type_4->data[3] = arfcn_low;
970
971 /* patch Control Channel Description 10.5.2.11 */
972 type_3->control_channel_desc = bts->chan_desc;
973
974 /* patch BSIC */
Harald Weltef739ae62009-06-20 10:42:17 +0200975 bs11_attr_bts[1] = bts->bsic;
Harald Welte59b04682009-06-10 05:40:52 +0800976 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
Harald Welte52281c12009-07-21 22:12:23 +0200977
978 /* patch TSC */
979 si4[15] &= ~0xe0;
980 si4[15] |= (bts->tsc & 7) << 5;
Harald Welte59b04682009-06-10 05:40:52 +0800981}
982
983
984static void bootstrap_rsl(struct gsm_bts_trx *trx)
985{
986 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte52281c12009-07-21 22:12:23 +0200987 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
Harald Welte1a503162009-08-04 01:31:53 +0200988 trx->bts->nr, trx->nr, MCC, MNC, BSIC, TSC);
Harald Welte59b04682009-06-10 05:40:52 +0800989 set_system_infos(trx);
990}
991
992void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
993{
994 switch (event) {
995 case EVT_E1_TEI_UP:
996 switch (type) {
997 case E1INP_SIGN_OML:
998 bootstrap_om(trx->bts);
999 break;
1000 case E1INP_SIGN_RSL:
1001 bootstrap_rsl(trx);
1002 break;
1003 default:
1004 break;
1005 }
1006 break;
1007 case EVT_E1_TEI_DN:
1008 fprintf(stderr, "Lost some E1 TEI link\n");
1009 /* FIXME: deal with TEI or L1 link loss */
1010 break;
1011 default:
1012 break;
1013 }
1014}
1015
1016static int bootstrap_bts(struct gsm_bts *bts)
1017{
Harald Welte91afe4c2009-06-20 18:15:19 +02001018 bts->band = BAND;
Harald Welte59b04682009-06-10 05:40:52 +08001019 bts->location_area_code = LAC;
Harald Weltee712a5f2009-06-21 16:17:15 +02001020 bts->c0->arfcn = ARFCN;
Harald Welte59b04682009-06-10 05:40:52 +08001021
1022 /* Control Channel Description */
1023 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
1024 bts->chan_desc.att = 1;
1025 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1026 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1027 bts->chan_desc.t3212 = 0;
1028
1029 patch_tables(bts);
1030
1031 paging_init(bts);
1032
1033 if (bts->type == GSM_BTS_TYPE_BS11) {
Harald Weltee712a5f2009-06-21 16:17:15 +02001034 struct gsm_bts_trx *trx = bts->c0;
Harald Welte59b04682009-06-10 05:40:52 +08001035 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
1036 set_ts_e1link(&trx->ts[1], 0, 2, 1);
1037 set_ts_e1link(&trx->ts[2], 0, 2, 2);
1038 set_ts_e1link(&trx->ts[3], 0, 2, 3);
1039 set_ts_e1link(&trx->ts[4], 0, 3, 0);
1040 set_ts_e1link(&trx->ts[5], 0, 3, 1);
1041 set_ts_e1link(&trx->ts[6], 0, 3, 2);
1042 set_ts_e1link(&trx->ts[7], 0, 3, 3);
Harald Welte25b70c52009-07-29 16:42:16 +02001043
Harald Welte59b04682009-06-10 05:40:52 +08001044 /* TRX 1 */
Harald Welte25b70c52009-07-29 16:42:16 +02001045 trx = gsm_bts_trx_num(bts, 1);
1046 if (trx) {
1047 trx = gsm_bts_trx_num(bts, 1);
1048 set_ts_e1link(&trx->ts[0], 0, 4, 0);
1049 set_ts_e1link(&trx->ts[1], 0, 4, 1);
1050 set_ts_e1link(&trx->ts[2], 0, 4, 2);
1051 set_ts_e1link(&trx->ts[3], 0, 4, 3);
1052 set_ts_e1link(&trx->ts[4], 0, 5, 0);
1053 set_ts_e1link(&trx->ts[5], 0, 5, 1);
1054 set_ts_e1link(&trx->ts[6], 0, 5, 2);
1055 set_ts_e1link(&trx->ts[7], 0, 5, 3);
1056 }
Harald Welte59b04682009-06-10 05:40:52 +08001057 }
1058
1059 return 0;
1060}
1061
1062static int bootstrap_network(void)
1063{
Holger Hans Peter Freytheref5f4182009-06-10 10:20:16 +02001064 switch(BTS_TYPE) {
1065 case GSM_BTS_TYPE_NANOBTS_1800:
1066 if (ARFCN < 512 || ARFCN > 885) {
1067 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
1068 return -EINVAL;
1069 }
1070 break;
1071 case GSM_BTS_TYPE_BS11:
1072 case GSM_BTS_TYPE_NANOBTS_900:
1073 /* Assume we have a P-GSM900 here */
1074 if (ARFCN < 1 || ARFCN > 124) {
1075 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1076 return -EINVAL;
1077 }
1078 break;
1079 case GSM_BTS_TYPE_UNKNOWN:
1080 fprintf(stderr, "Unknown BTS. Please use the --bts-type switch\n");
1081 return -EINVAL;
1082 }
1083
Harald Welte59b04682009-06-10 05:40:52 +08001084 /* initialize our data structures */
Harald Weltee712a5f2009-06-21 16:17:15 +02001085 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +08001086 if (!gsmnet)
1087 return -ENOMEM;
1088
1089 gsmnet->name_long = "OpenBSC";
1090 gsmnet->name_short = "OpenBSC";
1091
Harald Welte59b04682009-06-10 05:40:52 +08001092 if (db_init(database_name)) {
1093 printf("DB: Failed to init database. Please check the option settings.\n");
1094 return -1;
1095 }
1096 printf("DB: Database initialized.\n");
1097
1098 if (db_prepare()) {
1099 printf("DB: Failed to prepare database.\n");
1100 return -1;
1101 }
1102 printf("DB: Database prepared.\n");
1103
1104 telnet_init(gsmnet, 4242);
1105
1106 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1107
1108 /* E1 mISDN input setup */
1109 if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
Harald Welte52281c12009-07-21 22:12:23 +02001110 struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Harald Welte25b70c52009-07-29 16:42:16 +02001111
1112 if (bs11_has_trx1) {
1113 struct gsm_bts_trx *trx1;
1114 trx1 = gsm_bts_trx_alloc(bts);
1115 trx1->arfcn = ARFCN + 2;
1116 }
1117
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001118 bootstrap_bts(bts);
1119
Harald Welte59b04682009-06-10 05:40:52 +08001120 gsmnet->num_bts = 1;
1121 return e1_config(bts, cardnr, release_l2);
1122 } else {
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001123 struct nano_bts_id *bts_id;
1124 struct gsm_bts *bts;
Harald Welte91afe4c2009-06-20 18:15:19 +02001125
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001126 if (llist_empty(&nanobts_ids)) {
1127 fprintf(stderr, "You need to specify -i DEVICE_1 -i DEVICE_2 for nanoBTS.\n");
1128 return -EINVAL;
1129 }
1130
1131 llist_for_each_entry(bts_id, &nanobts_ids, entry) {
Harald Welte52281c12009-07-21 22:12:23 +02001132 bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001133 bootstrap_bts(bts);
1134 bts->ip_access.site_id = bts_id->site_id;
1135 bts->ip_access.bts_id = 0;
1136 }
1137
Harald Welte59b04682009-06-10 05:40:52 +08001138 return ipaccess_setup(gsmnet);
1139 }
1140}
1141
1142static void create_pcap_file(char *file)
1143{
1144 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1145 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1146
1147 if (fd < 0) {
1148 perror("Failed to open file for pcap");
1149 return;
1150 }
1151
1152 e1_set_pcap_fd(fd);
1153}
1154
1155static void print_usage()
1156{
1157 printf("Usage: bsc_hack\n");
1158}
1159
1160static void print_help()
1161{
1162 printf(" Some useful help...\n");
1163 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1164 printf(" -s --disable-color\n");
1165 printf(" -n --network-code number(MNC) \n");
1166 printf(" -c --country-code number (MCC) \n");
1167 printf(" -L --location-area-code number (LAC) \n");
1168 printf(" -f --arfcn number The frequency ARFCN\n");
1169 printf(" -l --database db-name The database to use\n");
1170 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1171 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1172 printf(" -p --pcap file The filename of the pcap file\n");
1173 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001174 printf(" -i --bts-id=NUMBER The known nanoBTS device numbers. Can be specified multiple times.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001175 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1176 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
1177 printf(" -h --help this text\n");
1178}
1179
1180static void handle_options(int argc, char** argv)
1181{
1182 while (1) {
Harald Weltea8379772009-06-20 22:36:41 +02001183 int option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001184 static struct option long_options[] = {
1185 {"help", 0, 0, 'h'},
1186 {"debug", 1, 0, 'd'},
1187 {"disable-color", 0, 0, 's'},
1188 {"network-code", 1, 0, 'n'},
1189 {"country-code", 1, 0, 'c'},
1190 {"location-area-code", 1, 0, 'L'},
1191 {"database", 1, 0, 'l'},
1192 {"authorize-everyone", 0, 0, 'a'},
1193 {"reject-cause", 1, 0, 'r'},
1194 {"pcap", 1, 0, 'p'},
1195 {"arfcn", 1, 0, 'f'},
1196 {"bts-type", 1, 0, 't'},
1197 {"cardnr", 1, 0, 'C'},
1198 {"release-l2", 0, 0, 'R'},
1199 {"timestamp", 0, 0, 'T'},
Harald Welte91afe4c2009-06-20 18:15:19 +02001200 {"band", 0, 0, 'b'},
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001201 {"bts-id", 1, 0, 'i'},
Harald Welte52281c12009-07-21 22:12:23 +02001202 {"tsc", 1, 0, 'S'},
1203 {"bsic", 1, 0, 'B'},
Harald Welte3c062072009-07-28 18:25:29 +02001204 {"rtp-proxy", 0, 0, 'P'},
Harald Welte25b70c52009-07-29 16:42:16 +02001205 {"trx1", 0, 0, '1'},
Harald Welte59b04682009-06-10 05:40:52 +08001206 {0, 0, 0, 0}
1207 };
1208
Harald Welte25b70c52009-07-29 16:42:16 +02001209 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:P1",
Harald Welte59b04682009-06-10 05:40:52 +08001210 long_options, &option_index);
1211 if (c == -1)
1212 break;
1213
1214 switch (c) {
1215 case 'h':
1216 print_usage();
1217 print_help();
1218 exit(0);
1219 case 's':
1220 debug_use_color(0);
1221 break;
1222 case 'd':
1223 debug_parse_category_mask(optarg);
1224 break;
1225 case 'n':
1226 MNC = atoi(optarg);
1227 break;
1228 case 'c':
1229 MCC = atoi(optarg);
1230 break;
1231 case 'L':
1232 LAC = atoi(optarg);
1233 break;
1234 case 'f':
1235 ARFCN = atoi(optarg);
1236 break;
1237 case 'l':
1238 database_name = strdup(optarg);
1239 break;
1240 case 'a':
1241 gsm0408_allow_everyone(1);
1242 break;
1243 case 'r':
1244 gsm0408_set_reject_cause(atoi(optarg));
1245 break;
1246 case 'p':
1247 create_pcap_file(optarg);
1248 break;
1249 case 't':
1250 BTS_TYPE = parse_btstype(optarg);
1251 break;
1252 case 'C':
1253 cardnr = atoi(optarg);
1254 break;
1255 case 'R':
1256 release_l2 = 1;
1257 break;
1258 case 'T':
1259 debug_timestamp(1);
1260 break;
Harald Welte91afe4c2009-06-20 18:15:19 +02001261 case 'b':
1262 BAND = gsm_band_parse(atoi(optarg));
1263 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001264 case 'i': {
1265 struct nano_bts_id *bts_id = talloc_zero(tall_bsc_ctx, struct nano_bts_id);
1266 if (!bts_id) {
1267 fprintf(stderr, "Failed to allocate bts id\n");
1268 exit(-1);
1269 }
1270
1271 bts_id->site_id = atoi(optarg);
1272 llist_add(&bts_id->entry, &nanobts_ids);
1273 break;
Harald Welte52281c12009-07-21 22:12:23 +02001274 case 'S':
1275 TSC = atoi(optarg);
1276 break;
1277 case 'B':
1278 BSIC = atoi(optarg);
1279 break;
Harald Welte3c062072009-07-28 18:25:29 +02001280 case 'P':
1281 ipacc_rtp_direct = 0;
1282 break;
Harald Welte25b70c52009-07-29 16:42:16 +02001283 case '1':
1284 bs11_has_trx1 = 1;
1285 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001286 }
Harald Welte59b04682009-06-10 05:40:52 +08001287 default:
1288 /* ignore */
1289 break;
1290 }
1291 }
1292}
1293
1294static void signal_handler(int signal)
1295{
1296 fprintf(stdout, "signal %u received\n", signal);
1297
1298 switch (signal) {
Harald Welte3b714502009-08-06 17:43:50 +02001299 case SIGINT:
Harald Welte59b04682009-06-10 05:40:52 +08001300 case SIGABRT:
1301 shutdown_net(gsmnet);
Harald Welte3b714502009-08-06 17:43:50 +02001302 sleep(3);
1303 exit(0);
Harald Welte59b04682009-06-10 05:40:52 +08001304 break;
Harald Weltea8379772009-06-20 22:36:41 +02001305 case SIGUSR1:
1306 talloc_report_full(tall_bsc_ctx, stderr);
1307 break;
Harald Welte59b04682009-06-10 05:40:52 +08001308 default:
1309 break;
1310 }
1311}
1312
1313int main(int argc, char **argv)
1314{
1315 int rc;
1316
Harald Weltea8379772009-06-20 22:36:41 +02001317 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1318
Harald Welte59b04682009-06-10 05:40:52 +08001319 /* parse options */
1320 handle_options(argc, argv);
1321
1322 /* seed the PRNG */
1323 srand(time(NULL));
1324
1325 rc = bootstrap_network();
1326 if (rc < 0)
1327 exit(1);
1328
Harald Welte3b714502009-08-06 17:43:50 +02001329 signal(SIGINT, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001330 signal(SIGABRT, &signal_handler);
Harald Weltea8379772009-06-20 22:36:41 +02001331 signal(SIGUSR1, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001332
1333 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001334 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001335 bsc_select_main(0);
1336 }
1337}