blob: 57fc4b3e1c43917186cac251f2548840264981be [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>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010024#include <osmocore/gsm_utils.h>
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020025#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>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010034#include <osmocore/talloc.h>
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020035
36/* global pointer to the gsm network data structure */
37extern struct gsm_network *bsc_gsmnet;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020038
39static void patch_nm_tables(struct gsm_bts *bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020040
41/* The following definitions are for OM and NM packets that we cannot yet
42 * generate by code but we just pass on */
43
44// BTS Site Manager, SET ATTRIBUTES
45
46/*
47 Object Class: BTS Site Manager
48 Instance 1: FF
49 Instance 2: FF
50 Instance 3: FF
51SET ATTRIBUTES
52 sAbisExternalTime: 2007/09/08 14:36:11
53 omLAPDRelTimer: 30sec
54 shortLAPDIntTimer: 5sec
55 emergencyTimer1: 10 minutes
56 emergencyTimer2: 0 minutes
57*/
58
59unsigned char msg_1[] =
60{
61 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
62 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
63 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
64 0x02,
65 0x00, 0x1E,
66 NM_ATT_BS11_SH_LAPD_INT_TIMER,
67 0x01, 0x05,
68 0x42, 0x02, 0x00, 0x0A,
69 0x44, 0x02, 0x00, 0x00
70};
71
72// BTS, SET BTS ATTRIBUTES
73
74/*
75 Object Class: BTS
76 BTS relat. Number: 0
77 Instance 2: FF
78 Instance 3: FF
79SET BTS ATTRIBUTES
80 bsIdentityCode / BSIC:
81 PLMN_colour_code: 7h
82 BS_colour_code: 7h
83 BTS Air Timer T3105: 4 ,unit 10 ms
84 btsIsHopping: FALSE
85 periodCCCHLoadIndication: 1sec
86 thresholdCCCHLoadIndication: 0%
87 cellAllocationNumber: 00h = GSM 900
88 enableInterferenceClass: 00h = Disabled
89 fACCHQual: 6 (FACCH stealing flags minus 1)
90 intaveParameter: 31 SACCH multiframes
91 interferenceLevelBoundaries:
92 Interference Boundary 1: 0Ah
93 Interference Boundary 2: 0Fh
94 Interference Boundary 3: 14h
95 Interference Boundary 4: 19h
96 Interference Boundary 5: 1Eh
97 mSTxPwrMax: 11
98 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
99 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
100 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
101 30=33dBm, 31=32dBm
102 ny1:
103 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
104 powerOutputThresholds:
105 Out Power Fault Threshold: -10 dB
106 Red Out Power Threshold: - 6 dB
107 Excessive Out Power Threshold: 5 dB
108 rACHBusyThreshold: -127 dBm
109 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
110 rfResourceIndicationPeriod: 125 SACCH multiframes
111 T200:
112 SDCCH: 044 in 5 ms
113 FACCH/Full rate: 031 in 5 ms
114 FACCH/Half rate: 041 in 5 ms
115 SACCH with TCH SAPI0: 090 in 10 ms
116 SACCH with SDCCH: 090 in 10 ms
117 SDCCH with SAPI3: 090 in 5 ms
118 SACCH with TCH SAPI3: 135 in 10 ms
119 tSync: 9000 units of 10 msec
120 tTrau: 9000 units of 10 msec
121 enableUmLoopTest: 00h = disabled
122 enableExcessiveDistance: 00h = Disabled
123 excessiveDistance: 64km
124 hoppingMode: 00h = baseband hopping
125 cellType: 00h = Standard Cell
126 BCCH ARFCN / bCCHFrequency: 1
127*/
128
129static unsigned char bs11_attr_bts[] =
130{
131 NM_ATT_BSIC, HARDCODED_BSIC,
132 NM_ATT_BTS_AIR_TIMER, 0x04,
133 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
134 NM_ATT_CCCH_L_I_P, 0x01,
135 NM_ATT_CCCH_L_T, 0x00,
136 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
137 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
138 NM_ATT_BS11_FACCH_QUAL, 0x06,
139 /* interference avg. period in numbers of SACCH multifr */
140 NM_ATT_INTAVE_PARAM, 0x1F,
141 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
142 NM_ATT_CCCH_L_T, 0x23,
143 NM_ATT_GSM_TIME, 0x28, 0x00,
144 NM_ATT_ADM_STATE, 0x03,
145 NM_ATT_RACH_B_THRESH, 0x7F,
146 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
147 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
148 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
149 NM_ATT_BS11_TSYNC, 0x23, 0x28,
150 NM_ATT_BS11_TTRAU, 0x23, 0x28,
151 NM_ATT_TEST_DUR, 0x01, 0x00,
152 NM_ATT_OUTST_ALARM, 0x01, 0x00,
153 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
154 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
155 NM_ATT_BS11_PLL, 0x01, 0x00,
156 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
157};
158
159// Handover Recognition, SET ATTRIBUTES
160
161/*
162Illegal Contents GSM Formatted O&M Msg
163 Object Class: Handover Recognition
164 BTS relat. Number: 0
165 Instance 2: FF
166 Instance 3: FF
167SET ATTRIBUTES
168 enableDelayPowerBudgetHO: 00h = Disabled
169 enableDistanceHO: 00h = Disabled
170 enableInternalInterCellHandover: 00h = Disabled
171 enableInternalIntraCellHandover: 00h = Disabled
172 enablePowerBudgetHO: 00h = Disabled
173 enableRXLEVHO: 00h = Disabled
174 enableRXQUALHO: 00h = Disabled
175 hoAveragingDistance: 8 SACCH multiframes
176 hoAveragingLev:
177 A_LEV_HO: 8 SACCH multiframes
178 W_LEV_HO: 1 SACCH multiframes
179 hoAveragingPowerBudget: 16 SACCH multiframes
180 hoAveragingQual:
181 A_QUAL_HO: 8 SACCH multiframes
182 W_QUAL_HO: 2 SACCH multiframes
183 hoLowerThresholdLevDL: (10 - 110) dBm
184 hoLowerThresholdLevUL: (5 - 110) dBm
185 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
186 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
187 hoThresholdLevDLintra : (20 - 110) dBm
188 hoThresholdLevULintra: (20 - 110) dBm
189 hoThresholdMsRangeMax: 20 km
190 nCell: 06h
191 timerHORequest: 3 ,unit 2 SACCH multiframes
192*/
193
194unsigned char msg_3[] =
195{
196 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
197 0xD0, 0x00, /* enableDelayPowerBudgetHO */
198 0x64, 0x00, /* enableDistanceHO */
199 0x67, 0x00, /* enableInternalInterCellHandover */
200 0x68, 0x00, /* enableInternalInterCellHandover */
201 0x6A, 0x00, /* enablePowerBudgetHO */
202 0x6C, 0x00, /* enableRXLEVHO */
203 0x6D, 0x00, /* enableRXQUALHO */
204 0x6F, 0x08, /* hoAveragingDistance */
205 0x70, 0x08, 0x01, /* hoAveragingLev */
206 0x71, 0x10, 0x10, 0x10,
207 0x72, 0x08, 0x02, /* hoAveragingQual */
208 0x73, 0x0A, /* hoLowerThresholdLevDL */
209 0x74, 0x05, /* hoLowerThresholdLevUL */
210 0x75, 0x06, /* hoLowerThresholdQualDL */
211 0x76, 0x06, /* hoLowerThresholdQualUL */
212 0x78, 0x14, /* hoThresholdLevDLintra */
213 0x79, 0x14, /* hoThresholdLevULintra */
214 0x7A, 0x14, /* hoThresholdMsRangeMax */
215 0x7D, 0x06, /* nCell */
216 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
217 0x20, 0x01, 0x00,
218 0x45, 0x01, 0x00,
219 0x48, 0x01, 0x00,
220 0x5A, 0x01, 0x00,
221 0x5B, 0x01, 0x05,
222 0x5E, 0x01, 0x1A,
223 0x5F, 0x01, 0x20,
224 0x9D, 0x01, 0x00,
225 0x47, 0x01, 0x00,
226 0x5C, 0x01, 0x64,
227 0x5D, 0x01, 0x1E,
228 0x97, 0x01, 0x20,
229 0xF7, 0x01, 0x3C,
230};
231
232// Power Control, SET ATTRIBUTES
233
234/*
235 Object Class: Power Control
236 BTS relat. Number: 0
237 Instance 2: FF
238 Instance 3: FF
239SET ATTRIBUTES
240 enableMsPowerControl: 00h = Disabled
241 enablePowerControlRLFW: 00h = Disabled
242 pcAveragingLev:
243 A_LEV_PC: 4 SACCH multiframes
244 W_LEV_PC: 1 SACCH multiframes
245 pcAveragingQual:
246 A_QUAL_PC: 4 SACCH multiframes
247 W_QUAL_PC: 2 SACCH multiframes
248 pcLowerThresholdLevDL: 0Fh
249 pcLowerThresholdLevUL: 0Ah
250 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
251 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
252 pcRLFThreshold: 0Ch
253 pcUpperThresholdLevDL: 14h
254 pcUpperThresholdLevUL: 0Fh
255 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
256 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
257 powerConfirm: 2 ,unit 2 SACCH multiframes
258 powerControlInterval: 2 ,unit 2 SACCH multiframes
259 powerIncrStepSize: 02h = 4 dB
260 powerRedStepSize: 01h = 2 dB
261 radioLinkTimeoutBs: 64 SACCH multiframes
262 enableBSPowerControl: 00h = disabled
263*/
264
265unsigned char msg_4[] =
266{
267 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
268 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
269 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
270 0x7E, 0x04, 0x01, /* pcAveragingLev */
271 0x7F, 0x04, 0x02, /* pcAveragingQual */
272 0x80, 0x0F, /* pcLowerThresholdLevDL */
273 0x81, 0x0A, /* pcLowerThresholdLevUL */
274 0x82, 0x05, /* pcLowerThresholdQualDL */
275 0x83, 0x05, /* pcLowerThresholdQualUL */
276 0x84, 0x0C, /* pcRLFThreshold */
277 0x85, 0x14, /* pcUpperThresholdLevDL */
278 0x86, 0x0F, /* pcUpperThresholdLevUL */
279 0x87, 0x04, /* pcUpperThresholdQualDL */
280 0x88, 0x04, /* pcUpperThresholdQualUL */
281 0x89, 0x02, /* powerConfirm */
282 0x8A, 0x02, /* powerConfirmInterval */
283 0x8B, 0x02, /* powerIncrStepSize */
284 0x8C, 0x01, /* powerRedStepSize */
285 0x8D, 0x40, /* radioLinkTimeoutBs */
286 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
287};
288
289
290// Transceiver, SET TRX ATTRIBUTES (TRX 0)
291
292/*
293 Object Class: Transceiver
294 BTS relat. Number: 0
295 Tranceiver number: 0
296 Instance 3: FF
297SET TRX ATTRIBUTES
298 aRFCNList (HEX): 0001
299 txPwrMaxReduction: 00h = 30dB
300 radioMeasGran: 254 SACCH multiframes
301 radioMeasRep: 01h = enabled
302 memberOfEmergencyConfig: 01h = TRUE
303 trxArea: 00h = TRX doesn't belong to a concentric cell
304*/
305
306static unsigned char bs11_attr_radio[] =
307{
308 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
309 NM_ATT_RF_MAXPOWR_R, 0x00,
310 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0x05,
311 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
312 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
313 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
314};
315
316static unsigned char nanobts_attr_bts[] = {
317 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
318 /* interference avg. period in numbers of SACCH multifr */
319 NM_ATT_INTAVE_PARAM, 0x06,
320 /* conn fail based on SACCH error rate */
321 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
322 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
323 NM_ATT_MAX_TA, 0x3f,
324 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
325 NM_ATT_CCCH_L_T, 10, /* percent */
326 NM_ATT_CCCH_L_I_P, 1, /* seconds */
327 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
328 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
329 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
330 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
331 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
332 NM_ATT_BSIC, HARDCODED_BSIC,
333};
334
335static unsigned char nanobts_attr_radio[] = {
336 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
337 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
338};
339
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200340/* Callback function to be called whenever we get a GSM 12.21 state change event */
341int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
342 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
343{
344 struct gsm_bts *bts;
345 struct gsm_bts_trx *trx;
346 struct gsm_bts_trx_ts *ts;
347
Harald Welte8406ec22009-10-20 17:31:00 +0200348 /* This event-driven BTS setup is currently only required on nanoBTS */
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200349
Harald Welte8406ec22009-10-20 17:31:00 +0200350 /* EVT_STATECHG_ADM is called after we call chg_adm_state() and would create
351 * endless loop */
352 if (evt != EVT_STATECHG_OPER)
353 return 0;
354
355 switch (obj_class) {
356 case NM_OC_SITE_MANAGER:
357 bts = container_of(obj, struct gsm_bts, site_mgr);
Sylvain Munaut7de67962009-12-18 17:45:45 +0100358 if ((new_state->operational == 2 &&
359 new_state->availability == NM_AVSTATE_OK) ||
360 (new_state->operational == 1 &&
361 new_state->availability == NM_AVSTATE_OFF_LINE))
Harald Welte8406ec22009-10-20 17:31:00 +0200362 abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
363 break;
364 case NM_OC_BTS:
365 bts = obj;
366 if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
367 patch_nm_tables(bts);
368 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
369 sizeof(nanobts_attr_bts));
370 abis_nm_chg_adm_state(bts, obj_class,
371 bts->bts_nr, 0xff, 0xff,
372 NM_STATE_UNLOCKED);
373 abis_nm_opstart(bts, obj_class,
374 bts->bts_nr, 0xff, 0xff);
375 }
376 break;
377 case NM_OC_CHANNEL:
378 ts = obj;
379 trx = ts->trx;
380 if (new_state->operational == 1 &&
381 new_state->availability == NM_AVSTATE_DEPENDENCY) {
Harald Welte65bdc912009-10-26 20:14:33 +0100382 patch_nm_tables(trx->bts);
Harald Welte0f890b02009-10-24 09:09:05 +0200383 enum abis_nm_chan_comb ccomb =
384 abis_nm_chcomb4pchan(ts->pchan);
385 abis_nm_set_channel_attr(ts, ccomb);
Harald Welte8406ec22009-10-20 17:31:00 +0200386 abis_nm_chg_adm_state(trx->bts, obj_class,
387 trx->bts->bts_nr, trx->nr, ts->nr,
388 NM_STATE_UNLOCKED);
389 abis_nm_opstart(trx->bts, obj_class,
390 trx->bts->bts_nr, trx->nr, ts->nr);
391 }
392 break;
393 case NM_OC_RADIO_CARRIER:
394 trx = obj;
395 if (new_state->operational == 1 &&
Harald Welte8406ec22009-10-20 17:31:00 +0200396 new_state->availability == NM_AVSTATE_OK)
397 abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
398 trx->nr, 0xff);
399 break;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200400 default:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200401 break;
402 }
403 return 0;
404}
405
406/* Callback function to be called every time we receive a 12.21 SW activated report */
407static int sw_activ_rep(struct msgb *mb)
408{
409 struct abis_om_fom_hdr *foh = msgb_l3(mb);
Harald Welted004a642009-10-19 21:47:54 +0200410 struct gsm_bts *bts = mb->trx->bts;
411 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
412
Harald Welteb7bcb792009-12-23 18:24:31 +0100413 if (!trx)
414 return -EINVAL;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200415
416 switch (foh->obj_class) {
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100417 case NM_OC_BASEB_TRANSC:
418 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
419 trx->bts->bts_nr, trx->nr, 0xff,
420 NM_STATE_UNLOCKED);
421 abis_nm_opstart(trx->bts, foh->obj_class,
422 trx->bts->bts_nr, trx->nr, 0xff);
423 /* TRX software is active, tell it to initiate RSL Link */
424 abis_nm_ipaccess_rsl_connect(trx, 0, 3003, trx->rsl_tei);
425 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100426 case NM_OC_RADIO_CARRIER: {
427 /*
428 * Locking the radio carrier will make it go
429 * offline again and we would come here. The
430 * framework should determine that there was
431 * no change and avoid recursion.
432 *
433 * This code is here to make sure that on start
434 * a TRX remains locked.
435 */
Holger Hans Peter Freytherf31e4742009-12-31 03:05:52 +0100436 int rc_state = trx->nm_state.administrative;
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100437 /* Patch ARFCN into radio attribute */
438 nanobts_attr_radio[5] &= 0xf0;
439 nanobts_attr_radio[5] |= trx->arfcn >> 8;
440 nanobts_attr_radio[6] = trx->arfcn & 0xff;
441 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
442 sizeof(nanobts_attr_radio));
443 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
444 trx->bts->bts_nr, trx->nr, 0xff,
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100445 rc_state);
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100446 abis_nm_opstart(trx->bts, foh->obj_class, trx->bts->bts_nr,
447 trx->nr, 0xff);
448 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100449 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200450 }
451 return 0;
452}
453
454/* Callback function for NACK on the OML NM */
Harald Welted8cfc902009-11-17 06:09:56 +0100455static int oml_msg_nack(u_int8_t mt)
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200456{
457 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100458 LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200459 "Was the bts type and frequency properly specified?\n");
460 exit(-1);
461 }
462
463 return 0;
464}
465
466/* Callback function to be called every time we receive a signal from NM */
467static int nm_sig_cb(unsigned int subsys, unsigned int signal,
468 void *handler_data, void *signal_data)
469{
Harald Welted8cfc902009-11-17 06:09:56 +0100470 u_int8_t *msg_type;
471
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200472 switch (signal) {
473 case S_NM_SW_ACTIV_REP:
474 return sw_activ_rep(signal_data);
475 case S_NM_NACK:
Harald Welted8cfc902009-11-17 06:09:56 +0100476 msg_type = signal_data;
477 return oml_msg_nack(*msg_type);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200478 default:
479 break;
480 }
481 return 0;
482}
483
484static void bootstrap_om_nanobts(struct gsm_bts *bts)
485{
486 /* We don't do callback based bootstrapping, but event driven (see above) */
487}
488
489static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
490{
491 enum abis_nm_chan_comb ccomb = abis_nm_chcomb4pchan(ts->pchan);
492 struct gsm_e1_subslot *e1l = &ts->e1_link;
493
494 abis_nm_set_channel_attr(ts, ccomb);
495
496 if (is_ipaccess_bts(ts->trx->bts))
497 return;
498
499 switch (ts->pchan) {
500 case GSM_PCHAN_TCH_F:
501 case GSM_PCHAN_TCH_H:
502 abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts,
503 e1l->e1_ts_ss);
504 break;
505 default:
506 break;
507 }
508}
509
510static void nm_reconfig_trx(struct gsm_bts_trx *trx)
511{
512 struct gsm_e1_subslot *e1l = &trx->rsl_e1_link;
513 int i;
514
515 patch_nm_tables(trx->bts);
516
517 switch (trx->bts->type) {
518 case GSM_BTS_TYPE_BS11:
519 /* FIXME: discover this by fetching an attribute */
520#if 0
521 trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
522#else
523 trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
524#endif
525 abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
526 e1l->e1_ts_ss);
527 abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
528 e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei);
529
530 /* Set Radio Attributes */
531 if (trx == trx->bts->c0)
532 abis_nm_set_radio_attr(trx, bs11_attr_radio,
533 sizeof(bs11_attr_radio));
534 else {
535 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
536 u_int8_t arfcn_low = trx->arfcn & 0xff;
537 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
538 memcpy(trx1_attr_radio, bs11_attr_radio,
539 sizeof(trx1_attr_radio));
540
541 /* patch ARFCN into TRX Attributes */
542 trx1_attr_radio[2] &= 0xf0;
543 trx1_attr_radio[2] |= arfcn_high;
544 trx1_attr_radio[3] = arfcn_low;
545
546 abis_nm_set_radio_attr(trx, trx1_attr_radio,
547 sizeof(trx1_attr_radio));
548 }
549 break;
Mike Habene2d82272009-10-02 12:19:34 +0100550 case GSM_BTS_TYPE_NANOBTS:
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200551 switch (trx->bts->band) {
552 case GSM_BAND_850:
553 case GSM_BAND_900:
554 trx->nominal_power = 20;
555 break;
556 case GSM_BAND_1800:
557 case GSM_BAND_1900:
558 trx->nominal_power = 23;
559 break;
Holger Hans Peter Freyther555eba12009-10-22 15:46:16 +0200560 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100561 LOGP(DNM, LOGL_ERROR, "Unsupported nanoBTS GSM band %s\n",
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200562 gsm_band_name(trx->bts->band));
563 break;
564 }
565 break;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200566 default:
567 break;
568 }
569
570 for (i = 0; i < TRX_NR_TS; i++)
571 nm_reconfig_ts(&trx->ts[i]);
572}
573
574static void nm_reconfig_bts(struct gsm_bts *bts)
575{
576 struct gsm_bts_trx *trx;
577
578 switch (bts->type) {
579 case GSM_BTS_TYPE_BS11:
Harald Welteade7a142009-12-14 17:49:52 +0100580 patch_nm_tables(bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200581 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
582 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
583 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
584 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
585 break;
586 default:
587 break;
588 }
589
590 llist_for_each_entry(trx, &bts->trx_list, list)
591 nm_reconfig_trx(trx);
592}
593
594static void bootstrap_om_bs11(struct gsm_bts *bts)
595{
596 /* stop sending event reports */
597 abis_nm_event_reports(bts, 0);
598
599 /* begin DB transmission */
600 abis_nm_bs11_db_transmission(bts, 1);
601
602 /* end DB transmission */
603 abis_nm_bs11_db_transmission(bts, 0);
604
605 /* Reset BTS Site manager resource */
606 abis_nm_bs11_reset_resource(bts);
607
608 /* begin DB transmission */
609 abis_nm_bs11_db_transmission(bts, 1);
610
611 /* reconfigure BTS with all TRX and all TS */
612 nm_reconfig_bts(bts);
613
614 /* end DB transmission */
615 abis_nm_bs11_db_transmission(bts, 0);
616
617 /* Reset BTS Site manager resource */
618 abis_nm_bs11_reset_resource(bts);
619
620 /* restart sending event reports */
621 abis_nm_event_reports(bts, 1);
622}
623
624static void bootstrap_om(struct gsm_bts *bts)
625{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100626 LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200627
628 switch (bts->type) {
629 case GSM_BTS_TYPE_BS11:
630 bootstrap_om_bs11(bts);
631 break;
Mike Habene2d82272009-10-02 12:19:34 +0100632 case GSM_BTS_TYPE_NANOBTS:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200633 bootstrap_om_nanobts(bts);
634 break;
635 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100636 LOGP(DNM, LOGL_ERROR, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200637 }
638}
639
640static int shutdown_om(struct gsm_bts *bts)
641{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100642 LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200643
644 /* stop sending event reports */
645 abis_nm_event_reports(bts, 0);
646
647 /* begin DB transmission */
648 abis_nm_bs11_db_transmission(bts, 1);
649
650 /* end DB transmission */
651 abis_nm_bs11_db_transmission(bts, 0);
652
653 /* Reset BTS Site manager resource */
654 abis_nm_bs11_reset_resource(bts);
655
656 return 0;
657}
658
659int bsc_shutdown_net(struct gsm_network *net)
660{
661 struct gsm_bts *bts;
662
663 llist_for_each_entry(bts, &net->bts_list, list) {
664 int rc;
665 rc = shutdown_om(bts);
666 if (rc < 0)
667 return rc;
668 }
669
670 return 0;
671}
672
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200673/* set all system information types */
674static int set_system_infos(struct gsm_bts_trx *trx)
675{
Harald Weltea43f7892009-12-01 18:04:30 +0530676 int i, rc;
677 u_int8_t si_tmp[23];
Harald Welte73d4fce2009-12-21 23:12:19 +0100678 struct gsm_bts *bts = trx->bts;
679
680 bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
681 ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
682 bts->si_common.cell_sel_par.neci = bts->network->neci;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200683
684 if (trx == trx->bts->c0) {
Harald Weltea43f7892009-12-01 18:04:30 +0530685 for (i = 1; i <= 4; i++) {
686 rc = gsm_generate_si(si_tmp, trx->bts, i);
687 if (rc < 0)
688 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100689 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530690 rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200691 }
Harald Weltea43f7892009-12-01 18:04:30 +0530692#ifdef GPRS
Harald Welte9c4f6b52009-12-22 13:16:27 +0100693 i = 13;
Harald Welte6a22c012009-12-21 17:02:32 +0100694 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
695 if (rc < 0)
696 goto err_out;
697 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
698 rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
Harald Weltea43f7892009-12-01 18:04:30 +0530699#endif
Harald Welte6a22c012009-12-21 17:02:32 +0100700 }
701
Harald Welte50e7fec2009-12-19 21:29:00 +0100702 i = 5;
703 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_5);
704 if (rc < 0)
Harald Weltea43f7892009-12-01 18:04:30 +0530705 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100706 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530707 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si_tmp, rc);
708
Harald Welte50e7fec2009-12-19 21:29:00 +0100709 i = 6;
710 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_6);
711 if (rc < 0)
Harald Weltea43f7892009-12-01 18:04:30 +0530712 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100713 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530714 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si_tmp, rc);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200715
716 return 0;
Harald Weltea43f7892009-12-01 18:04:30 +0530717err_out:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100718 LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
Harald Weltea43f7892009-12-01 18:04:30 +0530719 "a problem with neighbor cell list generation\n",
Harald Welte152b6262009-12-16 11:57:48 +0100720 i, trx->bts->nr);
Harald Weltea43f7892009-12-01 18:04:30 +0530721 return rc;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200722}
723
724/*
725 * Patch the various SYSTEM INFORMATION tables to update
726 * the LAI
727 */
728static void patch_nm_tables(struct gsm_bts *bts)
729{
730 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
731 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
732
733 /* patch ARFCN into BTS Attributes */
734 bs11_attr_bts[69] &= 0xf0;
735 bs11_attr_bts[69] |= arfcn_high;
736 bs11_attr_bts[70] = arfcn_low;
737 nanobts_attr_bts[42] &= 0xf0;
738 nanobts_attr_bts[42] |= arfcn_high;
739 nanobts_attr_bts[43] = arfcn_low;
740
741 /* patch ARFCN into TRX Attributes */
742 bs11_attr_radio[2] &= 0xf0;
743 bs11_attr_radio[2] |= arfcn_high;
744 bs11_attr_radio[3] = arfcn_low;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200745
746 /* patch BSIC */
747 bs11_attr_bts[1] = bts->bsic;
748 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
749
750 /* patch the power reduction */
751 bs11_attr_radio[5] = bts->c0->max_power_red / 2;
752 nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
753}
754
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200755static void bootstrap_rsl(struct gsm_bts_trx *trx)
756{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100757 LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte19a3f0b2009-12-24 13:39:34 +0100758 "on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
759 trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
760 bsc_gsmnet->network_code, trx->bts->location_area_code,
761 trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200762 set_system_infos(trx);
763}
764
765void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
766{
767 switch (event) {
768 case EVT_E1_TEI_UP:
769 switch (type) {
770 case E1INP_SIGN_OML:
771 bootstrap_om(trx->bts);
772 break;
773 case E1INP_SIGN_RSL:
774 bootstrap_rsl(trx);
775 break;
776 default:
777 break;
778 }
779 break;
780 case EVT_E1_TEI_DN:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100781 LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200782 /* FIXME: deal with TEI or L1 link loss */
783 break;
784 default:
785 break;
786 }
787}
788
789static int bootstrap_bts(struct gsm_bts *bts)
790{
Mike Habene2d82272009-10-02 12:19:34 +0100791 switch (bts->band) {
792 case GSM_BAND_1800:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200793 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100794 LOGP(DNM, LOGL_ERROR, "GSM1800 channel must be between 512-885.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200795 return -EINVAL;
796 }
797 break;
Mike Habene2d82272009-10-02 12:19:34 +0100798 case GSM_BAND_1900:
799 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 810) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100800 LOGP(DNM, LOGL_ERROR, "GSM1900 channel must be between 512-810.\n");
Mike Habene2d82272009-10-02 12:19:34 +0100801 return -EINVAL;
802 }
803 break;
804 case GSM_BAND_900:
Holger Hans Peter Freytherfb0b6fc2010-02-09 15:44:14 +0100805 if (bts->c0->arfcn < 1 ||
806 (bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
807 bts->c0->arfcn > 1023) {
808 LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200809 return -EINVAL;
810 }
811 break;
Mike Habene2d82272009-10-02 12:19:34 +0100812 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100813 LOGP(DNM, LOGL_ERROR, "Unsupported frequency band.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200814 return -EINVAL;
815 }
816
Harald Welted6aa5242009-12-12 13:44:19 +0100817 if (bts->network->auth_policy == GSM_AUTH_POLICY_ACCEPT_ALL &&
Harald Welte71355012009-12-21 23:08:18 +0100818 !bts->si_common.rach_control.cell_bar)
Harald Weltea992a362009-12-21 23:36:45 +0100819 LOGP(DNM, LOGL_ERROR, "\nWARNING: You are running an 'accept-all' "
Harald Welted6aa5242009-12-12 13:44:19 +0100820 "network on a BTS that is not barred. This "
821 "configuration is likely to interfere with production "
822 "GSM networks and should only be used in a RF "
823 "shielded environment such as a faraday cage!\n\n");
824
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200825 /* Control Channel Description */
Harald Weltea43f7892009-12-01 18:04:30 +0530826 bts->si_common.chan_desc.att = 1;
827 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
828 bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200829 /* T3212 is set from vty/config */
830
Harald Weltea43f7892009-12-01 18:04:30 +0530831 /* some defaults for our system information */
Harald Weltea43f7892009-12-01 18:04:30 +0530832 bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
833 bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
834 bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
835
Harald Weltea43f7892009-12-01 18:04:30 +0530836 bts->si_common.cell_sel_par.acs = 0;
Harald Weltea43f7892009-12-01 18:04:30 +0530837
838 bts->si_common.ncc_permitted = 0xff;
839
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200840 paging_init(bts);
841
842 return 0;
843}
844
845int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
846 const char *config_file)
847{
848 struct gsm_bts *bts;
849 int rc;
850
851 /* initialize our data structures */
852 bsc_gsmnet = gsm_network_init(1, 1, mncc_recv);
853 if (!bsc_gsmnet)
854 return -ENOMEM;
855
856 bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
857 bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
858
859 telnet_init(bsc_gsmnet, 4242);
860 rc = vty_read_config_file(config_file);
861 if (rc < 0) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100862 LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200863 return rc;
864 }
865
866 register_signal_handler(SS_NM, nm_sig_cb, NULL);
867
868 llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
869 bootstrap_bts(bts);
870 if (!is_ipaccess_bts(bts))
871 rc = e1_reconfig_bts(bts);
872
873 if (rc < 0)
874 exit (1);
875 }
876
877 /* initialize nanoBTS support omce */
878 rc = ipaccess_setup(bsc_gsmnet);
879
880 return 0;
881}