blob: 7065833bfc1bfb9f4f3f28751a48b674144a8bf4 [file] [log] [blame]
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001/* 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 <openbsc/gsm_data.h>
24#include <openbsc/gsm_utils.h>
25#include <openbsc/gsm_04_08.h>
26#include <openbsc/abis_rsl.h>
27#include <openbsc/abis_nm.h>
28#include <openbsc/debug.h>
29#include <openbsc/misdn.h>
30#include <openbsc/telnet_interface.h>
Harald Weltea43f7892009-12-01 18:04:30 +053031#include <openbsc/system_information.h>
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020032#include <openbsc/paging.h>
33#include <openbsc/signal.h>
34#include <openbsc/talloc.h>
35
36/* global pointer to the gsm network data structure */
37extern struct gsm_network *bsc_gsmnet;
38extern int ipacc_rtp_direct;
39
40static void patch_nm_tables(struct gsm_bts *bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020041
42/* The following definitions are for OM and NM packets that we cannot yet
43 * generate by code but we just pass on */
44
45// BTS Site Manager, SET ATTRIBUTES
46
47/*
48 Object Class: BTS Site Manager
49 Instance 1: FF
50 Instance 2: FF
51 Instance 3: FF
52SET ATTRIBUTES
53 sAbisExternalTime: 2007/09/08 14:36:11
54 omLAPDRelTimer: 30sec
55 shortLAPDIntTimer: 5sec
56 emergencyTimer1: 10 minutes
57 emergencyTimer2: 0 minutes
58*/
59
60unsigned char msg_1[] =
61{
62 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
63 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
64 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
65 0x02,
66 0x00, 0x1E,
67 NM_ATT_BS11_SH_LAPD_INT_TIMER,
68 0x01, 0x05,
69 0x42, 0x02, 0x00, 0x0A,
70 0x44, 0x02, 0x00, 0x00
71};
72
73// BTS, SET BTS ATTRIBUTES
74
75/*
76 Object Class: BTS
77 BTS relat. Number: 0
78 Instance 2: FF
79 Instance 3: FF
80SET BTS ATTRIBUTES
81 bsIdentityCode / BSIC:
82 PLMN_colour_code: 7h
83 BS_colour_code: 7h
84 BTS Air Timer T3105: 4 ,unit 10 ms
85 btsIsHopping: FALSE
86 periodCCCHLoadIndication: 1sec
87 thresholdCCCHLoadIndication: 0%
88 cellAllocationNumber: 00h = GSM 900
89 enableInterferenceClass: 00h = Disabled
90 fACCHQual: 6 (FACCH stealing flags minus 1)
91 intaveParameter: 31 SACCH multiframes
92 interferenceLevelBoundaries:
93 Interference Boundary 1: 0Ah
94 Interference Boundary 2: 0Fh
95 Interference Boundary 3: 14h
96 Interference Boundary 4: 19h
97 Interference Boundary 5: 1Eh
98 mSTxPwrMax: 11
99 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
100 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
101 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
102 30=33dBm, 31=32dBm
103 ny1:
104 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
105 powerOutputThresholds:
106 Out Power Fault Threshold: -10 dB
107 Red Out Power Threshold: - 6 dB
108 Excessive Out Power Threshold: 5 dB
109 rACHBusyThreshold: -127 dBm
110 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
111 rfResourceIndicationPeriod: 125 SACCH multiframes
112 T200:
113 SDCCH: 044 in 5 ms
114 FACCH/Full rate: 031 in 5 ms
115 FACCH/Half rate: 041 in 5 ms
116 SACCH with TCH SAPI0: 090 in 10 ms
117 SACCH with SDCCH: 090 in 10 ms
118 SDCCH with SAPI3: 090 in 5 ms
119 SACCH with TCH SAPI3: 135 in 10 ms
120 tSync: 9000 units of 10 msec
121 tTrau: 9000 units of 10 msec
122 enableUmLoopTest: 00h = disabled
123 enableExcessiveDistance: 00h = Disabled
124 excessiveDistance: 64km
125 hoppingMode: 00h = baseband hopping
126 cellType: 00h = Standard Cell
127 BCCH ARFCN / bCCHFrequency: 1
128*/
129
130static unsigned char bs11_attr_bts[] =
131{
132 NM_ATT_BSIC, HARDCODED_BSIC,
133 NM_ATT_BTS_AIR_TIMER, 0x04,
134 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
135 NM_ATT_CCCH_L_I_P, 0x01,
136 NM_ATT_CCCH_L_T, 0x00,
137 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
138 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
139 NM_ATT_BS11_FACCH_QUAL, 0x06,
140 /* interference avg. period in numbers of SACCH multifr */
141 NM_ATT_INTAVE_PARAM, 0x1F,
142 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
143 NM_ATT_CCCH_L_T, 0x23,
144 NM_ATT_GSM_TIME, 0x28, 0x00,
145 NM_ATT_ADM_STATE, 0x03,
146 NM_ATT_RACH_B_THRESH, 0x7F,
147 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
148 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
149 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
150 NM_ATT_BS11_TSYNC, 0x23, 0x28,
151 NM_ATT_BS11_TTRAU, 0x23, 0x28,
152 NM_ATT_TEST_DUR, 0x01, 0x00,
153 NM_ATT_OUTST_ALARM, 0x01, 0x00,
154 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
155 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
156 NM_ATT_BS11_PLL, 0x01, 0x00,
157 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
158};
159
160// Handover Recognition, SET ATTRIBUTES
161
162/*
163Illegal Contents GSM Formatted O&M Msg
164 Object Class: Handover Recognition
165 BTS relat. Number: 0
166 Instance 2: FF
167 Instance 3: FF
168SET ATTRIBUTES
169 enableDelayPowerBudgetHO: 00h = Disabled
170 enableDistanceHO: 00h = Disabled
171 enableInternalInterCellHandover: 00h = Disabled
172 enableInternalIntraCellHandover: 00h = Disabled
173 enablePowerBudgetHO: 00h = Disabled
174 enableRXLEVHO: 00h = Disabled
175 enableRXQUALHO: 00h = Disabled
176 hoAveragingDistance: 8 SACCH multiframes
177 hoAveragingLev:
178 A_LEV_HO: 8 SACCH multiframes
179 W_LEV_HO: 1 SACCH multiframes
180 hoAveragingPowerBudget: 16 SACCH multiframes
181 hoAveragingQual:
182 A_QUAL_HO: 8 SACCH multiframes
183 W_QUAL_HO: 2 SACCH multiframes
184 hoLowerThresholdLevDL: (10 - 110) dBm
185 hoLowerThresholdLevUL: (5 - 110) dBm
186 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
187 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
188 hoThresholdLevDLintra : (20 - 110) dBm
189 hoThresholdLevULintra: (20 - 110) dBm
190 hoThresholdMsRangeMax: 20 km
191 nCell: 06h
192 timerHORequest: 3 ,unit 2 SACCH multiframes
193*/
194
195unsigned char msg_3[] =
196{
197 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
198 0xD0, 0x00, /* enableDelayPowerBudgetHO */
199 0x64, 0x00, /* enableDistanceHO */
200 0x67, 0x00, /* enableInternalInterCellHandover */
201 0x68, 0x00, /* enableInternalInterCellHandover */
202 0x6A, 0x00, /* enablePowerBudgetHO */
203 0x6C, 0x00, /* enableRXLEVHO */
204 0x6D, 0x00, /* enableRXQUALHO */
205 0x6F, 0x08, /* hoAveragingDistance */
206 0x70, 0x08, 0x01, /* hoAveragingLev */
207 0x71, 0x10, 0x10, 0x10,
208 0x72, 0x08, 0x02, /* hoAveragingQual */
209 0x73, 0x0A, /* hoLowerThresholdLevDL */
210 0x74, 0x05, /* hoLowerThresholdLevUL */
211 0x75, 0x06, /* hoLowerThresholdQualDL */
212 0x76, 0x06, /* hoLowerThresholdQualUL */
213 0x78, 0x14, /* hoThresholdLevDLintra */
214 0x79, 0x14, /* hoThresholdLevULintra */
215 0x7A, 0x14, /* hoThresholdMsRangeMax */
216 0x7D, 0x06, /* nCell */
217 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
218 0x20, 0x01, 0x00,
219 0x45, 0x01, 0x00,
220 0x48, 0x01, 0x00,
221 0x5A, 0x01, 0x00,
222 0x5B, 0x01, 0x05,
223 0x5E, 0x01, 0x1A,
224 0x5F, 0x01, 0x20,
225 0x9D, 0x01, 0x00,
226 0x47, 0x01, 0x00,
227 0x5C, 0x01, 0x64,
228 0x5D, 0x01, 0x1E,
229 0x97, 0x01, 0x20,
230 0xF7, 0x01, 0x3C,
231};
232
233// Power Control, SET ATTRIBUTES
234
235/*
236 Object Class: Power Control
237 BTS relat. Number: 0
238 Instance 2: FF
239 Instance 3: FF
240SET ATTRIBUTES
241 enableMsPowerControl: 00h = Disabled
242 enablePowerControlRLFW: 00h = Disabled
243 pcAveragingLev:
244 A_LEV_PC: 4 SACCH multiframes
245 W_LEV_PC: 1 SACCH multiframes
246 pcAveragingQual:
247 A_QUAL_PC: 4 SACCH multiframes
248 W_QUAL_PC: 2 SACCH multiframes
249 pcLowerThresholdLevDL: 0Fh
250 pcLowerThresholdLevUL: 0Ah
251 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
252 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
253 pcRLFThreshold: 0Ch
254 pcUpperThresholdLevDL: 14h
255 pcUpperThresholdLevUL: 0Fh
256 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
257 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
258 powerConfirm: 2 ,unit 2 SACCH multiframes
259 powerControlInterval: 2 ,unit 2 SACCH multiframes
260 powerIncrStepSize: 02h = 4 dB
261 powerRedStepSize: 01h = 2 dB
262 radioLinkTimeoutBs: 64 SACCH multiframes
263 enableBSPowerControl: 00h = disabled
264*/
265
266unsigned char msg_4[] =
267{
268 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
269 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
270 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
271 0x7E, 0x04, 0x01, /* pcAveragingLev */
272 0x7F, 0x04, 0x02, /* pcAveragingQual */
273 0x80, 0x0F, /* pcLowerThresholdLevDL */
274 0x81, 0x0A, /* pcLowerThresholdLevUL */
275 0x82, 0x05, /* pcLowerThresholdQualDL */
276 0x83, 0x05, /* pcLowerThresholdQualUL */
277 0x84, 0x0C, /* pcRLFThreshold */
278 0x85, 0x14, /* pcUpperThresholdLevDL */
279 0x86, 0x0F, /* pcUpperThresholdLevUL */
280 0x87, 0x04, /* pcUpperThresholdQualDL */
281 0x88, 0x04, /* pcUpperThresholdQualUL */
282 0x89, 0x02, /* powerConfirm */
283 0x8A, 0x02, /* powerConfirmInterval */
284 0x8B, 0x02, /* powerIncrStepSize */
285 0x8C, 0x01, /* powerRedStepSize */
286 0x8D, 0x40, /* radioLinkTimeoutBs */
287 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
288};
289
290
291// Transceiver, SET TRX ATTRIBUTES (TRX 0)
292
293/*
294 Object Class: Transceiver
295 BTS relat. Number: 0
296 Tranceiver number: 0
297 Instance 3: FF
298SET TRX ATTRIBUTES
299 aRFCNList (HEX): 0001
300 txPwrMaxReduction: 00h = 30dB
301 radioMeasGran: 254 SACCH multiframes
302 radioMeasRep: 01h = enabled
303 memberOfEmergencyConfig: 01h = TRUE
304 trxArea: 00h = TRX doesn't belong to a concentric cell
305*/
306
307static unsigned char bs11_attr_radio[] =
308{
309 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
310 NM_ATT_RF_MAXPOWR_R, 0x00,
311 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0x05,
312 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
313 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
314 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
315};
316
317static unsigned char nanobts_attr_bts[] = {
318 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
319 /* interference avg. period in numbers of SACCH multifr */
320 NM_ATT_INTAVE_PARAM, 0x06,
321 /* conn fail based on SACCH error rate */
322 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
323 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
324 NM_ATT_MAX_TA, 0x3f,
325 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
326 NM_ATT_CCCH_L_T, 10, /* percent */
327 NM_ATT_CCCH_L_I_P, 1, /* seconds */
328 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
329 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
330 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
331 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
332 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
333 NM_ATT_BSIC, HARDCODED_BSIC,
334};
335
336static unsigned char nanobts_attr_radio[] = {
337 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
338 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
339};
340
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200341/* Callback function to be called whenever we get a GSM 12.21 state change event */
342int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
343 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
344{
345 struct gsm_bts *bts;
346 struct gsm_bts_trx *trx;
347 struct gsm_bts_trx_ts *ts;
348
Harald Welte8406ec22009-10-20 17:31:00 +0200349 /* This event-driven BTS setup is currently only required on nanoBTS */
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200350
Harald Welte8406ec22009-10-20 17:31:00 +0200351 /* EVT_STATECHG_ADM is called after we call chg_adm_state() and would create
352 * endless loop */
353 if (evt != EVT_STATECHG_OPER)
354 return 0;
355
356 switch (obj_class) {
357 case NM_OC_SITE_MANAGER:
358 bts = container_of(obj, struct gsm_bts, site_mgr);
359 if (new_state->operational == 2 &&
360 new_state->availability == NM_AVSTATE_OK)
361 abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
362 break;
363 case NM_OC_BTS:
364 bts = obj;
365 if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
366 patch_nm_tables(bts);
367 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
368 sizeof(nanobts_attr_bts));
369 abis_nm_chg_adm_state(bts, obj_class,
370 bts->bts_nr, 0xff, 0xff,
371 NM_STATE_UNLOCKED);
372 abis_nm_opstart(bts, obj_class,
373 bts->bts_nr, 0xff, 0xff);
374 }
375 break;
376 case NM_OC_CHANNEL:
377 ts = obj;
378 trx = ts->trx;
379 if (new_state->operational == 1 &&
380 new_state->availability == NM_AVSTATE_DEPENDENCY) {
Harald Welte65bdc912009-10-26 20:14:33 +0100381 patch_nm_tables(trx->bts);
Harald Welte0f890b02009-10-24 09:09:05 +0200382 enum abis_nm_chan_comb ccomb =
383 abis_nm_chcomb4pchan(ts->pchan);
384 abis_nm_set_channel_attr(ts, ccomb);
Harald Welte8406ec22009-10-20 17:31:00 +0200385 abis_nm_chg_adm_state(trx->bts, obj_class,
386 trx->bts->bts_nr, trx->nr, ts->nr,
387 NM_STATE_UNLOCKED);
388 abis_nm_opstart(trx->bts, obj_class,
389 trx->bts->bts_nr, trx->nr, ts->nr);
390 }
391 break;
392 case NM_OC_RADIO_CARRIER:
393 trx = obj;
394 if (new_state->operational == 1 &&
Harald Welte8406ec22009-10-20 17:31:00 +0200395 new_state->availability == NM_AVSTATE_OK)
396 abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
397 trx->nr, 0xff);
398 break;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200399 default:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200400 break;
401 }
402 return 0;
403}
404
405/* Callback function to be called every time we receive a 12.21 SW activated report */
406static int sw_activ_rep(struct msgb *mb)
407{
408 struct abis_om_fom_hdr *foh = msgb_l3(mb);
Harald Welted004a642009-10-19 21:47:54 +0200409 struct gsm_bts *bts = mb->trx->bts;
410 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
411
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200412
413 switch (foh->obj_class) {
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100414 case NM_OC_BASEB_TRANSC:
415 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
416 trx->bts->bts_nr, trx->nr, 0xff,
417 NM_STATE_UNLOCKED);
418 abis_nm_opstart(trx->bts, foh->obj_class,
419 trx->bts->bts_nr, trx->nr, 0xff);
420 /* TRX software is active, tell it to initiate RSL Link */
421 abis_nm_ipaccess_rsl_connect(trx, 0, 3003, trx->rsl_tei);
422 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100423 case NM_OC_RADIO_CARRIER: {
424 /*
425 * Locking the radio carrier will make it go
426 * offline again and we would come here. The
427 * framework should determine that there was
428 * no change and avoid recursion.
429 *
430 * This code is here to make sure that on start
431 * a TRX remains locked.
432 */
433 int rc_state = trx->rf_locked ?
434 NM_STATE_LOCKED : NM_STATE_UNLOCKED;
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100435 /* Patch ARFCN into radio attribute */
436 nanobts_attr_radio[5] &= 0xf0;
437 nanobts_attr_radio[5] |= trx->arfcn >> 8;
438 nanobts_attr_radio[6] = trx->arfcn & 0xff;
439 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
440 sizeof(nanobts_attr_radio));
441 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
442 trx->bts->bts_nr, trx->nr, 0xff,
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100443 rc_state);
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100444 abis_nm_opstart(trx->bts, foh->obj_class, trx->bts->bts_nr,
445 trx->nr, 0xff);
446 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100447 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200448 }
449 return 0;
450}
451
452/* Callback function for NACK on the OML NM */
Harald Welted8cfc902009-11-17 06:09:56 +0100453static int oml_msg_nack(u_int8_t mt)
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200454{
455 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100456 LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200457 "Was the bts type and frequency properly specified?\n");
458 exit(-1);
459 }
460
461 return 0;
462}
463
464/* Callback function to be called every time we receive a signal from NM */
465static int nm_sig_cb(unsigned int subsys, unsigned int signal,
466 void *handler_data, void *signal_data)
467{
Harald Welted8cfc902009-11-17 06:09:56 +0100468 u_int8_t *msg_type;
469
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200470 switch (signal) {
471 case S_NM_SW_ACTIV_REP:
472 return sw_activ_rep(signal_data);
473 case S_NM_NACK:
Harald Welted8cfc902009-11-17 06:09:56 +0100474 msg_type = signal_data;
475 return oml_msg_nack(*msg_type);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200476 default:
477 break;
478 }
479 return 0;
480}
481
482static void bootstrap_om_nanobts(struct gsm_bts *bts)
483{
484 /* We don't do callback based bootstrapping, but event driven (see above) */
485}
486
487static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
488{
489 enum abis_nm_chan_comb ccomb = abis_nm_chcomb4pchan(ts->pchan);
490 struct gsm_e1_subslot *e1l = &ts->e1_link;
491
492 abis_nm_set_channel_attr(ts, ccomb);
493
494 if (is_ipaccess_bts(ts->trx->bts))
495 return;
496
497 switch (ts->pchan) {
498 case GSM_PCHAN_TCH_F:
499 case GSM_PCHAN_TCH_H:
500 abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts,
501 e1l->e1_ts_ss);
502 break;
503 default:
504 break;
505 }
506}
507
508static void nm_reconfig_trx(struct gsm_bts_trx *trx)
509{
510 struct gsm_e1_subslot *e1l = &trx->rsl_e1_link;
511 int i;
512
513 patch_nm_tables(trx->bts);
514
515 switch (trx->bts->type) {
516 case GSM_BTS_TYPE_BS11:
517 /* FIXME: discover this by fetching an attribute */
518#if 0
519 trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
520#else
521 trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
522#endif
523 abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
524 e1l->e1_ts_ss);
525 abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
526 e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei);
527
528 /* Set Radio Attributes */
529 if (trx == trx->bts->c0)
530 abis_nm_set_radio_attr(trx, bs11_attr_radio,
531 sizeof(bs11_attr_radio));
532 else {
533 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
534 u_int8_t arfcn_low = trx->arfcn & 0xff;
535 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
536 memcpy(trx1_attr_radio, bs11_attr_radio,
537 sizeof(trx1_attr_radio));
538
539 /* patch ARFCN into TRX Attributes */
540 trx1_attr_radio[2] &= 0xf0;
541 trx1_attr_radio[2] |= arfcn_high;
542 trx1_attr_radio[3] = arfcn_low;
543
544 abis_nm_set_radio_attr(trx, trx1_attr_radio,
545 sizeof(trx1_attr_radio));
546 }
547 break;
Mike Habene2d82272009-10-02 12:19:34 +0100548 case GSM_BTS_TYPE_NANOBTS:
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200549 switch (trx->bts->band) {
550 case GSM_BAND_850:
551 case GSM_BAND_900:
552 trx->nominal_power = 20;
553 break;
554 case GSM_BAND_1800:
555 case GSM_BAND_1900:
556 trx->nominal_power = 23;
557 break;
Holger Hans Peter Freyther555eba12009-10-22 15:46:16 +0200558 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100559 LOGP(DNM, LOGL_ERROR, "Unsupported nanoBTS GSM band %s\n",
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200560 gsm_band_name(trx->bts->band));
561 break;
562 }
563 break;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200564 default:
565 break;
566 }
567
568 for (i = 0; i < TRX_NR_TS; i++)
569 nm_reconfig_ts(&trx->ts[i]);
570}
571
572static void nm_reconfig_bts(struct gsm_bts *bts)
573{
574 struct gsm_bts_trx *trx;
575
576 switch (bts->type) {
577 case GSM_BTS_TYPE_BS11:
Harald Welteade7a142009-12-14 17:49:52 +0100578 patch_nm_tables(bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200579 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
580 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
581 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
582 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
583 break;
584 default:
585 break;
586 }
587
588 llist_for_each_entry(trx, &bts->trx_list, list)
589 nm_reconfig_trx(trx);
590}
591
592static void bootstrap_om_bs11(struct gsm_bts *bts)
593{
594 /* stop sending event reports */
595 abis_nm_event_reports(bts, 0);
596
597 /* begin DB transmission */
598 abis_nm_bs11_db_transmission(bts, 1);
599
600 /* end DB transmission */
601 abis_nm_bs11_db_transmission(bts, 0);
602
603 /* Reset BTS Site manager resource */
604 abis_nm_bs11_reset_resource(bts);
605
606 /* begin DB transmission */
607 abis_nm_bs11_db_transmission(bts, 1);
608
609 /* reconfigure BTS with all TRX and all TS */
610 nm_reconfig_bts(bts);
611
612 /* end DB transmission */
613 abis_nm_bs11_db_transmission(bts, 0);
614
615 /* Reset BTS Site manager resource */
616 abis_nm_bs11_reset_resource(bts);
617
618 /* restart sending event reports */
619 abis_nm_event_reports(bts, 1);
620}
621
622static void bootstrap_om(struct gsm_bts *bts)
623{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100624 LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200625
626 switch (bts->type) {
627 case GSM_BTS_TYPE_BS11:
628 bootstrap_om_bs11(bts);
629 break;
Mike Habene2d82272009-10-02 12:19:34 +0100630 case GSM_BTS_TYPE_NANOBTS:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200631 bootstrap_om_nanobts(bts);
632 break;
633 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100634 LOGP(DNM, LOGL_ERROR, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200635 }
636}
637
638static int shutdown_om(struct gsm_bts *bts)
639{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100640 LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200641
642 /* stop sending event reports */
643 abis_nm_event_reports(bts, 0);
644
645 /* begin DB transmission */
646 abis_nm_bs11_db_transmission(bts, 1);
647
648 /* end DB transmission */
649 abis_nm_bs11_db_transmission(bts, 0);
650
651 /* Reset BTS Site manager resource */
652 abis_nm_bs11_reset_resource(bts);
653
654 return 0;
655}
656
657int bsc_shutdown_net(struct gsm_network *net)
658{
659 struct gsm_bts *bts;
660
661 llist_for_each_entry(bts, &net->bts_list, list) {
662 int rc;
663 rc = shutdown_om(bts);
664 if (rc < 0)
665 return rc;
666 }
667
668 return 0;
669}
670
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200671/* set all system information types */
672static int set_system_infos(struct gsm_bts_trx *trx)
673{
Harald Weltea43f7892009-12-01 18:04:30 +0530674 int i, rc;
675 u_int8_t si_tmp[23];
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200676
677 if (trx == trx->bts->c0) {
Harald Weltea43f7892009-12-01 18:04:30 +0530678 for (i = 1; i <= 4; i++) {
679 rc = gsm_generate_si(si_tmp, trx->bts, i);
680 if (rc < 0)
681 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100682 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530683 rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200684 }
685 }
Harald Weltea43f7892009-12-01 18:04:30 +0530686#ifdef GPRS
Harald Welte50e7fec2009-12-19 21:29:00 +0100687 i = 13
Harald Weltea43f7892009-12-01 18:04:30 +0530688 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
Harald Welte50e7fec2009-12-19 21:29:00 +0100689 if (rc < 0)
Harald Weltea43f7892009-12-01 18:04:30 +0530690 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100691 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530692 rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
693#endif
Harald Welte50e7fec2009-12-19 21:29:00 +0100694 i = 5;
695 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_5);
696 if (rc < 0)
Harald Weltea43f7892009-12-01 18:04:30 +0530697 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100698 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530699 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si_tmp, rc);
700
Harald Welte50e7fec2009-12-19 21:29:00 +0100701 i = 6;
702 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_6);
703 if (rc < 0)
Harald Weltea43f7892009-12-01 18:04:30 +0530704 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100705 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530706 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si_tmp, rc);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200707
708 return 0;
Harald Weltea43f7892009-12-01 18:04:30 +0530709err_out:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100710 LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
Harald Weltea43f7892009-12-01 18:04:30 +0530711 "a problem with neighbor cell list generation\n",
Harald Welte152b6262009-12-16 11:57:48 +0100712 i, trx->bts->nr);
Harald Weltea43f7892009-12-01 18:04:30 +0530713 return rc;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200714}
715
716/*
717 * Patch the various SYSTEM INFORMATION tables to update
718 * the LAI
719 */
720static void patch_nm_tables(struct gsm_bts *bts)
721{
722 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
723 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
724
725 /* patch ARFCN into BTS Attributes */
726 bs11_attr_bts[69] &= 0xf0;
727 bs11_attr_bts[69] |= arfcn_high;
728 bs11_attr_bts[70] = arfcn_low;
729 nanobts_attr_bts[42] &= 0xf0;
730 nanobts_attr_bts[42] |= arfcn_high;
731 nanobts_attr_bts[43] = arfcn_low;
732
733 /* patch ARFCN into TRX Attributes */
734 bs11_attr_radio[2] &= 0xf0;
735 bs11_attr_radio[2] |= arfcn_high;
736 bs11_attr_radio[3] = arfcn_low;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200737
738 /* patch BSIC */
739 bs11_attr_bts[1] = bts->bsic;
740 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
741
742 /* patch the power reduction */
743 bs11_attr_radio[5] = bts->c0->max_power_red / 2;
744 nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
745}
746
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200747static void bootstrap_rsl(struct gsm_bts_trx *trx)
748{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100749 LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200750 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
751 trx->bts->nr, trx->nr, bsc_gsmnet->country_code,
752 bsc_gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200753 set_system_infos(trx);
754}
755
756void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
757{
758 switch (event) {
759 case EVT_E1_TEI_UP:
760 switch (type) {
761 case E1INP_SIGN_OML:
762 bootstrap_om(trx->bts);
763 break;
764 case E1INP_SIGN_RSL:
765 bootstrap_rsl(trx);
766 break;
767 default:
768 break;
769 }
770 break;
771 case EVT_E1_TEI_DN:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100772 LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200773 /* FIXME: deal with TEI or L1 link loss */
774 break;
775 default:
776 break;
777 }
778}
779
780static int bootstrap_bts(struct gsm_bts *bts)
781{
Mike Habene2d82272009-10-02 12:19:34 +0100782 switch (bts->band) {
783 case GSM_BAND_1800:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200784 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100785 LOGP(DNM, LOGL_ERROR, "GSM1800 channel must be between 512-885.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200786 return -EINVAL;
787 }
788 break;
Mike Habene2d82272009-10-02 12:19:34 +0100789 case GSM_BAND_1900:
790 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 810) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100791 LOGP(DNM, LOGL_ERROR, "GSM1900 channel must be between 512-810.\n");
Mike Habene2d82272009-10-02 12:19:34 +0100792 return -EINVAL;
793 }
794 break;
795 case GSM_BAND_900:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200796 if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100797 LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200798 return -EINVAL;
799 }
800 break;
Mike Habene2d82272009-10-02 12:19:34 +0100801 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100802 LOGP(DNM, LOGL_ERROR, "Unsupported frequency band.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200803 return -EINVAL;
804 }
805
Harald Welted6aa5242009-12-12 13:44:19 +0100806 if (bts->network->auth_policy == GSM_AUTH_POLICY_ACCEPT_ALL &&
807 !bts->cell_barred)
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100808 LOGP(DNM, LOG_ERROR, "\nWARNING: You are running an 'accept-all' "
Harald Welted6aa5242009-12-12 13:44:19 +0100809 "network on a BTS that is not barred. This "
810 "configuration is likely to interfere with production "
811 "GSM networks and should only be used in a RF "
812 "shielded environment such as a faraday cage!\n\n");
813
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200814 /* Control Channel Description */
Harald Weltea43f7892009-12-01 18:04:30 +0530815 bts->si_common.chan_desc.att = 1;
816 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
817 bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
818 if (bts->cell_barred)
819 bts->si_common.rach_control.cell_bar = 1;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200820 /* T3212 is set from vty/config */
821
Harald Weltea43f7892009-12-01 18:04:30 +0530822 /* some defaults for our system information */
823 bts->si_common.rach_control.re = 1; /* no re-establishment */
824 bts->si_common.rach_control.tx_integer = 5; /* 8 slots spread */
825 bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
826 bts->si_common.rach_control.t2 = 4; /* no emergency calls */
827
828 bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
829 bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
830 bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
831
832 bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
833 ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
Harald Weltea43f7892009-12-01 18:04:30 +0530834 bts->si_common.cell_sel_par.acs = 0;
835 bts->si_common.cell_sel_par.neci = bts->network->neci;
836
837 bts->si_common.ncc_permitted = 0xff;
838
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200839 paging_init(bts);
840
841 return 0;
842}
843
844int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
845 const char *config_file)
846{
847 struct gsm_bts *bts;
848 int rc;
849
850 /* initialize our data structures */
851 bsc_gsmnet = gsm_network_init(1, 1, mncc_recv);
852 if (!bsc_gsmnet)
853 return -ENOMEM;
854
855 bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
856 bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
857
858 telnet_init(bsc_gsmnet, 4242);
859 rc = vty_read_config_file(config_file);
860 if (rc < 0) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100861 LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200862 return rc;
863 }
864
865 register_signal_handler(SS_NM, nm_sig_cb, NULL);
866
867 llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
868 bootstrap_bts(bts);
869 if (!is_ipaccess_bts(bts))
870 rc = e1_reconfig_bts(bts);
871
872 if (rc < 0)
873 exit (1);
874 }
875
876 /* initialize nanoBTS support omce */
877 rc = ipaccess_setup(bsc_gsmnet);
878
879 return 0;
880}