blob: 9e0a26096b0427d15b6ebf35a8d7a0da42391ddd [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 Welteca9af2b2009-08-06 17:54:21 +020065static int bs11_has_bts1 = 0;
Harald Welte59b04682009-06-10 05:40:52 +080066static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
Harald Welte91afe4c2009-06-20 18:15:19 +020067static enum gsm_band BAND = GSM_BAND_900;
Harald Welte59b04682009-06-10 05:40:52 +080068static const char *database_name = "hlr.sqlite3";
Harald Welte3c062072009-07-28 18:25:29 +020069extern int ipacc_rtp_direct;
Harald Welte59b04682009-06-10 05:40:52 +080070
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +020071struct nano_bts_id {
72 struct llist_head entry;
73 int site_id;
74 int bts_id;
75};
76
77static LLIST_HEAD(nanobts_ids);
78
79
Harald Welte59b04682009-06-10 05:40:52 +080080/* The following definitions are for OM and NM packets that we cannot yet
81 * generate by code but we just pass on */
82
83// BTS Site Manager, SET ATTRIBUTES
84
85/*
86 Object Class: BTS Site Manager
87 Instance 1: FF
88 Instance 2: FF
89 Instance 3: FF
90SET ATTRIBUTES
91 sAbisExternalTime: 2007/09/08 14:36:11
92 omLAPDRelTimer: 30sec
93 shortLAPDIntTimer: 5sec
94 emergencyTimer1: 10 minutes
95 emergencyTimer2: 0 minutes
96*/
97
98unsigned char msg_1[] =
99{
Harald Weltef739ae62009-06-20 10:42:17 +0200100 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800101 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
102 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
103 0x02,
104 0x00, 0x1E,
105 NM_ATT_BS11_SH_LAPD_INT_TIMER,
106 0x01, 0x05,
107 0x42, 0x02, 0x00, 0x0A,
108 0x44, 0x02, 0x00, 0x00
109};
110
111// BTS, SET BTS ATTRIBUTES
112
113/*
114 Object Class: BTS
115 BTS relat. Number: 0
116 Instance 2: FF
117 Instance 3: FF
118SET BTS ATTRIBUTES
119 bsIdentityCode / BSIC:
120 PLMN_colour_code: 7h
121 BS_colour_code: 7h
122 BTS Air Timer T3105: 4 ,unit 10 ms
123 btsIsHopping: FALSE
124 periodCCCHLoadIndication: 1sec
125 thresholdCCCHLoadIndication: 0%
126 cellAllocationNumber: 00h = GSM 900
127 enableInterferenceClass: 00h = Disabled
128 fACCHQual: 6 (FACCH stealing flags minus 1)
129 intaveParameter: 31 SACCH multiframes
130 interferenceLevelBoundaries:
131 Interference Boundary 1: 0Ah
132 Interference Boundary 2: 0Fh
133 Interference Boundary 3: 14h
134 Interference Boundary 4: 19h
135 Interference Boundary 5: 1Eh
136 mSTxPwrMax: 11
137 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
138 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
139 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
140 30=33dBm, 31=32dBm
141 ny1:
142 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
143 powerOutputThresholds:
144 Out Power Fault Threshold: -10 dB
145 Red Out Power Threshold: - 6 dB
146 Excessive Out Power Threshold: 5 dB
147 rACHBusyThreshold: -127 dBm
148 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
149 rfResourceIndicationPeriod: 125 SACCH multiframes
150 T200:
151 SDCCH: 044 in 5 ms
152 FACCH/Full rate: 031 in 5 ms
153 FACCH/Half rate: 041 in 5 ms
154 SACCH with TCH SAPI0: 090 in 10 ms
155 SACCH with SDCCH: 090 in 10 ms
156 SDCCH with SAPI3: 090 in 5 ms
157 SACCH with TCH SAPI3: 135 in 10 ms
158 tSync: 9000 units of 10 msec
159 tTrau: 9000 units of 10 msec
160 enableUmLoopTest: 00h = disabled
161 enableExcessiveDistance: 00h = Disabled
162 excessiveDistance: 64km
163 hoppingMode: 00h = baseband hopping
164 cellType: 00h = Standard Cell
165 BCCH ARFCN / bCCHFrequency: 1
166*/
167
Harald Weltef739ae62009-06-20 10:42:17 +0200168static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800169{
Harald Welte59b04682009-06-10 05:40:52 +0800170 NM_ATT_BSIC, HARDCODED_BSIC,
171 NM_ATT_BTS_AIR_TIMER, 0x04,
172 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
173 NM_ATT_CCCH_L_I_P, 0x01,
174 NM_ATT_CCCH_L_T, 0x00,
175 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
176 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
177 NM_ATT_BS11_FACCH_QUAL, 0x06,
178 /* interference avg. period in numbers of SACCH multifr */
179 NM_ATT_INTAVE_PARAM, 0x1F,
180 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
181 NM_ATT_CCCH_L_T, 0x23,
182 NM_ATT_GSM_TIME, 0x28, 0x00,
183 NM_ATT_ADM_STATE, 0x03,
184 NM_ATT_RACH_B_THRESH, 0x7F,
185 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
186 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
187 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
188 NM_ATT_BS11_TSYNC, 0x23, 0x28,
189 NM_ATT_BS11_TTRAU, 0x23, 0x28,
190 NM_ATT_TEST_DUR, 0x01, 0x00,
191 NM_ATT_OUTST_ALARM, 0x01, 0x00,
192 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
193 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
194 NM_ATT_BS11_PLL, 0x01, 0x00,
195 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
196};
197
198// Handover Recognition, SET ATTRIBUTES
199
200/*
201Illegal Contents GSM Formatted O&M Msg
202 Object Class: Handover Recognition
203 BTS relat. Number: 0
204 Instance 2: FF
205 Instance 3: FF
206SET ATTRIBUTES
207 enableDelayPowerBudgetHO: 00h = Disabled
208 enableDistanceHO: 00h = Disabled
209 enableInternalInterCellHandover: 00h = Disabled
210 enableInternalIntraCellHandover: 00h = Disabled
211 enablePowerBudgetHO: 00h = Disabled
212 enableRXLEVHO: 00h = Disabled
213 enableRXQUALHO: 00h = Disabled
214 hoAveragingDistance: 8 SACCH multiframes
215 hoAveragingLev:
216 A_LEV_HO: 8 SACCH multiframes
217 W_LEV_HO: 1 SACCH multiframes
218 hoAveragingPowerBudget: 16 SACCH multiframes
219 hoAveragingQual:
220 A_QUAL_HO: 8 SACCH multiframes
221 W_QUAL_HO: 2 SACCH multiframes
222 hoLowerThresholdLevDL: (10 - 110) dBm
223 hoLowerThresholdLevUL: (5 - 110) dBm
224 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
225 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
226 hoThresholdLevDLintra : (20 - 110) dBm
227 hoThresholdLevULintra: (20 - 110) dBm
228 hoThresholdMsRangeMax: 20 km
229 nCell: 06h
230 timerHORequest: 3 ,unit 2 SACCH multiframes
231*/
232
233unsigned char msg_3[] =
234{
Harald Weltef739ae62009-06-20 10:42:17 +0200235 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Weltec7d75062009-07-18 16:18:11 +0200236 0xD0, 0x00, /* enableDelayPowerBudgetHO */
237 0x64, 0x00, /* enableDistanceHO */
238 0x67, 0x00, /* enableInternalInterCellHandover */
239 0x68, 0x00, /* enableInternalInterCellHandover */
240 0x6A, 0x00, /* enablePowerBudgetHO */
241 0x6C, 0x00, /* enableRXLEVHO */
242 0x6D, 0x00, /* enableRXQUALHO */
243 0x6F, 0x08, /* hoAveragingDistance */
244 0x70, 0x08, 0x01, /* hoAveragingLev */
Harald Welte59b04682009-06-10 05:40:52 +0800245 0x71, 0x10, 0x10, 0x10,
Harald Weltec7d75062009-07-18 16:18:11 +0200246 0x72, 0x08, 0x02, /* hoAveragingQual */
247 0x73, 0x0A, /* hoLowerThresholdLevDL */
248 0x74, 0x05, /* hoLowerThresholdLevUL */
249 0x75, 0x06, /* hoLowerThresholdQualDL */
250 0x76, 0x06, /* hoLowerThresholdQualUL */
251 0x78, 0x14, /* hoThresholdLevDLintra */
252 0x79, 0x14, /* hoThresholdLevULintra */
253 0x7A, 0x14, /* hoThresholdMsRangeMax */
254 0x7D, 0x06, /* nCell */
255 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
256 0x20, 0x01, 0x00,
Harald Welte59b04682009-06-10 05:40:52 +0800257 0x45, 0x01, 0x00,
258 0x48, 0x01, 0x00,
259 0x5A, 0x01, 0x00,
260 0x5B, 0x01, 0x05,
261 0x5E, 0x01, 0x1A,
262 0x5F, 0x01, 0x20,
263 0x9D, 0x01, 0x00,
264 0x47, 0x01, 0x00,
265 0x5C, 0x01, 0x64,
266 0x5D, 0x01, 0x1E,
267 0x97, 0x01, 0x20,
268 0xF7, 0x01, 0x3C,
269};
270
271// Power Control, SET ATTRIBUTES
272
273/*
274 Object Class: Power Control
275 BTS relat. Number: 0
276 Instance 2: FF
277 Instance 3: FF
278SET ATTRIBUTES
279 enableMsPowerControl: 00h = Disabled
280 enablePowerControlRLFW: 00h = Disabled
281 pcAveragingLev:
282 A_LEV_PC: 4 SACCH multiframes
283 W_LEV_PC: 1 SACCH multiframes
284 pcAveragingQual:
285 A_QUAL_PC: 4 SACCH multiframes
286 W_QUAL_PC: 2 SACCH multiframes
287 pcLowerThresholdLevDL: 0Fh
288 pcLowerThresholdLevUL: 0Ah
289 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
290 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
291 pcRLFThreshold: 0Ch
292 pcUpperThresholdLevDL: 14h
293 pcUpperThresholdLevUL: 0Fh
294 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
295 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
296 powerConfirm: 2 ,unit 2 SACCH multiframes
297 powerControlInterval: 2 ,unit 2 SACCH multiframes
298 powerIncrStepSize: 02h = 4 dB
299 powerRedStepSize: 01h = 2 dB
300 radioLinkTimeoutBs: 64 SACCH multiframes
301 enableBSPowerControl: 00h = disabled
302*/
303
304unsigned char msg_4[] =
305{
Harald Weltef739ae62009-06-20 10:42:17 +0200306 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800307 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
308 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Weltec7d75062009-07-18 16:18:11 +0200309 0x7E, 0x04, 0x01, /* pcAveragingLev */
310 0x7F, 0x04, 0x02, /* pcAveragingQual */
311 0x80, 0x0F, /* pcLowerThresholdLevDL */
312 0x81, 0x0A, /* pcLowerThresholdLevUL */
313 0x82, 0x05, /* pcLowerThresholdQualDL */
314 0x83, 0x05, /* pcLowerThresholdQualUL */
315 0x84, 0x0C, /* pcRLFThreshold */
316 0x85, 0x14, /* pcUpperThresholdLevDL */
317 0x86, 0x0F, /* pcUpperThresholdLevUL */
318 0x87, 0x04, /* pcUpperThresholdQualDL */
319 0x88, 0x04, /* pcUpperThresholdQualUL */
320 0x89, 0x02, /* powerConfirm */
321 0x8A, 0x02, /* powerConfirmInterval */
322 0x8B, 0x02, /* powerIncrStepSize */
323 0x8C, 0x01, /* powerRedStepSize */
324 0x8D, 0x40, /* radioLinkTimeoutBs */
Harald Welte59b04682009-06-10 05:40:52 +0800325 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
326};
327
328
329// Transceiver, SET TRX ATTRIBUTES (TRX 0)
330
331/*
332 Object Class: Transceiver
333 BTS relat. Number: 0
334 Tranceiver number: 0
335 Instance 3: FF
336SET TRX ATTRIBUTES
337 aRFCNList (HEX): 0001
338 txPwrMaxReduction: 00h = 30dB
339 radioMeasGran: 254 SACCH multiframes
340 radioMeasRep: 01h = enabled
341 memberOfEmergencyConfig: 01h = TRUE
342 trxArea: 00h = TRX doesn't belong to a concentric cell
343*/
344
Harald Weltef739ae62009-06-20 10:42:17 +0200345static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800346{
Harald Welte59b04682009-06-10 05:40:52 +0800347 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
348 NM_ATT_RF_MAXPOWR_R, 0x00,
349 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
350 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
351 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
352 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
353};
354
355static unsigned char nanobts_attr_bts[] = {
356 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
357 /* interference avg. period in numbers of SACCH multifr */
358 NM_ATT_INTAVE_PARAM, 0x06,
359 /* conn fail based on SACCH error rate */
360 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
361 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
362 NM_ATT_MAX_TA, 0x3f,
363 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
364 NM_ATT_CCCH_L_T, 10, /* percent */
365 NM_ATT_CCCH_L_I_P, 1, /* seconds */
366 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
367 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
368 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
369 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
370 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
371 NM_ATT_BSIC, HARDCODED_BSIC,
372};
373
374static unsigned char nanobts_attr_radio[] = {
375 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
376 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
377};
378
379static unsigned char nanobts_attr_e0[] = {
Harald Welte4206d982009-07-12 09:33:54 +0200380 NM_ATT_IPACC_STREAM_ID, 0x00,
381 NM_ATT_IPACC_DST_IP_PORT, 0x0b, 0xbb, /* TCP PORT for RSL */
Harald Welte59b04682009-06-10 05:40:52 +0800382};
383
384/* Callback function to be called whenever we get a GSM 12.21 state change event */
385int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
386 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
387{
388 struct gsm_bts *bts;
389 struct gsm_bts_trx *trx;
390 struct gsm_bts_trx_ts *ts;
391
392 /* This is currently only required on nanoBTS */
393
394 switch (evt) {
395 case EVT_STATECHG_OPER:
396 switch (obj_class) {
397 case NM_OC_SITE_MANAGER:
398 bts = container_of(obj, struct gsm_bts, site_mgr);
399 if (old_state->operational != 2 && new_state->operational == 2) {
400 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
401 }
402 break;
403 case NM_OC_BTS:
404 bts = obj;
405 if (new_state->availability == 5) {
406 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
407 sizeof(nanobts_attr_bts));
408 abis_nm_opstart(bts, NM_OC_BTS,
409 bts->bts_nr, 0xff, 0xff);
410 abis_nm_chg_adm_state(bts, NM_OC_BTS,
411 bts->bts_nr, 0xff, 0xff,
412 NM_STATE_UNLOCKED);
413 }
414 break;
415 case NM_OC_CHANNEL:
416 ts = obj;
417 trx = ts->trx;
418 if (new_state->availability == 5) {
419 if (ts->nr == 0 && trx == trx->bts->c0)
420 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
421 else
422 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
423 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
424 trx->bts->bts_nr, trx->nr, ts->nr);
425 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
426 trx->bts->bts_nr, trx->nr, ts->nr,
427 NM_STATE_UNLOCKED);
428 }
429 break;
430 default:
431 break;
432 }
433 break;
434 default:
435 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
436 break;
437 }
438 return 0;
439}
440
441/* Callback function to be called every time we receive a 12.21 SW activated report */
442static int sw_activ_rep(struct msgb *mb)
443{
444 struct abis_om_fom_hdr *foh = msgb_l3(mb);
445 struct gsm_bts_trx *trx = mb->trx;
446
447 switch (foh->obj_class) {
448 case NM_OC_BASEB_TRANSC:
449 /* TRX software is active, tell it to initiate RSL Link */
450 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
451 trx->bts->bts_nr, trx->nr, 0xff,
452 nanobts_attr_e0, sizeof(nanobts_attr_e0));
453 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
454 trx->bts->bts_nr, trx->nr, 0xff);
455 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
456 trx->bts->bts_nr, trx->nr, 0xff,
457 NM_STATE_UNLOCKED);
458 break;
459 case NM_OC_RADIO_CARRIER:
460 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
461 sizeof(nanobts_attr_radio));
462 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
463 trx->bts->bts_nr, trx->nr, 0xff);
464 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
465 trx->bts->bts_nr, trx->nr, 0xff,
466 NM_STATE_UNLOCKED);
467 break;
468 }
469 return 0;
470}
471
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200472/* Callback function for NACK on the OML NM */
473static int oml_msg_nack(int mt)
474{
475 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
476 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
477 "Was the bts type and frequency properly specified?\n");
478 exit(-1);
479 }
480
481 return 0;
482}
483
Harald Welte59b04682009-06-10 05:40:52 +0800484/* Callback function to be called every time we receive a signal from NM */
485static int nm_sig_cb(unsigned int subsys, unsigned int signal,
486 void *handler_data, void *signal_data)
487{
488 switch (signal) {
489 case S_NM_SW_ACTIV_REP:
490 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200491 case S_NM_NACK:
492 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800493 default:
494 break;
495 }
496 return 0;
497}
498
499static void bootstrap_om_nanobts(struct gsm_bts *bts)
500{
501 /* We don't do callback based bootstrapping, but event driven (see above) */
502}
503
504static void bootstrap_om_bs11(struct gsm_bts *bts)
505{
Harald Weltee712a5f2009-06-21 16:17:15 +0200506 struct gsm_bts_trx *trx = bts->c0;
Harald Weltecf833cd2009-08-06 17:40:24 +0200507 int base_ts;
508
509 switch (bts->nr) {
510 case 0:
511 /* First BTS uses E1 TS 01,02,03,04,05 */
512 base_ts = HARDCODED_BTS0_TS - 1;
513 break;
514 case 1:
515 /* Second BTS uses E1 TS 06,07,08,09,10 */
516 base_ts = HARDCODED_BTS1_TS - 1;
517 break;
518 case 2:
519 /* Third BTS uses E1 TS 11,12,13,14,15 */
520 base_ts = HARDCODED_BTS2_TS - 1;
521 default:
522 return;
523 }
Harald Welte59b04682009-06-10 05:40:52 +0800524
525 /* stop sending event reports */
526 abis_nm_event_reports(bts, 0);
527
528 /* begin DB transmission */
529 abis_nm_bs11_db_transmission(bts, 1);
530
531 /* end DB transmission */
532 abis_nm_bs11_db_transmission(bts, 0);
533
534 /* Reset BTS Site manager resource */
535 abis_nm_bs11_reset_resource(bts);
536
537 /* begin DB transmission */
538 abis_nm_bs11_db_transmission(bts, 1);
539
540 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltef739ae62009-06-20 10:42:17 +0200541 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800542 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
543 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
544
545 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200546 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Weltef739ae62009-06-20 10:42:17 +0200547 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800548
549 /* Use TEI 1 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200550 abis_nm_establish_tei(bts, 0, 0, base_ts+1, 0xff, 0x01);
Harald Welte59b04682009-06-10 05:40:52 +0800551 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
552
Harald Welte59b04682009-06-10 05:40:52 +0800553 /* SET CHANNEL ATTRIBUTE TS1 */
554 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
555 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200556 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+2, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800557
558 /* SET CHANNEL ATTRIBUTE TS2 */
559 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
560 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200561 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+2, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800562
563 /* SET CHANNEL ATTRIBUTE TS3 */
564 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
565 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200566 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+2, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800567
568 /* SET CHANNEL ATTRIBUTE TS4 */
569 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
570 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200571 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+3, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800572
573 /* SET CHANNEL ATTRIBUTE TS5 */
574 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
575 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200576 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+3, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800577
578 /* SET CHANNEL ATTRIBUTE TS6 */
579 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
580 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200581 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+3, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800582
583 /* SET CHANNEL ATTRIBUTE TS7 */
584 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
585 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200586 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+3, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800587
Harald Welte25b70c52009-07-29 16:42:16 +0200588 trx = gsm_bts_trx_num(bts, 1);
589 if (trx) {
590 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
591 u_int8_t arfcn_low = trx->arfcn & 0xff;
592 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
593 memcpy(trx1_attr_radio, bs11_attr_radio,
594 sizeof(trx1_attr_radio));
595
596 /* patch ARFCN into TRX Attributes */
597 trx1_attr_radio[2] &= 0xf0;
598 trx1_attr_radio[2] |= arfcn_high;
599 trx1_attr_radio[3] = arfcn_low;
600
601 /* Connect signalling of TRX1 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200602 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Welte25b70c52009-07-29 16:42:16 +0200603 /* FIXME: TRX ATTRIBUTE */
604 abis_nm_set_radio_attr(trx, trx1_attr_radio,
605 sizeof(trx1_attr_radio));
606
607 /* Use TEI 2 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200608 abis_nm_establish_tei(bts, 1, 0, base_ts+1, 0xff, 0x02);
Harald Welte25b70c52009-07-29 16:42:16 +0200609
Harald Welte1a503162009-08-04 01:31:53 +0200610 /* SET CHANNEL ATTRIBUTE TS0 */
611 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_TCHFull);
612 /* Connect traffic of bts0/trx0/ts0 to e1_0/ts4/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200613 abis_nm_conn_terr_traf(&trx->ts[0], 0, base_ts+4, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200614
615 /* SET CHANNEL ATTRIBUTE TS1 */
616 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
617 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200618 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+4, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200619
620 /* SET CHANNEL ATTRIBUTE TS2 */
621 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
622 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200623 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+4, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200624
625 /* SET CHANNEL ATTRIBUTE TS3 */
626 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
627 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200628 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+4, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200629
630 /* SET CHANNEL ATTRIBUTE TS4 */
631 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
632 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200633 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+5, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200634
635 /* SET CHANNEL ATTRIBUTE TS5 */
636 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
637 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200638 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+5, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200639
640 /* SET CHANNEL ATTRIBUTE TS6 */
641 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
642 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200643 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+5, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200644
645 /* SET CHANNEL ATTRIBUTE TS7 */
646 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
647 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200648 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+5, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200649 }
650
Harald Welte59b04682009-06-10 05:40:52 +0800651 /* end DB transmission */
652 abis_nm_bs11_db_transmission(bts, 0);
653
654 /* Reset BTS Site manager resource */
655 abis_nm_bs11_reset_resource(bts);
656
657 /* restart sending event reports */
658 abis_nm_event_reports(bts, 1);
659}
660
661static void bootstrap_om(struct gsm_bts *bts)
662{
663 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
664
665 switch (bts->type) {
666 case GSM_BTS_TYPE_BS11:
667 bootstrap_om_bs11(bts);
668 break;
669 case GSM_BTS_TYPE_NANOBTS_900:
670 case GSM_BTS_TYPE_NANOBTS_1800:
671 bootstrap_om_nanobts(bts);
672 break;
673 default:
674 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
675 }
676}
677
678static int shutdown_om(struct gsm_bts *bts)
679{
Harald Welte3b714502009-08-06 17:43:50 +0200680 fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
681
Harald Welte59b04682009-06-10 05:40:52 +0800682 /* stop sending event reports */
683 abis_nm_event_reports(bts, 0);
684
685 /* begin DB transmission */
686 abis_nm_bs11_db_transmission(bts, 1);
687
688 /* end DB transmission */
689 abis_nm_bs11_db_transmission(bts, 0);
690
691 /* Reset BTS Site manager resource */
692 abis_nm_bs11_reset_resource(bts);
693
694 return 0;
695}
696
697static int shutdown_net(struct gsm_network *net)
698{
Harald Weltee712a5f2009-06-21 16:17:15 +0200699 struct gsm_bts *bts;
700
701 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welte59b04682009-06-10 05:40:52 +0800702 int rc;
Harald Weltee712a5f2009-06-21 16:17:15 +0200703 rc = shutdown_om(bts);
Harald Welte59b04682009-06-10 05:40:52 +0800704 if (rc < 0)
705 return rc;
706 }
707
708 return 0;
709}
710
711struct bcch_info {
712 u_int8_t type;
713 u_int8_t len;
714 const u_int8_t *data;
715};
716
717/*
718SYSTEM INFORMATION TYPE 1
719 Cell channel description
720 Format-ID bit map 0
721 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
722 RACH Control Parameters
723 maximum 7 retransmissions
724 8 slots used to spread transmission
725 cell not barred for access
726 call reestablishment not allowed
727 Access Control Class = 0000
728*/
729static u_int8_t si1[] = {
730 /* header */0x55, 0x06, 0x19,
731 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
733 /* rach */0xD5, 0x00, 0x00,
734 /* s1 reset*/0x2B
735};
736
737/*
738 SYSTEM INFORMATION TYPE 2
739 Neighbour Cells Description
740 EXT-IND: Carries the complete BA
741 BA-IND = 0
742 Format-ID bit map 0
743 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
744 NCC permitted (NCC) = FF
745 RACH Control Parameters
746 maximum 7 retransmissions
747 8 slots used to spread transmission
748 cell not barred for access
749 call reestablishment not allowed
750 Access Control Class = 0000
751*/
752static u_int8_t si2[] = {
753 /* header */0x59, 0x06, 0x1A,
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756 /* ncc */0xFF,
757 /* rach*/0xD5, 0x00, 0x00
758};
759
760/*
761SYSTEM INFORMATION TYPE 3
762 Cell identity = 00001 (1h)
763 Location area identification
764 Mobile Country Code (MCC): 001
765 Mobile Network Code (MNC): 01
766 Location Area Code (LAC): 00001 (1h)
767 Control Channel Description
768 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
769 0 blocks reserved for access grant
770 1 channel used for CCCH, with SDCCH
771 5 multiframes period for PAGING REQUEST
772 Time-out T3212 = 0
773 Cell Options BCCH
774 Power control indicator: not set
775 MSs shall not use uplink DTX
776 Radio link timeout = 36
777 Cell Selection Parameters
778 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
779 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
780 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
781 Half rate support (NECI): New establishment causes are not supported
782 min.RX signal level for MS = 0
783 RACH Control Parameters
784 maximum 7 retransmissions
785 8 slots used to spread transmission
786 cell not barred for access
787 call reestablishment not allowed
788 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200789 SI 3 Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800790*/
791static u_int8_t si3[] = {
792 /* header */0x49, 0x06, 0x1B,
793 /* cell */0x00, 0x01,
794 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
795 /* desc */0x01, 0x03, 0x00,
796 /* option*/0x28,
797 /* selection*/0x62, 0x00,
798 /* rach */0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200799 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800800};
801
802/*
803SYSTEM INFORMATION TYPE 4
804 Location area identification
805 Mobile Country Code (MCC): 001
806 Mobile Network Code (MNC): 01
807 Location Area Code (LAC): 00001 (1h)
808 Cell Selection Parameters
809 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
810 max.TX power level MS may use for CCH = 2
811 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
812 Half rate support (NECI): New establishment causes are not supported
813 min.RX signal level for MS = 0
814 RACH Control Parameters
815 maximum 7 retransmissions
816 8 slots used to spread transmission
817 cell not barred for access
818 call reestablishment not allowed
819 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200820 CBCH Channel Description
Harald Welte59b04682009-06-10 05:40:52 +0800821 Type = SDCCH/4[2]
822 Timeslot Number: 0
823 Training Sequence Code: 7h
824 ARFCN: 1
Harald Weltec1c4a952009-07-05 13:41:40 +0200825 SI Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800826*/
827static u_int8_t si4[] = {
828 /* header */0x41, 0x06, 0x1C,
829 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
830 /* sel */0x62, 0x00,
831 /* rach*/0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200832 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
833 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800834};
835
836/*
837 SYSTEM INFORMATION TYPE 5
838 Neighbour Cells Description
839 EXT-IND: Carries the complete BA
840 BA-IND = 0
841 Format-ID bit map 0
842 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
843*/
844
845static u_int8_t si5[] = {
846 /* header without l2 len*/0x06, 0x1D,
847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849};
850
851// SYSTEM INFORMATION TYPE 6
852
853/*
854SACCH FILLING
855 System Info Type: SYSTEM INFORMATION 6
856 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
857
858SYSTEM INFORMATION TYPE 6
859 Cell identity = 00001 (1h)
860 Location area identification
861 Mobile Country Code (MCC): 001
862 Mobile Network Code (MNC): 01
863 Location Area Code (LAC): 00001 (1h)
864 Cell Options SACCH
865 Power control indicator: not set
866 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
867 Radio link timeout = 36
868 NCC permitted (NCC) = FF
869*/
870
871static u_int8_t si6[] = {
872 /* header */0x06, 0x1E,
873 /* cell id*/ 0x00, 0x01,
874 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
875 /* options */ 0x28,
876 /* ncc */ 0xFF,
877};
878
879
880
881static const struct bcch_info bcch_infos[] = {
882 {
883 .type = RSL_SYSTEM_INFO_1,
884 .len = sizeof(si1),
885 .data = si1,
886 }, {
887 .type = RSL_SYSTEM_INFO_2,
888 .len = sizeof(si2),
889 .data = si2,
890 }, {
891 .type = RSL_SYSTEM_INFO_3,
892 .len = sizeof(si3),
893 .data = si3,
894 }, {
895 .type = RSL_SYSTEM_INFO_4,
896 .len = sizeof(si4),
897 .data = si4,
898 },
899};
900
901static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
902static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
903static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
904static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
905static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
906static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
907
908/* set all system information types */
909static int set_system_infos(struct gsm_bts_trx *trx)
910{
911 int i;
912
Harald Welte6ab22d22009-08-06 17:41:19 +0200913 if (trx == trx->bts->c0) {
914 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
915 rsl_bcch_info(trx, bcch_infos[i].type,
916 bcch_infos[i].data,
917 bcch_infos[i].len);
918 }
Harald Welte59b04682009-06-10 05:40:52 +0800919 }
920 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
921 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
922
923 return 0;
924}
925
926/*
927 * Patch the various SYSTEM INFORMATION tables to update
928 * the LAI
929 */
930static void patch_tables(struct gsm_bts *bts)
931{
Harald Weltee712a5f2009-06-21 16:17:15 +0200932 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
933 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Harald Welte59b04682009-06-10 05:40:52 +0800934 /* covert the raw packet to the struct */
935 struct gsm48_system_information_type_3 *type_3 =
936 (struct gsm48_system_information_type_3*)&si3;
937 struct gsm48_system_information_type_4 *type_4 =
938 (struct gsm48_system_information_type_4*)&si4;
939 struct gsm48_system_information_type_6 *type_6 =
940 (struct gsm48_system_information_type_6*)&si6;
941 struct gsm48_loc_area_id lai;
942
943 gsm0408_generate_lai(&lai, bts->network->country_code,
944 bts->network->network_code,
945 bts->location_area_code);
946
947 /* assign the MCC and MNC */
948 type_3->lai = lai;
949 type_4->lai = lai;
950 type_6->lai = lai;
951
952 /* patch ARFCN into BTS Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200953 bs11_attr_bts[69] &= 0xf0;
954 bs11_attr_bts[69] |= arfcn_high;
955 bs11_attr_bts[70] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800956 nanobts_attr_bts[42] &= 0xf0;
957 nanobts_attr_bts[42] |= arfcn_high;
958 nanobts_attr_bts[43] = arfcn_low;
959
960 /* patch ARFCN into TRX Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200961 bs11_attr_radio[2] &= 0xf0;
962 bs11_attr_radio[2] |= arfcn_high;
963 bs11_attr_radio[3] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800964 nanobts_attr_radio[5] &= 0xf0;
965 nanobts_attr_radio[5] |= arfcn_high;
966 nanobts_attr_radio[6] = arfcn_low;
967
968 type_4->data[2] &= 0xf0;
969 type_4->data[2] |= arfcn_high;
970 type_4->data[3] = arfcn_low;
971
972 /* patch Control Channel Description 10.5.2.11 */
973 type_3->control_channel_desc = bts->chan_desc;
974
975 /* patch BSIC */
Harald Weltef739ae62009-06-20 10:42:17 +0200976 bs11_attr_bts[1] = bts->bsic;
Harald Welte59b04682009-06-10 05:40:52 +0800977 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
Harald Welte52281c12009-07-21 22:12:23 +0200978
979 /* patch TSC */
980 si4[15] &= ~0xe0;
981 si4[15] |= (bts->tsc & 7) << 5;
Harald Welte59b04682009-06-10 05:40:52 +0800982}
983
984
985static void bootstrap_rsl(struct gsm_bts_trx *trx)
986{
987 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte52281c12009-07-21 22:12:23 +0200988 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
Harald Welte1a503162009-08-04 01:31:53 +0200989 trx->bts->nr, trx->nr, MCC, MNC, BSIC, TSC);
Harald Welte59b04682009-06-10 05:40:52 +0800990 set_system_infos(trx);
991}
992
993void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
994{
995 switch (event) {
996 case EVT_E1_TEI_UP:
997 switch (type) {
998 case E1INP_SIGN_OML:
999 bootstrap_om(trx->bts);
1000 break;
1001 case E1INP_SIGN_RSL:
1002 bootstrap_rsl(trx);
1003 break;
1004 default:
1005 break;
1006 }
1007 break;
1008 case EVT_E1_TEI_DN:
1009 fprintf(stderr, "Lost some E1 TEI link\n");
1010 /* FIXME: deal with TEI or L1 link loss */
1011 break;
1012 default:
1013 break;
1014 }
1015}
1016
1017static int bootstrap_bts(struct gsm_bts *bts)
1018{
Harald Welte91afe4c2009-06-20 18:15:19 +02001019 bts->band = BAND;
Harald Welte59b04682009-06-10 05:40:52 +08001020 bts->location_area_code = LAC;
Harald Weltee712a5f2009-06-21 16:17:15 +02001021 bts->c0->arfcn = ARFCN;
Harald Welte59b04682009-06-10 05:40:52 +08001022
1023 /* Control Channel Description */
1024 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
1025 bts->chan_desc.att = 1;
1026 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1027 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1028 bts->chan_desc.t3212 = 0;
1029
1030 patch_tables(bts);
1031
1032 paging_init(bts);
1033
1034 if (bts->type == GSM_BTS_TYPE_BS11) {
Harald Weltee712a5f2009-06-21 16:17:15 +02001035 struct gsm_bts_trx *trx = bts->c0;
Harald Welte59b04682009-06-10 05:40:52 +08001036 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
1037 set_ts_e1link(&trx->ts[1], 0, 2, 1);
1038 set_ts_e1link(&trx->ts[2], 0, 2, 2);
1039 set_ts_e1link(&trx->ts[3], 0, 2, 3);
1040 set_ts_e1link(&trx->ts[4], 0, 3, 0);
1041 set_ts_e1link(&trx->ts[5], 0, 3, 1);
1042 set_ts_e1link(&trx->ts[6], 0, 3, 2);
1043 set_ts_e1link(&trx->ts[7], 0, 3, 3);
Harald Welte25b70c52009-07-29 16:42:16 +02001044
Harald Welte59b04682009-06-10 05:40:52 +08001045 /* TRX 1 */
Harald Welte25b70c52009-07-29 16:42:16 +02001046 trx = gsm_bts_trx_num(bts, 1);
1047 if (trx) {
1048 trx = gsm_bts_trx_num(bts, 1);
1049 set_ts_e1link(&trx->ts[0], 0, 4, 0);
1050 set_ts_e1link(&trx->ts[1], 0, 4, 1);
1051 set_ts_e1link(&trx->ts[2], 0, 4, 2);
1052 set_ts_e1link(&trx->ts[3], 0, 4, 3);
1053 set_ts_e1link(&trx->ts[4], 0, 5, 0);
1054 set_ts_e1link(&trx->ts[5], 0, 5, 1);
1055 set_ts_e1link(&trx->ts[6], 0, 5, 2);
1056 set_ts_e1link(&trx->ts[7], 0, 5, 3);
1057 }
Harald Welte59b04682009-06-10 05:40:52 +08001058 }
1059
1060 return 0;
1061}
1062
1063static int bootstrap_network(void)
1064{
Harald Welteca9af2b2009-08-06 17:54:21 +02001065 int rc;
1066
Holger Hans Peter Freytheref5f4182009-06-10 10:20:16 +02001067 switch(BTS_TYPE) {
1068 case GSM_BTS_TYPE_NANOBTS_1800:
1069 if (ARFCN < 512 || ARFCN > 885) {
1070 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
1071 return -EINVAL;
1072 }
1073 break;
1074 case GSM_BTS_TYPE_BS11:
1075 case GSM_BTS_TYPE_NANOBTS_900:
1076 /* Assume we have a P-GSM900 here */
1077 if (ARFCN < 1 || ARFCN > 124) {
1078 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1079 return -EINVAL;
1080 }
1081 break;
1082 case GSM_BTS_TYPE_UNKNOWN:
1083 fprintf(stderr, "Unknown BTS. Please use the --bts-type switch\n");
1084 return -EINVAL;
1085 }
1086
Harald Welte59b04682009-06-10 05:40:52 +08001087 /* initialize our data structures */
Harald Weltee712a5f2009-06-21 16:17:15 +02001088 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +08001089 if (!gsmnet)
1090 return -ENOMEM;
1091
1092 gsmnet->name_long = "OpenBSC";
1093 gsmnet->name_short = "OpenBSC";
1094
Harald Welte59b04682009-06-10 05:40:52 +08001095 if (db_init(database_name)) {
1096 printf("DB: Failed to init database. Please check the option settings.\n");
1097 return -1;
1098 }
1099 printf("DB: Database initialized.\n");
1100
1101 if (db_prepare()) {
1102 printf("DB: Failed to prepare database.\n");
1103 return -1;
1104 }
1105 printf("DB: Database prepared.\n");
1106
1107 telnet_init(gsmnet, 4242);
1108
1109 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1110
1111 /* E1 mISDN input setup */
1112 if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
Harald Welte52281c12009-07-21 22:12:23 +02001113 struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Harald Welte25b70c52009-07-29 16:42:16 +02001114
1115 if (bs11_has_trx1) {
1116 struct gsm_bts_trx *trx1;
1117 trx1 = gsm_bts_trx_alloc(bts);
1118 trx1->arfcn = ARFCN + 2;
1119 }
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001120 bootstrap_bts(bts);
Harald Welteca9af2b2009-08-06 17:54:21 +02001121 rc = e1_config(bts, cardnr, release_l2);
1122 if (rc < 0) {
1123 fprintf(stderr, "Error during E1 config of BTS 0\n");
1124 return rc;
1125 }
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001126
Harald Welteca9af2b2009-08-06 17:54:21 +02001127 if (bs11_has_bts1) {
1128 bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
1129 if (bs11_has_trx1) {
1130 struct gsm_bts_trx *trx1;
1131 trx1 = gsm_bts_trx_alloc(bts);
1132 trx1->arfcn = ARFCN + 2;
1133 }
1134 bootstrap_bts(bts);
1135 rc = e1_config(bts, cardnr+1, release_l2);
1136 if (rc < 0)
1137 fprintf(stderr, "Error during E1 config of BTS 1\n");
1138 }
1139 return rc;
Harald Welte59b04682009-06-10 05:40:52 +08001140 } else {
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001141 struct nano_bts_id *bts_id;
1142 struct gsm_bts *bts;
Harald Welte91afe4c2009-06-20 18:15:19 +02001143
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001144 if (llist_empty(&nanobts_ids)) {
1145 fprintf(stderr, "You need to specify -i DEVICE_1 -i DEVICE_2 for nanoBTS.\n");
1146 return -EINVAL;
1147 }
1148
1149 llist_for_each_entry(bts_id, &nanobts_ids, entry) {
Harald Welte52281c12009-07-21 22:12:23 +02001150 bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001151 bootstrap_bts(bts);
1152 bts->ip_access.site_id = bts_id->site_id;
1153 bts->ip_access.bts_id = 0;
1154 }
1155
Harald Welte59b04682009-06-10 05:40:52 +08001156 return ipaccess_setup(gsmnet);
1157 }
1158}
1159
1160static void create_pcap_file(char *file)
1161{
1162 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1163 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1164
1165 if (fd < 0) {
1166 perror("Failed to open file for pcap");
1167 return;
1168 }
1169
1170 e1_set_pcap_fd(fd);
1171}
1172
1173static void print_usage()
1174{
1175 printf("Usage: bsc_hack\n");
1176}
1177
1178static void print_help()
1179{
1180 printf(" Some useful help...\n");
1181 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1182 printf(" -s --disable-color\n");
1183 printf(" -n --network-code number(MNC) \n");
1184 printf(" -c --country-code number (MCC) \n");
1185 printf(" -L --location-area-code number (LAC) \n");
1186 printf(" -f --arfcn number The frequency ARFCN\n");
1187 printf(" -l --database db-name The database to use\n");
1188 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1189 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1190 printf(" -p --pcap file The filename of the pcap file\n");
1191 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001192 printf(" -i --bts-id=NUMBER The known nanoBTS device numbers. Can be specified multiple times.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001193 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1194 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
Harald Welteca9af2b2009-08-06 17:54:21 +02001195 printf(" -2 --second-bs11 Configure + Use a second BS-11\n");
Harald Welte59b04682009-06-10 05:40:52 +08001196 printf(" -h --help this text\n");
1197}
1198
1199static void handle_options(int argc, char** argv)
1200{
1201 while (1) {
Harald Weltea8379772009-06-20 22:36:41 +02001202 int option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001203 static struct option long_options[] = {
1204 {"help", 0, 0, 'h'},
1205 {"debug", 1, 0, 'd'},
1206 {"disable-color", 0, 0, 's'},
1207 {"network-code", 1, 0, 'n'},
1208 {"country-code", 1, 0, 'c'},
1209 {"location-area-code", 1, 0, 'L'},
1210 {"database", 1, 0, 'l'},
1211 {"authorize-everyone", 0, 0, 'a'},
1212 {"reject-cause", 1, 0, 'r'},
1213 {"pcap", 1, 0, 'p'},
1214 {"arfcn", 1, 0, 'f'},
1215 {"bts-type", 1, 0, 't'},
1216 {"cardnr", 1, 0, 'C'},
1217 {"release-l2", 0, 0, 'R'},
1218 {"timestamp", 0, 0, 'T'},
Harald Welte91afe4c2009-06-20 18:15:19 +02001219 {"band", 0, 0, 'b'},
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001220 {"bts-id", 1, 0, 'i'},
Harald Welte52281c12009-07-21 22:12:23 +02001221 {"tsc", 1, 0, 'S'},
1222 {"bsic", 1, 0, 'B'},
Harald Welte3c062072009-07-28 18:25:29 +02001223 {"rtp-proxy", 0, 0, 'P'},
Harald Welte25b70c52009-07-29 16:42:16 +02001224 {"trx1", 0, 0, '1'},
Harald Welteca9af2b2009-08-06 17:54:21 +02001225 {"second-bs11", 0, 0, '2'},
Harald Welte59b04682009-06-10 05:40:52 +08001226 {0, 0, 0, 0}
1227 };
1228
Harald Welteca9af2b2009-08-06 17:54:21 +02001229 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:P12",
Harald Welte59b04682009-06-10 05:40:52 +08001230 long_options, &option_index);
1231 if (c == -1)
1232 break;
1233
1234 switch (c) {
1235 case 'h':
1236 print_usage();
1237 print_help();
1238 exit(0);
1239 case 's':
1240 debug_use_color(0);
1241 break;
1242 case 'd':
1243 debug_parse_category_mask(optarg);
1244 break;
1245 case 'n':
1246 MNC = atoi(optarg);
1247 break;
1248 case 'c':
1249 MCC = atoi(optarg);
1250 break;
1251 case 'L':
1252 LAC = atoi(optarg);
1253 break;
1254 case 'f':
1255 ARFCN = atoi(optarg);
1256 break;
1257 case 'l':
1258 database_name = strdup(optarg);
1259 break;
1260 case 'a':
1261 gsm0408_allow_everyone(1);
1262 break;
1263 case 'r':
1264 gsm0408_set_reject_cause(atoi(optarg));
1265 break;
1266 case 'p':
1267 create_pcap_file(optarg);
1268 break;
1269 case 't':
1270 BTS_TYPE = parse_btstype(optarg);
1271 break;
1272 case 'C':
1273 cardnr = atoi(optarg);
1274 break;
1275 case 'R':
1276 release_l2 = 1;
1277 break;
1278 case 'T':
1279 debug_timestamp(1);
1280 break;
Harald Welte91afe4c2009-06-20 18:15:19 +02001281 case 'b':
1282 BAND = gsm_band_parse(atoi(optarg));
1283 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001284 case 'i': {
1285 struct nano_bts_id *bts_id = talloc_zero(tall_bsc_ctx, struct nano_bts_id);
1286 if (!bts_id) {
1287 fprintf(stderr, "Failed to allocate bts id\n");
1288 exit(-1);
1289 }
1290
1291 bts_id->site_id = atoi(optarg);
1292 llist_add(&bts_id->entry, &nanobts_ids);
1293 break;
Harald Welte52281c12009-07-21 22:12:23 +02001294 case 'S':
1295 TSC = atoi(optarg);
1296 break;
1297 case 'B':
1298 BSIC = atoi(optarg);
1299 break;
Harald Welte3c062072009-07-28 18:25:29 +02001300 case 'P':
1301 ipacc_rtp_direct = 0;
1302 break;
Harald Welte25b70c52009-07-29 16:42:16 +02001303 case '1':
1304 bs11_has_trx1 = 1;
1305 break;
Harald Welteca9af2b2009-08-06 17:54:21 +02001306 case '2':
1307 bs11_has_bts1 = 1;
1308 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001309 }
Harald Welte59b04682009-06-10 05:40:52 +08001310 default:
1311 /* ignore */
1312 break;
1313 }
1314 }
1315}
1316
1317static void signal_handler(int signal)
1318{
1319 fprintf(stdout, "signal %u received\n", signal);
1320
1321 switch (signal) {
Harald Welte3b714502009-08-06 17:43:50 +02001322 case SIGINT:
Harald Welte59b04682009-06-10 05:40:52 +08001323 shutdown_net(gsmnet);
Harald Welte3b714502009-08-06 17:43:50 +02001324 sleep(3);
1325 exit(0);
Harald Welte59b04682009-06-10 05:40:52 +08001326 break;
Harald Welte4d5e6d52009-08-07 00:29:44 +02001327 case SIGABRT:
1328 /* in case of abort, we want to obtain a talloc report
1329 * and then return to the caller, who will abort the process */
Harald Weltea8379772009-06-20 22:36:41 +02001330 case SIGUSR1:
1331 talloc_report_full(tall_bsc_ctx, stderr);
1332 break;
Harald Welte59b04682009-06-10 05:40:52 +08001333 default:
1334 break;
1335 }
1336}
1337
1338int main(int argc, char **argv)
1339{
1340 int rc;
1341
Harald Weltea8379772009-06-20 22:36:41 +02001342 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1343
Harald Welte59b04682009-06-10 05:40:52 +08001344 /* parse options */
1345 handle_options(argc, argv);
1346
1347 /* seed the PRNG */
1348 srand(time(NULL));
1349
1350 rc = bootstrap_network();
1351 if (rc < 0)
1352 exit(1);
1353
Harald Welte3b714502009-08-06 17:43:50 +02001354 signal(SIGINT, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001355 signal(SIGABRT, &signal_handler);
Harald Weltea8379772009-06-20 22:36:41 +02001356 signal(SIGUSR1, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001357
1358 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001359 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001360 bsc_select_main(0);
1361 }
1362}