blob: 0f0f4c8c7c1f771f5685cbf72190a2644c5b6ce2 [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>
Harald Weltec4dcda02009-08-09 14:45:18 +020040#include <openbsc/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080041#include <openbsc/gsm_04_08.h>
42#include <openbsc/select.h>
43#include <openbsc/abis_rsl.h>
44#include <openbsc/abis_nm.h>
45#include <openbsc/debug.h>
46#include <openbsc/misdn.h>
47#include <openbsc/telnet_interface.h>
48#include <openbsc/paging.h>
49#include <openbsc/e1_input.h>
50#include <openbsc/signal.h>
Harald Weltea8379772009-06-20 22:36:41 +020051#include <openbsc/talloc.h>
52
Harald Welte59b04682009-06-10 05:40:52 +080053/* global pointer to the gsm network data structure */
54static struct gsm_network *gsmnet;
55
56/* MCC and MNC for the Location Area Identifier */
57static int MCC = 1;
58static int MNC = 1;
59static int LAC = 1;
Harald Welte52281c12009-07-21 22:12:23 +020060static int TSC = HARDCODED_TSC;
61static int BSIC = HARDCODED_BSIC;
Harald Welte59b04682009-06-10 05:40:52 +080062static int ARFCN = HARDCODED_ARFCN;
63static int cardnr = 0;
64static int release_l2 = 0;
Harald Welte25b70c52009-07-29 16:42:16 +020065static int bs11_has_trx1 = 0;
Harald Welteca9af2b2009-08-06 17:54:21 +020066static int bs11_has_bts1 = 0;
Harald Welte59b04682009-06-10 05:40:52 +080067static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
Harald Welte91afe4c2009-06-20 18:15:19 +020068static enum gsm_band BAND = GSM_BAND_900;
Harald Welte59b04682009-06-10 05:40:52 +080069static const char *database_name = "hlr.sqlite3";
Harald Welte3c062072009-07-28 18:25:29 +020070extern int ipacc_rtp_direct;
Harald Welte59b04682009-06-10 05:40:52 +080071
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +020072struct nano_bts_id {
73 struct llist_head entry;
74 int site_id;
75 int bts_id;
76};
77
78static LLIST_HEAD(nanobts_ids);
79
80
Harald Welte59b04682009-06-10 05:40:52 +080081/* The following definitions are for OM and NM packets that we cannot yet
82 * generate by code but we just pass on */
83
84// BTS Site Manager, SET ATTRIBUTES
85
86/*
87 Object Class: BTS Site Manager
88 Instance 1: FF
89 Instance 2: FF
90 Instance 3: FF
91SET ATTRIBUTES
92 sAbisExternalTime: 2007/09/08 14:36:11
93 omLAPDRelTimer: 30sec
94 shortLAPDIntTimer: 5sec
95 emergencyTimer1: 10 minutes
96 emergencyTimer2: 0 minutes
97*/
98
99unsigned char msg_1[] =
100{
Harald Weltef739ae62009-06-20 10:42:17 +0200101 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800102 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
103 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
104 0x02,
105 0x00, 0x1E,
106 NM_ATT_BS11_SH_LAPD_INT_TIMER,
107 0x01, 0x05,
108 0x42, 0x02, 0x00, 0x0A,
109 0x44, 0x02, 0x00, 0x00
110};
111
112// BTS, SET BTS ATTRIBUTES
113
114/*
115 Object Class: BTS
116 BTS relat. Number: 0
117 Instance 2: FF
118 Instance 3: FF
119SET BTS ATTRIBUTES
120 bsIdentityCode / BSIC:
121 PLMN_colour_code: 7h
122 BS_colour_code: 7h
123 BTS Air Timer T3105: 4 ,unit 10 ms
124 btsIsHopping: FALSE
125 periodCCCHLoadIndication: 1sec
126 thresholdCCCHLoadIndication: 0%
127 cellAllocationNumber: 00h = GSM 900
128 enableInterferenceClass: 00h = Disabled
129 fACCHQual: 6 (FACCH stealing flags minus 1)
130 intaveParameter: 31 SACCH multiframes
131 interferenceLevelBoundaries:
132 Interference Boundary 1: 0Ah
133 Interference Boundary 2: 0Fh
134 Interference Boundary 3: 14h
135 Interference Boundary 4: 19h
136 Interference Boundary 5: 1Eh
137 mSTxPwrMax: 11
138 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
139 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
140 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
141 30=33dBm, 31=32dBm
142 ny1:
143 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
144 powerOutputThresholds:
145 Out Power Fault Threshold: -10 dB
146 Red Out Power Threshold: - 6 dB
147 Excessive Out Power Threshold: 5 dB
148 rACHBusyThreshold: -127 dBm
149 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
150 rfResourceIndicationPeriod: 125 SACCH multiframes
151 T200:
152 SDCCH: 044 in 5 ms
153 FACCH/Full rate: 031 in 5 ms
154 FACCH/Half rate: 041 in 5 ms
155 SACCH with TCH SAPI0: 090 in 10 ms
156 SACCH with SDCCH: 090 in 10 ms
157 SDCCH with SAPI3: 090 in 5 ms
158 SACCH with TCH SAPI3: 135 in 10 ms
159 tSync: 9000 units of 10 msec
160 tTrau: 9000 units of 10 msec
161 enableUmLoopTest: 00h = disabled
162 enableExcessiveDistance: 00h = Disabled
163 excessiveDistance: 64km
164 hoppingMode: 00h = baseband hopping
165 cellType: 00h = Standard Cell
166 BCCH ARFCN / bCCHFrequency: 1
167*/
168
Harald Weltef739ae62009-06-20 10:42:17 +0200169static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800170{
Harald Welte59b04682009-06-10 05:40:52 +0800171 NM_ATT_BSIC, HARDCODED_BSIC,
172 NM_ATT_BTS_AIR_TIMER, 0x04,
173 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
174 NM_ATT_CCCH_L_I_P, 0x01,
175 NM_ATT_CCCH_L_T, 0x00,
176 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
177 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
178 NM_ATT_BS11_FACCH_QUAL, 0x06,
179 /* interference avg. period in numbers of SACCH multifr */
180 NM_ATT_INTAVE_PARAM, 0x1F,
181 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
182 NM_ATT_CCCH_L_T, 0x23,
183 NM_ATT_GSM_TIME, 0x28, 0x00,
184 NM_ATT_ADM_STATE, 0x03,
185 NM_ATT_RACH_B_THRESH, 0x7F,
186 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
187 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
188 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
189 NM_ATT_BS11_TSYNC, 0x23, 0x28,
190 NM_ATT_BS11_TTRAU, 0x23, 0x28,
191 NM_ATT_TEST_DUR, 0x01, 0x00,
192 NM_ATT_OUTST_ALARM, 0x01, 0x00,
193 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
194 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
195 NM_ATT_BS11_PLL, 0x01, 0x00,
196 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
197};
198
199// Handover Recognition, SET ATTRIBUTES
200
201/*
202Illegal Contents GSM Formatted O&M Msg
203 Object Class: Handover Recognition
204 BTS relat. Number: 0
205 Instance 2: FF
206 Instance 3: FF
207SET ATTRIBUTES
208 enableDelayPowerBudgetHO: 00h = Disabled
209 enableDistanceHO: 00h = Disabled
210 enableInternalInterCellHandover: 00h = Disabled
211 enableInternalIntraCellHandover: 00h = Disabled
212 enablePowerBudgetHO: 00h = Disabled
213 enableRXLEVHO: 00h = Disabled
214 enableRXQUALHO: 00h = Disabled
215 hoAveragingDistance: 8 SACCH multiframes
216 hoAveragingLev:
217 A_LEV_HO: 8 SACCH multiframes
218 W_LEV_HO: 1 SACCH multiframes
219 hoAveragingPowerBudget: 16 SACCH multiframes
220 hoAveragingQual:
221 A_QUAL_HO: 8 SACCH multiframes
222 W_QUAL_HO: 2 SACCH multiframes
223 hoLowerThresholdLevDL: (10 - 110) dBm
224 hoLowerThresholdLevUL: (5 - 110) dBm
225 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
226 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
227 hoThresholdLevDLintra : (20 - 110) dBm
228 hoThresholdLevULintra: (20 - 110) dBm
229 hoThresholdMsRangeMax: 20 km
230 nCell: 06h
231 timerHORequest: 3 ,unit 2 SACCH multiframes
232*/
233
234unsigned char msg_3[] =
235{
Harald Weltef739ae62009-06-20 10:42:17 +0200236 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Weltec7d75062009-07-18 16:18:11 +0200237 0xD0, 0x00, /* enableDelayPowerBudgetHO */
238 0x64, 0x00, /* enableDistanceHO */
239 0x67, 0x00, /* enableInternalInterCellHandover */
240 0x68, 0x00, /* enableInternalInterCellHandover */
241 0x6A, 0x00, /* enablePowerBudgetHO */
242 0x6C, 0x00, /* enableRXLEVHO */
243 0x6D, 0x00, /* enableRXQUALHO */
244 0x6F, 0x08, /* hoAveragingDistance */
245 0x70, 0x08, 0x01, /* hoAveragingLev */
Harald Welte59b04682009-06-10 05:40:52 +0800246 0x71, 0x10, 0x10, 0x10,
Harald Weltec7d75062009-07-18 16:18:11 +0200247 0x72, 0x08, 0x02, /* hoAveragingQual */
248 0x73, 0x0A, /* hoLowerThresholdLevDL */
249 0x74, 0x05, /* hoLowerThresholdLevUL */
250 0x75, 0x06, /* hoLowerThresholdQualDL */
251 0x76, 0x06, /* hoLowerThresholdQualUL */
252 0x78, 0x14, /* hoThresholdLevDLintra */
253 0x79, 0x14, /* hoThresholdLevULintra */
254 0x7A, 0x14, /* hoThresholdMsRangeMax */
255 0x7D, 0x06, /* nCell */
256 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
257 0x20, 0x01, 0x00,
Harald Welte59b04682009-06-10 05:40:52 +0800258 0x45, 0x01, 0x00,
259 0x48, 0x01, 0x00,
260 0x5A, 0x01, 0x00,
261 0x5B, 0x01, 0x05,
262 0x5E, 0x01, 0x1A,
263 0x5F, 0x01, 0x20,
264 0x9D, 0x01, 0x00,
265 0x47, 0x01, 0x00,
266 0x5C, 0x01, 0x64,
267 0x5D, 0x01, 0x1E,
268 0x97, 0x01, 0x20,
269 0xF7, 0x01, 0x3C,
270};
271
272// Power Control, SET ATTRIBUTES
273
274/*
275 Object Class: Power Control
276 BTS relat. Number: 0
277 Instance 2: FF
278 Instance 3: FF
279SET ATTRIBUTES
280 enableMsPowerControl: 00h = Disabled
281 enablePowerControlRLFW: 00h = Disabled
282 pcAveragingLev:
283 A_LEV_PC: 4 SACCH multiframes
284 W_LEV_PC: 1 SACCH multiframes
285 pcAveragingQual:
286 A_QUAL_PC: 4 SACCH multiframes
287 W_QUAL_PC: 2 SACCH multiframes
288 pcLowerThresholdLevDL: 0Fh
289 pcLowerThresholdLevUL: 0Ah
290 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
291 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
292 pcRLFThreshold: 0Ch
293 pcUpperThresholdLevDL: 14h
294 pcUpperThresholdLevUL: 0Fh
295 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
296 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
297 powerConfirm: 2 ,unit 2 SACCH multiframes
298 powerControlInterval: 2 ,unit 2 SACCH multiframes
299 powerIncrStepSize: 02h = 4 dB
300 powerRedStepSize: 01h = 2 dB
301 radioLinkTimeoutBs: 64 SACCH multiframes
302 enableBSPowerControl: 00h = disabled
303*/
304
305unsigned char msg_4[] =
306{
Harald Weltef739ae62009-06-20 10:42:17 +0200307 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800308 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
309 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Weltec7d75062009-07-18 16:18:11 +0200310 0x7E, 0x04, 0x01, /* pcAveragingLev */
311 0x7F, 0x04, 0x02, /* pcAveragingQual */
312 0x80, 0x0F, /* pcLowerThresholdLevDL */
313 0x81, 0x0A, /* pcLowerThresholdLevUL */
314 0x82, 0x05, /* pcLowerThresholdQualDL */
315 0x83, 0x05, /* pcLowerThresholdQualUL */
316 0x84, 0x0C, /* pcRLFThreshold */
317 0x85, 0x14, /* pcUpperThresholdLevDL */
318 0x86, 0x0F, /* pcUpperThresholdLevUL */
319 0x87, 0x04, /* pcUpperThresholdQualDL */
320 0x88, 0x04, /* pcUpperThresholdQualUL */
321 0x89, 0x02, /* powerConfirm */
322 0x8A, 0x02, /* powerConfirmInterval */
323 0x8B, 0x02, /* powerIncrStepSize */
324 0x8C, 0x01, /* powerRedStepSize */
325 0x8D, 0x40, /* radioLinkTimeoutBs */
Harald Welte59b04682009-06-10 05:40:52 +0800326 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
327};
328
329
330// Transceiver, SET TRX ATTRIBUTES (TRX 0)
331
332/*
333 Object Class: Transceiver
334 BTS relat. Number: 0
335 Tranceiver number: 0
336 Instance 3: FF
337SET TRX ATTRIBUTES
338 aRFCNList (HEX): 0001
339 txPwrMaxReduction: 00h = 30dB
340 radioMeasGran: 254 SACCH multiframes
341 radioMeasRep: 01h = enabled
342 memberOfEmergencyConfig: 01h = TRUE
343 trxArea: 00h = TRX doesn't belong to a concentric cell
344*/
345
Harald Weltef739ae62009-06-20 10:42:17 +0200346static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800347{
Harald Welte59b04682009-06-10 05:40:52 +0800348 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
349 NM_ATT_RF_MAXPOWR_R, 0x00,
350 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
351 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
352 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
353 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
354};
355
356static unsigned char nanobts_attr_bts[] = {
357 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
358 /* interference avg. period in numbers of SACCH multifr */
359 NM_ATT_INTAVE_PARAM, 0x06,
360 /* conn fail based on SACCH error rate */
361 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
362 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
363 NM_ATT_MAX_TA, 0x3f,
364 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
365 NM_ATT_CCCH_L_T, 10, /* percent */
366 NM_ATT_CCCH_L_I_P, 1, /* seconds */
367 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
368 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
369 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
370 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
371 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
372 NM_ATT_BSIC, HARDCODED_BSIC,
373};
374
375static unsigned char nanobts_attr_radio[] = {
376 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
377 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
378};
379
380static unsigned char nanobts_attr_e0[] = {
Harald Welte4206d982009-07-12 09:33:54 +0200381 NM_ATT_IPACC_STREAM_ID, 0x00,
382 NM_ATT_IPACC_DST_IP_PORT, 0x0b, 0xbb, /* TCP PORT for RSL */
Harald Welte59b04682009-06-10 05:40:52 +0800383};
384
385/* Callback function to be called whenever we get a GSM 12.21 state change event */
386int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
387 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
388{
389 struct gsm_bts *bts;
390 struct gsm_bts_trx *trx;
391 struct gsm_bts_trx_ts *ts;
392
393 /* This is currently only required on nanoBTS */
394
395 switch (evt) {
396 case EVT_STATECHG_OPER:
397 switch (obj_class) {
398 case NM_OC_SITE_MANAGER:
399 bts = container_of(obj, struct gsm_bts, site_mgr);
400 if (old_state->operational != 2 && new_state->operational == 2) {
401 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
402 }
403 break;
404 case NM_OC_BTS:
405 bts = obj;
406 if (new_state->availability == 5) {
407 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
408 sizeof(nanobts_attr_bts));
409 abis_nm_opstart(bts, NM_OC_BTS,
410 bts->bts_nr, 0xff, 0xff);
411 abis_nm_chg_adm_state(bts, NM_OC_BTS,
412 bts->bts_nr, 0xff, 0xff,
413 NM_STATE_UNLOCKED);
414 }
415 break;
416 case NM_OC_CHANNEL:
417 ts = obj;
418 trx = ts->trx;
419 if (new_state->availability == 5) {
420 if (ts->nr == 0 && trx == trx->bts->c0)
421 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
422 else
423 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
424 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
425 trx->bts->bts_nr, trx->nr, ts->nr);
426 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
427 trx->bts->bts_nr, trx->nr, ts->nr,
428 NM_STATE_UNLOCKED);
429 }
430 break;
431 default:
432 break;
433 }
434 break;
435 default:
436 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
437 break;
438 }
439 return 0;
440}
441
442/* Callback function to be called every time we receive a 12.21 SW activated report */
443static int sw_activ_rep(struct msgb *mb)
444{
445 struct abis_om_fom_hdr *foh = msgb_l3(mb);
446 struct gsm_bts_trx *trx = mb->trx;
447
448 switch (foh->obj_class) {
449 case NM_OC_BASEB_TRANSC:
450 /* TRX software is active, tell it to initiate RSL Link */
451 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
452 trx->bts->bts_nr, trx->nr, 0xff,
453 nanobts_attr_e0, sizeof(nanobts_attr_e0));
454 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
455 trx->bts->bts_nr, trx->nr, 0xff);
456 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
457 trx->bts->bts_nr, trx->nr, 0xff,
458 NM_STATE_UNLOCKED);
459 break;
460 case NM_OC_RADIO_CARRIER:
461 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
462 sizeof(nanobts_attr_radio));
463 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
464 trx->bts->bts_nr, trx->nr, 0xff);
465 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
466 trx->bts->bts_nr, trx->nr, 0xff,
467 NM_STATE_UNLOCKED);
468 break;
469 }
470 return 0;
471}
472
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200473/* Callback function for NACK on the OML NM */
474static int oml_msg_nack(int mt)
475{
476 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
477 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
478 "Was the bts type and frequency properly specified?\n");
479 exit(-1);
480 }
481
482 return 0;
483}
484
Harald Welte59b04682009-06-10 05:40:52 +0800485/* Callback function to be called every time we receive a signal from NM */
486static int nm_sig_cb(unsigned int subsys, unsigned int signal,
487 void *handler_data, void *signal_data)
488{
489 switch (signal) {
490 case S_NM_SW_ACTIV_REP:
491 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200492 case S_NM_NACK:
493 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800494 default:
495 break;
496 }
497 return 0;
498}
499
500static void bootstrap_om_nanobts(struct gsm_bts *bts)
501{
502 /* We don't do callback based bootstrapping, but event driven (see above) */
503}
504
505static void bootstrap_om_bs11(struct gsm_bts *bts)
506{
Harald Weltee712a5f2009-06-21 16:17:15 +0200507 struct gsm_bts_trx *trx = bts->c0;
Harald Weltecf833cd2009-08-06 17:40:24 +0200508 int base_ts;
509
510 switch (bts->nr) {
511 case 0:
512 /* First BTS uses E1 TS 01,02,03,04,05 */
513 base_ts = HARDCODED_BTS0_TS - 1;
514 break;
515 case 1:
516 /* Second BTS uses E1 TS 06,07,08,09,10 */
517 base_ts = HARDCODED_BTS1_TS - 1;
518 break;
519 case 2:
520 /* Third BTS uses E1 TS 11,12,13,14,15 */
521 base_ts = HARDCODED_BTS2_TS - 1;
522 default:
523 return;
524 }
Harald Welte59b04682009-06-10 05:40:52 +0800525
526 /* stop sending event reports */
527 abis_nm_event_reports(bts, 0);
528
529 /* begin DB transmission */
530 abis_nm_bs11_db_transmission(bts, 1);
531
532 /* end DB transmission */
533 abis_nm_bs11_db_transmission(bts, 0);
534
535 /* Reset BTS Site manager resource */
536 abis_nm_bs11_reset_resource(bts);
537
538 /* begin DB transmission */
539 abis_nm_bs11_db_transmission(bts, 1);
540
541 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltef739ae62009-06-20 10:42:17 +0200542 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800543 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
544 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
545
546 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200547 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Weltef739ae62009-06-20 10:42:17 +0200548 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800549
550 /* Use TEI 1 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200551 abis_nm_establish_tei(bts, 0, 0, base_ts+1, 0xff, 0x01);
Harald Welte59b04682009-06-10 05:40:52 +0800552 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
553
Harald Welte59b04682009-06-10 05:40:52 +0800554 /* SET CHANNEL ATTRIBUTE TS1 */
555 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
556 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200557 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+2, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800558
559 /* SET CHANNEL ATTRIBUTE TS2 */
560 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
561 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200562 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+2, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800563
564 /* SET CHANNEL ATTRIBUTE TS3 */
565 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
566 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200567 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+2, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800568
569 /* SET CHANNEL ATTRIBUTE TS4 */
570 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
571 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200572 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+3, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800573
574 /* SET CHANNEL ATTRIBUTE TS5 */
575 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
576 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200577 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+3, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800578
579 /* SET CHANNEL ATTRIBUTE TS6 */
580 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
581 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200582 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+3, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800583
584 /* SET CHANNEL ATTRIBUTE TS7 */
585 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
586 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200587 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+3, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800588
Harald Welte25b70c52009-07-29 16:42:16 +0200589 trx = gsm_bts_trx_num(bts, 1);
590 if (trx) {
591 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
592 u_int8_t arfcn_low = trx->arfcn & 0xff;
593 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
594 memcpy(trx1_attr_radio, bs11_attr_radio,
595 sizeof(trx1_attr_radio));
596
597 /* patch ARFCN into TRX Attributes */
598 trx1_attr_radio[2] &= 0xf0;
599 trx1_attr_radio[2] |= arfcn_high;
600 trx1_attr_radio[3] = arfcn_low;
601
602 /* Connect signalling of TRX1 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200603 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Welte25b70c52009-07-29 16:42:16 +0200604 /* FIXME: TRX ATTRIBUTE */
605 abis_nm_set_radio_attr(trx, trx1_attr_radio,
606 sizeof(trx1_attr_radio));
607
608 /* Use TEI 2 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200609 abis_nm_establish_tei(bts, 1, 0, base_ts+1, 0xff, 0x02);
Harald Welte25b70c52009-07-29 16:42:16 +0200610
Harald Welte1a503162009-08-04 01:31:53 +0200611 /* SET CHANNEL ATTRIBUTE TS0 */
612 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_TCHFull);
613 /* Connect traffic of bts0/trx0/ts0 to e1_0/ts4/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200614 abis_nm_conn_terr_traf(&trx->ts[0], 0, base_ts+4, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200615
616 /* SET CHANNEL ATTRIBUTE TS1 */
617 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
618 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200619 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+4, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200620
621 /* SET CHANNEL ATTRIBUTE TS2 */
622 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
623 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200624 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+4, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200625
626 /* SET CHANNEL ATTRIBUTE TS3 */
627 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
628 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200629 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+4, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200630
631 /* SET CHANNEL ATTRIBUTE TS4 */
632 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
633 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200634 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+5, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200635
636 /* SET CHANNEL ATTRIBUTE TS5 */
637 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
638 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200639 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+5, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200640
641 /* SET CHANNEL ATTRIBUTE TS6 */
642 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
643 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200644 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+5, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200645
646 /* SET CHANNEL ATTRIBUTE TS7 */
647 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
648 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200649 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+5, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200650 }
651
Harald Welte59b04682009-06-10 05:40:52 +0800652 /* end DB transmission */
653 abis_nm_bs11_db_transmission(bts, 0);
654
655 /* Reset BTS Site manager resource */
656 abis_nm_bs11_reset_resource(bts);
657
658 /* restart sending event reports */
659 abis_nm_event_reports(bts, 1);
660}
661
662static void bootstrap_om(struct gsm_bts *bts)
663{
664 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
665
666 switch (bts->type) {
667 case GSM_BTS_TYPE_BS11:
668 bootstrap_om_bs11(bts);
669 break;
670 case GSM_BTS_TYPE_NANOBTS_900:
671 case GSM_BTS_TYPE_NANOBTS_1800:
672 bootstrap_om_nanobts(bts);
673 break;
674 default:
675 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
676 }
677}
678
679static int shutdown_om(struct gsm_bts *bts)
680{
Harald Welte3b714502009-08-06 17:43:50 +0200681 fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
682
Harald Welte59b04682009-06-10 05:40:52 +0800683 /* stop sending event reports */
684 abis_nm_event_reports(bts, 0);
685
686 /* begin DB transmission */
687 abis_nm_bs11_db_transmission(bts, 1);
688
689 /* end DB transmission */
690 abis_nm_bs11_db_transmission(bts, 0);
691
692 /* Reset BTS Site manager resource */
693 abis_nm_bs11_reset_resource(bts);
694
695 return 0;
696}
697
698static int shutdown_net(struct gsm_network *net)
699{
Harald Weltee712a5f2009-06-21 16:17:15 +0200700 struct gsm_bts *bts;
701
702 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welte59b04682009-06-10 05:40:52 +0800703 int rc;
Harald Weltee712a5f2009-06-21 16:17:15 +0200704 rc = shutdown_om(bts);
Harald Welte59b04682009-06-10 05:40:52 +0800705 if (rc < 0)
706 return rc;
707 }
708
709 return 0;
710}
711
712struct bcch_info {
713 u_int8_t type;
714 u_int8_t len;
715 const u_int8_t *data;
716};
717
718/*
719SYSTEM INFORMATION TYPE 1
720 Cell channel description
721 Format-ID bit map 0
722 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
723 RACH Control Parameters
724 maximum 7 retransmissions
725 8 slots used to spread transmission
726 cell not barred for access
727 call reestablishment not allowed
728 Access Control Class = 0000
729*/
730static u_int8_t si1[] = {
731 /* header */0x55, 0x06, 0x19,
732 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
734 /* rach */0xD5, 0x00, 0x00,
735 /* s1 reset*/0x2B
736};
737
738/*
739 SYSTEM INFORMATION TYPE 2
740 Neighbour Cells Description
741 EXT-IND: Carries the complete BA
742 BA-IND = 0
743 Format-ID bit map 0
744 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
745 NCC permitted (NCC) = FF
746 RACH Control Parameters
747 maximum 7 retransmissions
748 8 slots used to spread transmission
749 cell not barred for access
750 call reestablishment not allowed
751 Access Control Class = 0000
752*/
753static u_int8_t si2[] = {
754 /* header */0x59, 0x06, 0x1A,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757 /* ncc */0xFF,
758 /* rach*/0xD5, 0x00, 0x00
759};
760
761/*
762SYSTEM INFORMATION TYPE 3
763 Cell identity = 00001 (1h)
764 Location area identification
765 Mobile Country Code (MCC): 001
766 Mobile Network Code (MNC): 01
767 Location Area Code (LAC): 00001 (1h)
768 Control Channel Description
769 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
770 0 blocks reserved for access grant
771 1 channel used for CCCH, with SDCCH
772 5 multiframes period for PAGING REQUEST
773 Time-out T3212 = 0
774 Cell Options BCCH
775 Power control indicator: not set
776 MSs shall not use uplink DTX
777 Radio link timeout = 36
778 Cell Selection Parameters
779 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
780 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
781 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
782 Half rate support (NECI): New establishment causes are not supported
783 min.RX signal level for MS = 0
784 RACH Control Parameters
785 maximum 7 retransmissions
786 8 slots used to spread transmission
787 cell not barred for access
788 call reestablishment not allowed
789 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200790 SI 3 Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800791*/
792static u_int8_t si3[] = {
793 /* header */0x49, 0x06, 0x1B,
794 /* cell */0x00, 0x01,
795 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
796 /* desc */0x01, 0x03, 0x00,
797 /* option*/0x28,
798 /* selection*/0x62, 0x00,
799 /* rach */0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200800 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800801};
802
803/*
804SYSTEM INFORMATION TYPE 4
805 Location area identification
806 Mobile Country Code (MCC): 001
807 Mobile Network Code (MNC): 01
808 Location Area Code (LAC): 00001 (1h)
809 Cell Selection Parameters
810 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
811 max.TX power level MS may use for CCH = 2
812 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
813 Half rate support (NECI): New establishment causes are not supported
814 min.RX signal level for MS = 0
815 RACH Control Parameters
816 maximum 7 retransmissions
817 8 slots used to spread transmission
818 cell not barred for access
819 call reestablishment not allowed
820 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200821 CBCH Channel Description
Harald Welte59b04682009-06-10 05:40:52 +0800822 Type = SDCCH/4[2]
823 Timeslot Number: 0
824 Training Sequence Code: 7h
825 ARFCN: 1
Harald Weltec1c4a952009-07-05 13:41:40 +0200826 SI Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800827*/
828static u_int8_t si4[] = {
829 /* header */0x41, 0x06, 0x1C,
830 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
831 /* sel */0x62, 0x00,
832 /* rach*/0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200833 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
834 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800835};
836
837/*
838 SYSTEM INFORMATION TYPE 5
839 Neighbour Cells Description
840 EXT-IND: Carries the complete BA
841 BA-IND = 0
842 Format-ID bit map 0
843 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
844*/
845
846static u_int8_t si5[] = {
847 /* header without l2 len*/0x06, 0x1D,
848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850};
851
852// SYSTEM INFORMATION TYPE 6
853
854/*
855SACCH FILLING
856 System Info Type: SYSTEM INFORMATION 6
857 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
858
859SYSTEM INFORMATION TYPE 6
860 Cell identity = 00001 (1h)
861 Location area identification
862 Mobile Country Code (MCC): 001
863 Mobile Network Code (MNC): 01
864 Location Area Code (LAC): 00001 (1h)
865 Cell Options SACCH
866 Power control indicator: not set
867 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
868 Radio link timeout = 36
869 NCC permitted (NCC) = FF
870*/
871
872static u_int8_t si6[] = {
873 /* header */0x06, 0x1E,
874 /* cell id*/ 0x00, 0x01,
875 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
876 /* options */ 0x28,
877 /* ncc */ 0xFF,
878};
879
880
881
882static const struct bcch_info bcch_infos[] = {
883 {
884 .type = RSL_SYSTEM_INFO_1,
885 .len = sizeof(si1),
886 .data = si1,
887 }, {
888 .type = RSL_SYSTEM_INFO_2,
889 .len = sizeof(si2),
890 .data = si2,
891 }, {
892 .type = RSL_SYSTEM_INFO_3,
893 .len = sizeof(si3),
894 .data = si3,
895 }, {
896 .type = RSL_SYSTEM_INFO_4,
897 .len = sizeof(si4),
898 .data = si4,
899 },
900};
901
902static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
903static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
904static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
905static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
906static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
907static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
908
909/* set all system information types */
910static int set_system_infos(struct gsm_bts_trx *trx)
911{
912 int i;
913
Harald Welte6ab22d22009-08-06 17:41:19 +0200914 if (trx == trx->bts->c0) {
915 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
916 rsl_bcch_info(trx, bcch_infos[i].type,
917 bcch_infos[i].data,
918 bcch_infos[i].len);
919 }
Harald Welte59b04682009-06-10 05:40:52 +0800920 }
921 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
922 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
923
924 return 0;
925}
926
927/*
928 * Patch the various SYSTEM INFORMATION tables to update
929 * the LAI
930 */
931static void patch_tables(struct gsm_bts *bts)
932{
Harald Weltee712a5f2009-06-21 16:17:15 +0200933 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
934 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Harald Welte59b04682009-06-10 05:40:52 +0800935 /* covert the raw packet to the struct */
936 struct gsm48_system_information_type_3 *type_3 =
937 (struct gsm48_system_information_type_3*)&si3;
938 struct gsm48_system_information_type_4 *type_4 =
939 (struct gsm48_system_information_type_4*)&si4;
940 struct gsm48_system_information_type_6 *type_6 =
941 (struct gsm48_system_information_type_6*)&si6;
942 struct gsm48_loc_area_id lai;
943
944 gsm0408_generate_lai(&lai, bts->network->country_code,
945 bts->network->network_code,
946 bts->location_area_code);
947
948 /* assign the MCC and MNC */
949 type_3->lai = lai;
950 type_4->lai = lai;
951 type_6->lai = lai;
952
953 /* patch ARFCN into BTS Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200954 bs11_attr_bts[69] &= 0xf0;
955 bs11_attr_bts[69] |= arfcn_high;
956 bs11_attr_bts[70] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800957 nanobts_attr_bts[42] &= 0xf0;
958 nanobts_attr_bts[42] |= arfcn_high;
959 nanobts_attr_bts[43] = arfcn_low;
960
961 /* patch ARFCN into TRX Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200962 bs11_attr_radio[2] &= 0xf0;
963 bs11_attr_radio[2] |= arfcn_high;
964 bs11_attr_radio[3] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800965 nanobts_attr_radio[5] &= 0xf0;
966 nanobts_attr_radio[5] |= arfcn_high;
967 nanobts_attr_radio[6] = arfcn_low;
968
969 type_4->data[2] &= 0xf0;
970 type_4->data[2] |= arfcn_high;
971 type_4->data[3] = arfcn_low;
972
973 /* patch Control Channel Description 10.5.2.11 */
974 type_3->control_channel_desc = bts->chan_desc;
975
976 /* patch BSIC */
Harald Weltef739ae62009-06-20 10:42:17 +0200977 bs11_attr_bts[1] = bts->bsic;
Harald Welte59b04682009-06-10 05:40:52 +0800978 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
Harald Welte52281c12009-07-21 22:12:23 +0200979
980 /* patch TSC */
981 si4[15] &= ~0xe0;
982 si4[15] |= (bts->tsc & 7) << 5;
Harald Weltede009e62009-08-09 14:38:49 +0200983
984 /* patch MS max power for CCH */
985 type_4->cell_sel_par.ms_txpwr_max_ccch =
Harald Weltec4dcda02009-08-09 14:45:18 +0200986 ms_pwr_ctl_lvl(bts->band, 20 /* dBm == 100mW */);
Harald Welte59b04682009-06-10 05:40:52 +0800987}
988
989
990static void bootstrap_rsl(struct gsm_bts_trx *trx)
991{
992 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte52281c12009-07-21 22:12:23 +0200993 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
Harald Welte1a503162009-08-04 01:31:53 +0200994 trx->bts->nr, trx->nr, MCC, MNC, BSIC, TSC);
Harald Welte59b04682009-06-10 05:40:52 +0800995 set_system_infos(trx);
996}
997
998void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
999{
1000 switch (event) {
1001 case EVT_E1_TEI_UP:
1002 switch (type) {
1003 case E1INP_SIGN_OML:
1004 bootstrap_om(trx->bts);
1005 break;
1006 case E1INP_SIGN_RSL:
1007 bootstrap_rsl(trx);
1008 break;
1009 default:
1010 break;
1011 }
1012 break;
1013 case EVT_E1_TEI_DN:
1014 fprintf(stderr, "Lost some E1 TEI link\n");
1015 /* FIXME: deal with TEI or L1 link loss */
1016 break;
1017 default:
1018 break;
1019 }
1020}
1021
1022static int bootstrap_bts(struct gsm_bts *bts)
1023{
Harald Welte91afe4c2009-06-20 18:15:19 +02001024 bts->band = BAND;
Harald Welte59b04682009-06-10 05:40:52 +08001025 bts->location_area_code = LAC;
Harald Weltee712a5f2009-06-21 16:17:15 +02001026 bts->c0->arfcn = ARFCN;
Harald Welte59b04682009-06-10 05:40:52 +08001027
1028 /* Control Channel Description */
1029 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
1030 bts->chan_desc.att = 1;
1031 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1032 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1033 bts->chan_desc.t3212 = 0;
1034
1035 patch_tables(bts);
1036
1037 paging_init(bts);
1038
1039 if (bts->type == GSM_BTS_TYPE_BS11) {
Harald Weltee712a5f2009-06-21 16:17:15 +02001040 struct gsm_bts_trx *trx = bts->c0;
Harald Welte59b04682009-06-10 05:40:52 +08001041 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
1042 set_ts_e1link(&trx->ts[1], 0, 2, 1);
1043 set_ts_e1link(&trx->ts[2], 0, 2, 2);
1044 set_ts_e1link(&trx->ts[3], 0, 2, 3);
1045 set_ts_e1link(&trx->ts[4], 0, 3, 0);
1046 set_ts_e1link(&trx->ts[5], 0, 3, 1);
1047 set_ts_e1link(&trx->ts[6], 0, 3, 2);
1048 set_ts_e1link(&trx->ts[7], 0, 3, 3);
Harald Welte25b70c52009-07-29 16:42:16 +02001049
Harald Welte59b04682009-06-10 05:40:52 +08001050 /* TRX 1 */
Harald Welte25b70c52009-07-29 16:42:16 +02001051 trx = gsm_bts_trx_num(bts, 1);
1052 if (trx) {
1053 trx = gsm_bts_trx_num(bts, 1);
1054 set_ts_e1link(&trx->ts[0], 0, 4, 0);
1055 set_ts_e1link(&trx->ts[1], 0, 4, 1);
1056 set_ts_e1link(&trx->ts[2], 0, 4, 2);
1057 set_ts_e1link(&trx->ts[3], 0, 4, 3);
1058 set_ts_e1link(&trx->ts[4], 0, 5, 0);
1059 set_ts_e1link(&trx->ts[5], 0, 5, 1);
1060 set_ts_e1link(&trx->ts[6], 0, 5, 2);
1061 set_ts_e1link(&trx->ts[7], 0, 5, 3);
1062 }
Harald Welte59b04682009-06-10 05:40:52 +08001063 }
1064
1065 return 0;
1066}
1067
1068static int bootstrap_network(void)
1069{
Harald Welteca9af2b2009-08-06 17:54:21 +02001070 int rc;
1071
Holger Hans Peter Freytheref5f4182009-06-10 10:20:16 +02001072 switch(BTS_TYPE) {
1073 case GSM_BTS_TYPE_NANOBTS_1800:
1074 if (ARFCN < 512 || ARFCN > 885) {
1075 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
1076 return -EINVAL;
1077 }
1078 break;
1079 case GSM_BTS_TYPE_BS11:
1080 case GSM_BTS_TYPE_NANOBTS_900:
1081 /* Assume we have a P-GSM900 here */
1082 if (ARFCN < 1 || ARFCN > 124) {
1083 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1084 return -EINVAL;
1085 }
1086 break;
1087 case GSM_BTS_TYPE_UNKNOWN:
1088 fprintf(stderr, "Unknown BTS. Please use the --bts-type switch\n");
1089 return -EINVAL;
1090 }
1091
Harald Welte59b04682009-06-10 05:40:52 +08001092 /* initialize our data structures */
Harald Weltee712a5f2009-06-21 16:17:15 +02001093 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +08001094 if (!gsmnet)
1095 return -ENOMEM;
1096
1097 gsmnet->name_long = "OpenBSC";
1098 gsmnet->name_short = "OpenBSC";
1099
Harald Welte59b04682009-06-10 05:40:52 +08001100 if (db_init(database_name)) {
1101 printf("DB: Failed to init database. Please check the option settings.\n");
1102 return -1;
1103 }
1104 printf("DB: Database initialized.\n");
1105
1106 if (db_prepare()) {
1107 printf("DB: Failed to prepare database.\n");
1108 return -1;
1109 }
1110 printf("DB: Database prepared.\n");
1111
1112 telnet_init(gsmnet, 4242);
1113
1114 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1115
1116 /* E1 mISDN input setup */
1117 if (BTS_TYPE == GSM_BTS_TYPE_BS11) {
Harald Welte52281c12009-07-21 22:12:23 +02001118 struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Harald Welte25b70c52009-07-29 16:42:16 +02001119
1120 if (bs11_has_trx1) {
1121 struct gsm_bts_trx *trx1;
1122 trx1 = gsm_bts_trx_alloc(bts);
1123 trx1->arfcn = ARFCN + 2;
1124 }
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001125 bootstrap_bts(bts);
Harald Welteca9af2b2009-08-06 17:54:21 +02001126 rc = e1_config(bts, cardnr, release_l2);
1127 if (rc < 0) {
1128 fprintf(stderr, "Error during E1 config of BTS 0\n");
1129 return rc;
1130 }
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001131
Harald Welteca9af2b2009-08-06 17:54:21 +02001132 if (bs11_has_bts1) {
1133 bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
1134 if (bs11_has_trx1) {
1135 struct gsm_bts_trx *trx1;
1136 trx1 = gsm_bts_trx_alloc(bts);
1137 trx1->arfcn = ARFCN + 2;
1138 }
1139 bootstrap_bts(bts);
1140 rc = e1_config(bts, cardnr+1, release_l2);
1141 if (rc < 0)
1142 fprintf(stderr, "Error during E1 config of BTS 1\n");
1143 }
1144 return rc;
Harald Welte59b04682009-06-10 05:40:52 +08001145 } else {
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001146 struct nano_bts_id *bts_id;
1147 struct gsm_bts *bts;
Harald Welte91afe4c2009-06-20 18:15:19 +02001148
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001149 if (llist_empty(&nanobts_ids)) {
1150 fprintf(stderr, "You need to specify -i DEVICE_1 -i DEVICE_2 for nanoBTS.\n");
1151 return -EINVAL;
1152 }
1153
1154 llist_for_each_entry(bts_id, &nanobts_ids, entry) {
Harald Welte52281c12009-07-21 22:12:23 +02001155 bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001156 bootstrap_bts(bts);
1157 bts->ip_access.site_id = bts_id->site_id;
1158 bts->ip_access.bts_id = 0;
1159 }
1160
Harald Welte59b04682009-06-10 05:40:52 +08001161 return ipaccess_setup(gsmnet);
1162 }
1163}
1164
1165static void create_pcap_file(char *file)
1166{
1167 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1168 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1169
1170 if (fd < 0) {
1171 perror("Failed to open file for pcap");
1172 return;
1173 }
1174
1175 e1_set_pcap_fd(fd);
1176}
1177
1178static void print_usage()
1179{
1180 printf("Usage: bsc_hack\n");
1181}
1182
1183static void print_help()
1184{
1185 printf(" Some useful help...\n");
1186 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1187 printf(" -s --disable-color\n");
1188 printf(" -n --network-code number(MNC) \n");
1189 printf(" -c --country-code number (MCC) \n");
1190 printf(" -L --location-area-code number (LAC) \n");
1191 printf(" -f --arfcn number The frequency ARFCN\n");
1192 printf(" -l --database db-name The database to use\n");
1193 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1194 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1195 printf(" -p --pcap file The filename of the pcap file\n");
1196 printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n");
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001197 printf(" -i --bts-id=NUMBER The known nanoBTS device numbers. Can be specified multiple times.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001198 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1199 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
Harald Welteca9af2b2009-08-06 17:54:21 +02001200 printf(" -2 --second-bs11 Configure + Use a second BS-11\n");
Harald Welte59b04682009-06-10 05:40:52 +08001201 printf(" -h --help this text\n");
1202}
1203
1204static void handle_options(int argc, char** argv)
1205{
1206 while (1) {
Harald Weltea8379772009-06-20 22:36:41 +02001207 int option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001208 static struct option long_options[] = {
1209 {"help", 0, 0, 'h'},
1210 {"debug", 1, 0, 'd'},
1211 {"disable-color", 0, 0, 's'},
1212 {"network-code", 1, 0, 'n'},
1213 {"country-code", 1, 0, 'c'},
1214 {"location-area-code", 1, 0, 'L'},
1215 {"database", 1, 0, 'l'},
1216 {"authorize-everyone", 0, 0, 'a'},
1217 {"reject-cause", 1, 0, 'r'},
1218 {"pcap", 1, 0, 'p'},
1219 {"arfcn", 1, 0, 'f'},
1220 {"bts-type", 1, 0, 't'},
1221 {"cardnr", 1, 0, 'C'},
1222 {"release-l2", 0, 0, 'R'},
1223 {"timestamp", 0, 0, 'T'},
Harald Welte91afe4c2009-06-20 18:15:19 +02001224 {"band", 0, 0, 'b'},
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001225 {"bts-id", 1, 0, 'i'},
Harald Welte52281c12009-07-21 22:12:23 +02001226 {"tsc", 1, 0, 'S'},
1227 {"bsic", 1, 0, 'B'},
Harald Welte3c062072009-07-28 18:25:29 +02001228 {"rtp-proxy", 0, 0, 'P'},
Harald Welte25b70c52009-07-29 16:42:16 +02001229 {"trx1", 0, 0, '1'},
Harald Welteca9af2b2009-08-06 17:54:21 +02001230 {"second-bs11", 0, 0, '2'},
Harald Welte59b04682009-06-10 05:40:52 +08001231 {0, 0, 0, 0}
1232 };
1233
Harald Welteca9af2b2009-08-06 17:54:21 +02001234 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 +08001235 long_options, &option_index);
1236 if (c == -1)
1237 break;
1238
1239 switch (c) {
1240 case 'h':
1241 print_usage();
1242 print_help();
1243 exit(0);
1244 case 's':
1245 debug_use_color(0);
1246 break;
1247 case 'd':
1248 debug_parse_category_mask(optarg);
1249 break;
1250 case 'n':
1251 MNC = atoi(optarg);
1252 break;
1253 case 'c':
1254 MCC = atoi(optarg);
1255 break;
1256 case 'L':
1257 LAC = atoi(optarg);
1258 break;
1259 case 'f':
1260 ARFCN = atoi(optarg);
1261 break;
1262 case 'l':
1263 database_name = strdup(optarg);
1264 break;
1265 case 'a':
1266 gsm0408_allow_everyone(1);
1267 break;
1268 case 'r':
1269 gsm0408_set_reject_cause(atoi(optarg));
1270 break;
1271 case 'p':
1272 create_pcap_file(optarg);
1273 break;
1274 case 't':
1275 BTS_TYPE = parse_btstype(optarg);
1276 break;
1277 case 'C':
1278 cardnr = atoi(optarg);
1279 break;
1280 case 'R':
1281 release_l2 = 1;
1282 break;
1283 case 'T':
1284 debug_timestamp(1);
1285 break;
Harald Welte91afe4c2009-06-20 18:15:19 +02001286 case 'b':
1287 BAND = gsm_band_parse(atoi(optarg));
1288 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001289 case 'i': {
1290 struct nano_bts_id *bts_id = talloc_zero(tall_bsc_ctx, struct nano_bts_id);
1291 if (!bts_id) {
1292 fprintf(stderr, "Failed to allocate bts id\n");
1293 exit(-1);
1294 }
1295
1296 bts_id->site_id = atoi(optarg);
1297 llist_add(&bts_id->entry, &nanobts_ids);
1298 break;
Harald Welte52281c12009-07-21 22:12:23 +02001299 case 'S':
1300 TSC = atoi(optarg);
1301 break;
1302 case 'B':
1303 BSIC = atoi(optarg);
1304 break;
Harald Welte3c062072009-07-28 18:25:29 +02001305 case 'P':
1306 ipacc_rtp_direct = 0;
1307 break;
Harald Welte25b70c52009-07-29 16:42:16 +02001308 case '1':
1309 bs11_has_trx1 = 1;
1310 break;
Harald Welteca9af2b2009-08-06 17:54:21 +02001311 case '2':
1312 bs11_has_bts1 = 1;
1313 break;
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001314 }
Harald Welte59b04682009-06-10 05:40:52 +08001315 default:
1316 /* ignore */
1317 break;
1318 }
1319 }
1320}
1321
1322static void signal_handler(int signal)
1323{
1324 fprintf(stdout, "signal %u received\n", signal);
1325
1326 switch (signal) {
Harald Welte3b714502009-08-06 17:43:50 +02001327 case SIGINT:
Harald Welte59b04682009-06-10 05:40:52 +08001328 shutdown_net(gsmnet);
Harald Welte3b714502009-08-06 17:43:50 +02001329 sleep(3);
1330 exit(0);
Harald Welte59b04682009-06-10 05:40:52 +08001331 break;
Harald Welte4d5e6d52009-08-07 00:29:44 +02001332 case SIGABRT:
1333 /* in case of abort, we want to obtain a talloc report
1334 * and then return to the caller, who will abort the process */
Harald Weltea8379772009-06-20 22:36:41 +02001335 case SIGUSR1:
1336 talloc_report_full(tall_bsc_ctx, stderr);
1337 break;
Harald Welte59b04682009-06-10 05:40:52 +08001338 default:
1339 break;
1340 }
1341}
1342
1343int main(int argc, char **argv)
1344{
1345 int rc;
1346
Harald Weltea8379772009-06-20 22:36:41 +02001347 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1348
Harald Welte59b04682009-06-10 05:40:52 +08001349 /* parse options */
1350 handle_options(argc, argv);
1351
1352 /* seed the PRNG */
1353 srand(time(NULL));
1354
1355 rc = bootstrap_network();
1356 if (rc < 0)
1357 exit(1);
1358
Harald Welte3b714502009-08-06 17:43:50 +02001359 signal(SIGINT, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001360 signal(SIGABRT, &signal_handler);
Harald Weltea8379772009-06-20 22:36:41 +02001361 signal(SIGUSR1, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001362
1363 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001364 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001365 bsc_select_main(0);
1366 }
1367}