blob: 9bc02c486cba219447c80c93c9db003bc54f6508 [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>
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +020034#include <openbsc/chan_alloc.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010035#include <osmocore/talloc.h>
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020036
37/* global pointer to the gsm network data structure */
38extern struct gsm_network *bsc_gsmnet;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020039
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,
Harald Welte97a282b2010-03-14 15:37:43 +0800334 NM_ATT_IPACC_CGI, 0, 7, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00,
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200335};
336
337static unsigned char nanobts_attr_radio[] = {
338 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
339 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
340};
341
Harald Welte97a282b2010-03-14 15:37:43 +0800342static unsigned char nanobts_attr_nse[] = {
343 NM_ATT_IPACC_NSEI, 0, 2, 0x03, 0x9d, /* NSEI 925 */
344 NM_ATT_IPACC_NS_CFG, 0, 7, 3, /* (un)blocking timer (Tns-block) */
345 3, /* (un)blocking retries */
346 3, /* reset timer (Tns-reset) */
347 3, /* reset retries */
348 30, /* test timer (Tns-test) */
349 3, /* alive timer (Tns-alive) */
350 10, /* alive retrires */
351 NM_ATT_IPACC_BSSGP_CFG, 0, 11,
352 3, /* blockimg timer (T1) */
353 3, /* blocking retries */
354 3, /* unblocking retries */
355 3, /* reset timer */
356 3, /* reset retries */
357 10, /* suspend timer (T3) in 100ms */
358 3, /* suspend retries */
359 10, /* resume timer (T4) in 100ms */
360 3, /* resume retries */
361 10, /* capability update timer (T5) */
362 3, /* capability update retries */
363};
364
365static unsigned char nanobts_attr_cell[] = {
366 NM_ATT_IPACC_RAC, 0, 1, 1, /* routing area code */
367 NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2,
368 5, /* repeat time (50ms) */
369 3, /* repeat count */
370 NM_ATT_IPACC_BVCI, 0, 2, 0x03, 0x9d, /* BVCI 925 */
371 NM_ATT_IPACC_RLC_CFG, 0, 9,
372 20, /* T3142 */
373 5, /* T3169 */
374 5, /* T3191 */
375 200, /* T3193 */
376 5, /* T3195 */
377 10, /* N3101 */
378 4, /* N3103 */
379 8, /* N3105 */
380 15, /* RLC CV countdown */
Harald Welte439bb822010-04-18 16:50:11 +0200381 NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00, /* CS1..CS4 */
Harald Welte97a282b2010-03-14 15:37:43 +0800382 NM_ATT_IPACC_RLC_CFG_2, 0, 5,
Harald Welte439bb822010-04-18 16:50:11 +0200383 0x00, 250, /* T downlink TBF extension (0..500) */
384 0x00, 250, /* T uplink TBF extension (0..500) */
385 2, /* CS2 */
Harald Welte97a282b2010-03-14 15:37:43 +0800386#if 0
387 /* EDGE model only, breaks older models.
388 * Should inquire the BTS capabilities */
389 NM_ATT_IPACC_RLC_CFG_3, 0, 1,
390 2, /* MCS2 */
391#endif
392};
393
394static unsigned char nanobts_attr_nsvc0[] = {
395 NM_ATT_IPACC_NSVCI, 0, 2, 0x03, 0x9d, /* 925 */
396 NM_ATT_IPACC_NS_LINK_CFG, 0, 8,
397 0x59, 0xd8, /* remote udp port (23000) */
398 192, 168, 100, 11, /* remote ip address */
399 0x59, 0xd8, /* local udp port (23000) */
400};
401
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200402/* Callback function to be called whenever we get a GSM 12.21 state change event */
403int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
404 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
405{
406 struct gsm_bts *bts;
407 struct gsm_bts_trx *trx;
408 struct gsm_bts_trx_ts *ts;
Harald Welte97a282b2010-03-14 15:37:43 +0800409 struct gsm_bts_gprs_nsvc *nsvc;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200410
Harald Welte8406ec22009-10-20 17:31:00 +0200411 /* This event-driven BTS setup is currently only required on nanoBTS */
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200412
Harald Welte8406ec22009-10-20 17:31:00 +0200413 /* EVT_STATECHG_ADM is called after we call chg_adm_state() and would create
414 * endless loop */
415 if (evt != EVT_STATECHG_OPER)
416 return 0;
417
418 switch (obj_class) {
419 case NM_OC_SITE_MANAGER:
420 bts = container_of(obj, struct gsm_bts, site_mgr);
Sylvain Munaut7de67962009-12-18 17:45:45 +0100421 if ((new_state->operational == 2 &&
422 new_state->availability == NM_AVSTATE_OK) ||
423 (new_state->operational == 1 &&
424 new_state->availability == NM_AVSTATE_OFF_LINE))
Harald Welte8406ec22009-10-20 17:31:00 +0200425 abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
426 break;
427 case NM_OC_BTS:
428 bts = obj;
429 if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
430 patch_nm_tables(bts);
431 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
432 sizeof(nanobts_attr_bts));
433 abis_nm_chg_adm_state(bts, obj_class,
434 bts->bts_nr, 0xff, 0xff,
435 NM_STATE_UNLOCKED);
436 abis_nm_opstart(bts, obj_class,
437 bts->bts_nr, 0xff, 0xff);
438 }
439 break;
440 case NM_OC_CHANNEL:
441 ts = obj;
442 trx = ts->trx;
443 if (new_state->operational == 1 &&
444 new_state->availability == NM_AVSTATE_DEPENDENCY) {
Harald Welte65bdc912009-10-26 20:14:33 +0100445 patch_nm_tables(trx->bts);
Harald Welte0f890b02009-10-24 09:09:05 +0200446 enum abis_nm_chan_comb ccomb =
447 abis_nm_chcomb4pchan(ts->pchan);
448 abis_nm_set_channel_attr(ts, ccomb);
Harald Welte8406ec22009-10-20 17:31:00 +0200449 abis_nm_chg_adm_state(trx->bts, obj_class,
450 trx->bts->bts_nr, trx->nr, ts->nr,
451 NM_STATE_UNLOCKED);
452 abis_nm_opstart(trx->bts, obj_class,
453 trx->bts->bts_nr, trx->nr, ts->nr);
454 }
455 break;
456 case NM_OC_RADIO_CARRIER:
457 trx = obj;
458 if (new_state->operational == 1 &&
Harald Welte8406ec22009-10-20 17:31:00 +0200459 new_state->availability == NM_AVSTATE_OK)
460 abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
461 trx->nr, 0xff);
462 break;
Harald Welte97a282b2010-03-14 15:37:43 +0800463 case NM_OC_GPRS_NSE:
464 bts = container_of(obj, struct gsm_bts, gprs.nse);
Harald Welte4511d892010-04-18 15:51:20 +0200465 if (bts->gprs.mode == BTS_GPRS_NONE)
Harald Weltefa586252010-03-14 23:33:36 +0800466 break;
Harald Welte97a282b2010-03-14 15:37:43 +0800467 if (new_state->availability == 5) {
468 abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
469 0xff, 0xff, nanobts_attr_nse,
470 sizeof(nanobts_attr_nse));
471 abis_nm_opstart(bts, obj_class, bts->bts_nr,
472 0xff, 0xff);
473 abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
474 0xff, 0xff, NM_STATE_UNLOCKED);
475 }
476 break;
477 case NM_OC_GPRS_CELL:
478 bts = container_of(obj, struct gsm_bts, gprs.cell);
Harald Welte4511d892010-04-18 15:51:20 +0200479 if (bts->gprs.mode == BTS_GPRS_NONE)
Harald Weltefa586252010-03-14 23:33:36 +0800480 break;
Harald Welte97a282b2010-03-14 15:37:43 +0800481 if (new_state->availability == 5) {
482 abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
483 0, 0xff, nanobts_attr_cell,
484 sizeof(nanobts_attr_cell));
485 abis_nm_opstart(bts, obj_class, bts->bts_nr,
486 0, 0xff);
487 abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
488 0, 0xff, NM_STATE_UNLOCKED);
489 }
490 break;
491 case NM_OC_GPRS_NSVC:
492 nsvc = obj;
493 bts = nsvc->bts;
Harald Welte4511d892010-04-18 15:51:20 +0200494 if (bts->gprs.mode == BTS_GPRS_NONE)
Harald Weltefa586252010-03-14 23:33:36 +0800495 break;
Holger Hans Peter Freythera5811362010-04-30 13:32:05 +0800496 /* We skip NSVC1 since we only use NSVC0 */
Harald Welte97a282b2010-03-14 15:37:43 +0800497 if (nsvc->id == 1)
498 break;
499 if (new_state->availability == NM_AVSTATE_OFF_LINE) {
500 abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
501 nsvc->id, 0xff,
502 nanobts_attr_nsvc0,
503 sizeof(nanobts_attr_nsvc0));
504 abis_nm_opstart(bts, obj_class, bts->bts_nr,
505 nsvc->id, 0xff);
506 abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
507 nsvc->id, 0xff,
508 NM_STATE_UNLOCKED);
509 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200510 default:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200511 break;
512 }
513 return 0;
514}
515
516/* Callback function to be called every time we receive a 12.21 SW activated report */
517static int sw_activ_rep(struct msgb *mb)
518{
519 struct abis_om_fom_hdr *foh = msgb_l3(mb);
Harald Welted004a642009-10-19 21:47:54 +0200520 struct gsm_bts *bts = mb->trx->bts;
521 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
522
Harald Welteb7bcb792009-12-23 18:24:31 +0100523 if (!trx)
524 return -EINVAL;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200525
526 switch (foh->obj_class) {
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100527 case NM_OC_BASEB_TRANSC:
528 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
529 trx->bts->bts_nr, trx->nr, 0xff,
530 NM_STATE_UNLOCKED);
531 abis_nm_opstart(trx->bts, foh->obj_class,
532 trx->bts->bts_nr, trx->nr, 0xff);
533 /* TRX software is active, tell it to initiate RSL Link */
534 abis_nm_ipaccess_rsl_connect(trx, 0, 3003, trx->rsl_tei);
535 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100536 case NM_OC_RADIO_CARRIER: {
537 /*
538 * Locking the radio carrier will make it go
539 * offline again and we would come here. The
540 * framework should determine that there was
541 * no change and avoid recursion.
542 *
543 * This code is here to make sure that on start
544 * a TRX remains locked.
545 */
Holger Hans Peter Freytherf31e4742009-12-31 03:05:52 +0100546 int rc_state = trx->nm_state.administrative;
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100547 /* Patch ARFCN into radio attribute */
548 nanobts_attr_radio[5] &= 0xf0;
549 nanobts_attr_radio[5] |= trx->arfcn >> 8;
550 nanobts_attr_radio[6] = trx->arfcn & 0xff;
551 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
552 sizeof(nanobts_attr_radio));
553 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
554 trx->bts->bts_nr, trx->nr, 0xff,
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100555 rc_state);
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100556 abis_nm_opstart(trx->bts, foh->obj_class, trx->bts->bts_nr,
557 trx->nr, 0xff);
558 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100559 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200560 }
561 return 0;
562}
563
564/* Callback function for NACK on the OML NM */
Harald Welted8cfc902009-11-17 06:09:56 +0100565static int oml_msg_nack(u_int8_t mt)
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200566{
567 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100568 LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200569 "Was the bts type and frequency properly specified?\n");
570 exit(-1);
571 }
572
573 return 0;
574}
575
576/* Callback function to be called every time we receive a signal from NM */
577static int nm_sig_cb(unsigned int subsys, unsigned int signal,
578 void *handler_data, void *signal_data)
579{
Harald Welted8cfc902009-11-17 06:09:56 +0100580 u_int8_t *msg_type;
581
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200582 switch (signal) {
583 case S_NM_SW_ACTIV_REP:
584 return sw_activ_rep(signal_data);
585 case S_NM_NACK:
Harald Welted8cfc902009-11-17 06:09:56 +0100586 msg_type = signal_data;
587 return oml_msg_nack(*msg_type);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200588 default:
589 break;
590 }
591 return 0;
592}
593
594static void bootstrap_om_nanobts(struct gsm_bts *bts)
595{
596 /* We don't do callback based bootstrapping, but event driven (see above) */
597}
598
599static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
600{
601 enum abis_nm_chan_comb ccomb = abis_nm_chcomb4pchan(ts->pchan);
602 struct gsm_e1_subslot *e1l = &ts->e1_link;
603
604 abis_nm_set_channel_attr(ts, ccomb);
605
606 if (is_ipaccess_bts(ts->trx->bts))
607 return;
608
609 switch (ts->pchan) {
610 case GSM_PCHAN_TCH_F:
611 case GSM_PCHAN_TCH_H:
612 abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts,
613 e1l->e1_ts_ss);
614 break;
615 default:
616 break;
617 }
618}
619
620static void nm_reconfig_trx(struct gsm_bts_trx *trx)
621{
622 struct gsm_e1_subslot *e1l = &trx->rsl_e1_link;
623 int i;
624
625 patch_nm_tables(trx->bts);
626
627 switch (trx->bts->type) {
628 case GSM_BTS_TYPE_BS11:
629 /* FIXME: discover this by fetching an attribute */
630#if 0
631 trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
632#else
633 trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
634#endif
635 abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
636 e1l->e1_ts_ss);
637 abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
638 e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei);
639
640 /* Set Radio Attributes */
641 if (trx == trx->bts->c0)
642 abis_nm_set_radio_attr(trx, bs11_attr_radio,
643 sizeof(bs11_attr_radio));
644 else {
645 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
646 u_int8_t arfcn_low = trx->arfcn & 0xff;
647 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
648 memcpy(trx1_attr_radio, bs11_attr_radio,
649 sizeof(trx1_attr_radio));
650
651 /* patch ARFCN into TRX Attributes */
652 trx1_attr_radio[2] &= 0xf0;
653 trx1_attr_radio[2] |= arfcn_high;
654 trx1_attr_radio[3] = arfcn_low;
655
656 abis_nm_set_radio_attr(trx, trx1_attr_radio,
657 sizeof(trx1_attr_radio));
658 }
659 break;
Mike Habene2d82272009-10-02 12:19:34 +0100660 case GSM_BTS_TYPE_NANOBTS:
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200661 switch (trx->bts->band) {
662 case GSM_BAND_850:
663 case GSM_BAND_900:
664 trx->nominal_power = 20;
665 break;
666 case GSM_BAND_1800:
667 case GSM_BAND_1900:
668 trx->nominal_power = 23;
669 break;
Holger Hans Peter Freyther555eba12009-10-22 15:46:16 +0200670 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100671 LOGP(DNM, LOGL_ERROR, "Unsupported nanoBTS GSM band %s\n",
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200672 gsm_band_name(trx->bts->band));
673 break;
674 }
675 break;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200676 default:
677 break;
678 }
679
680 for (i = 0; i < TRX_NR_TS; i++)
681 nm_reconfig_ts(&trx->ts[i]);
682}
683
684static void nm_reconfig_bts(struct gsm_bts *bts)
685{
686 struct gsm_bts_trx *trx;
687
688 switch (bts->type) {
689 case GSM_BTS_TYPE_BS11:
Harald Welteade7a142009-12-14 17:49:52 +0100690 patch_nm_tables(bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200691 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
692 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
693 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
694 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
695 break;
696 default:
697 break;
698 }
699
700 llist_for_each_entry(trx, &bts->trx_list, list)
701 nm_reconfig_trx(trx);
702}
703
704static void bootstrap_om_bs11(struct gsm_bts *bts)
705{
706 /* stop sending event reports */
707 abis_nm_event_reports(bts, 0);
708
709 /* begin DB transmission */
710 abis_nm_bs11_db_transmission(bts, 1);
711
712 /* end DB transmission */
713 abis_nm_bs11_db_transmission(bts, 0);
714
715 /* Reset BTS Site manager resource */
716 abis_nm_bs11_reset_resource(bts);
717
718 /* begin DB transmission */
719 abis_nm_bs11_db_transmission(bts, 1);
720
721 /* reconfigure BTS with all TRX and all TS */
722 nm_reconfig_bts(bts);
723
724 /* end DB transmission */
725 abis_nm_bs11_db_transmission(bts, 0);
726
727 /* Reset BTS Site manager resource */
728 abis_nm_bs11_reset_resource(bts);
729
730 /* restart sending event reports */
731 abis_nm_event_reports(bts, 1);
732}
733
734static void bootstrap_om(struct gsm_bts *bts)
735{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100736 LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200737
738 switch (bts->type) {
739 case GSM_BTS_TYPE_BS11:
740 bootstrap_om_bs11(bts);
741 break;
Mike Habene2d82272009-10-02 12:19:34 +0100742 case GSM_BTS_TYPE_NANOBTS:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200743 bootstrap_om_nanobts(bts);
744 break;
745 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100746 LOGP(DNM, LOGL_ERROR, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200747 }
748}
749
750static int shutdown_om(struct gsm_bts *bts)
751{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100752 LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200753
754 /* stop sending event reports */
755 abis_nm_event_reports(bts, 0);
756
757 /* begin DB transmission */
758 abis_nm_bs11_db_transmission(bts, 1);
759
760 /* end DB transmission */
761 abis_nm_bs11_db_transmission(bts, 0);
762
763 /* Reset BTS Site manager resource */
764 abis_nm_bs11_reset_resource(bts);
765
766 return 0;
767}
768
769int bsc_shutdown_net(struct gsm_network *net)
770{
771 struct gsm_bts *bts;
772
773 llist_for_each_entry(bts, &net->bts_list, list) {
774 int rc;
775 rc = shutdown_om(bts);
776 if (rc < 0)
777 return rc;
778 }
779
780 return 0;
781}
782
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200783/* set all system information types */
784static int set_system_infos(struct gsm_bts_trx *trx)
785{
Harald Weltea43f7892009-12-01 18:04:30 +0530786 int i, rc;
787 u_int8_t si_tmp[23];
Harald Welte73d4fce2009-12-21 23:12:19 +0100788 struct gsm_bts *bts = trx->bts;
789
790 bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
791 ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
792 bts->si_common.cell_sel_par.neci = bts->network->neci;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200793
794 if (trx == trx->bts->c0) {
Harald Weltea43f7892009-12-01 18:04:30 +0530795 for (i = 1; i <= 4; i++) {
796 rc = gsm_generate_si(si_tmp, trx->bts, i);
797 if (rc < 0)
798 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100799 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530800 rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200801 }
Harald Welte4511d892010-04-18 15:51:20 +0200802 if (bts->gprs.mode != BTS_GPRS_NONE) {
Harald Weltefa586252010-03-14 23:33:36 +0800803 i = 13;
804 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
805 if (rc < 0)
806 goto err_out;
807 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
808 rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
809 }
Harald Welte6a22c012009-12-21 17:02:32 +0100810 }
811
Harald Welte50e7fec2009-12-19 21:29:00 +0100812 i = 5;
813 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_5);
814 if (rc < 0)
Harald Weltea43f7892009-12-01 18:04:30 +0530815 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100816 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530817 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si_tmp, rc);
818
Harald Welte50e7fec2009-12-19 21:29:00 +0100819 i = 6;
820 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_6);
821 if (rc < 0)
Harald Weltea43f7892009-12-01 18:04:30 +0530822 goto err_out;
Harald Welte50e7fec2009-12-19 21:29:00 +0100823 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea43f7892009-12-01 18:04:30 +0530824 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si_tmp, rc);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200825
826 return 0;
Harald Weltea43f7892009-12-01 18:04:30 +0530827err_out:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100828 LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
Harald Weltea43f7892009-12-01 18:04:30 +0530829 "a problem with neighbor cell list generation\n",
Harald Welte152b6262009-12-16 11:57:48 +0100830 i, trx->bts->nr);
Harald Weltea43f7892009-12-01 18:04:30 +0530831 return rc;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200832}
833
834/*
835 * Patch the various SYSTEM INFORMATION tables to update
836 * the LAI
837 */
838static void patch_nm_tables(struct gsm_bts *bts)
839{
840 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
841 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
842
843 /* patch ARFCN into BTS Attributes */
844 bs11_attr_bts[69] &= 0xf0;
845 bs11_attr_bts[69] |= arfcn_high;
846 bs11_attr_bts[70] = arfcn_low;
847 nanobts_attr_bts[42] &= 0xf0;
848 nanobts_attr_bts[42] |= arfcn_high;
849 nanobts_attr_bts[43] = arfcn_low;
850
851 /* patch ARFCN into TRX Attributes */
852 bs11_attr_radio[2] &= 0xf0;
853 bs11_attr_radio[2] |= arfcn_high;
854 bs11_attr_radio[3] = arfcn_low;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200855
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800856 /* patch the RACH attributes */
857 if (bts->rach_b_thresh != -1) {
858 nanobts_attr_bts[33] = bts->rach_b_thresh & 0xff;
859 bs11_attr_bts[33] = bts->rach_b_thresh & 0xff;
860 }
861
862 if (bts->rach_ldavg_slots != -1) {
863 u_int8_t avg_high = bts->rach_ldavg_slots & 0xff;
864 u_int8_t avg_low = (bts->rach_ldavg_slots >> 8) & 0x0f;
865
866 nanobts_attr_bts[35] = avg_high;
867 nanobts_attr_bts[36] = avg_low;
868 bs11_attr_bts[35] = avg_high;
869 bs11_attr_bts[36] = avg_low;
870 }
871
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200872 /* patch BSIC */
873 bs11_attr_bts[1] = bts->bsic;
Harald Welte97a282b2010-03-14 15:37:43 +0800874 nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;
875
876 /* patch CGI */
877 abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200878
879 /* patch the power reduction */
880 bs11_attr_radio[5] = bts->c0->max_power_red / 2;
881 nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
Harald Welte97a282b2010-03-14 15:37:43 +0800882
Harald Weltea5731cf2010-03-22 11:48:36 +0800883 /* patch NSEI */
884 nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8;
885 nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff;
886
Harald Welte97a282b2010-03-14 15:37:43 +0800887 /* patch NSVCI */
888 nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
889 nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;
890
Harald Welteaf387632010-03-14 23:30:30 +0800891 /* patch IP address as SGSN IP */
892 *(u_int16_t *)(nanobts_attr_nsvc0+8) =
893 htons(bts->gprs.nsvc[0].remote_port);
894 *(u_int32_t *)(nanobts_attr_nsvc0+10) =
895 htonl(bts->gprs.nsvc[0].remote_ip);
896 *(u_int16_t *)(nanobts_attr_nsvc0+14) =
897 htons(bts->gprs.nsvc[0].local_port);
Harald Welte97a282b2010-03-14 15:37:43 +0800898
899 /* patch BVCI */
900 nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
901 nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
902 /* patch RAC */
903 nanobts_attr_cell[3] = bts->gprs.rac;
904
Harald Welte439bb822010-04-18 16:50:11 +0200905 if (bts->gprs.mode == BTS_GPRS_EGPRS) {
906 /* patch EGPRS coding schemes MCS 1..9 */
907 nanobts_attr_cell[29] = 0x8f;
908 nanobts_attr_cell[30] = 0xff;
909 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200910}
911
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200912static void bootstrap_rsl(struct gsm_bts_trx *trx)
913{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100914 LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte19a3f0b2009-12-24 13:39:34 +0100915 "on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
916 trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
917 bsc_gsmnet->network_code, trx->bts->location_area_code,
918 trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200919 set_system_infos(trx);
920}
921
922void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
923{
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +0200924 int ts_no, lchan_no;
925
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200926 switch (event) {
927 case EVT_E1_TEI_UP:
928 switch (type) {
929 case E1INP_SIGN_OML:
930 bootstrap_om(trx->bts);
931 break;
932 case E1INP_SIGN_RSL:
933 bootstrap_rsl(trx);
934 break;
935 default:
936 break;
937 }
938 break;
939 case EVT_E1_TEI_DN:
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +0200940 LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx);
941
Holger Hans Peter Freytherbb110f92010-04-12 10:45:52 +0200942 if (type == E1INP_SIGN_OML)
943 counter_inc(trx->bts->network->stats.bts.oml_fail);
944 else if (type == E1INP_SIGN_RSL)
945 counter_inc(trx->bts->network->stats.bts.rsl_fail);
946
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +0200947 /*
948 * free all allocated channels. change the nm_state so the
949 * trx and trx_ts becomes unusable and chan_alloc.c can not
950 * allocate from it.
951 */
952 for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
953 struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
954
955 for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
956 if (ts->lchan[lchan_no].state != GSM_LCHAN_NONE)
957 lchan_free(&ts->lchan[lchan_no]);
958 lchan_reset(&ts->lchan[lchan_no]);
959 }
960
961 ts->nm_state.operational = 0;
962 ts->nm_state.availability = 0;
963 }
964
965 trx->nm_state.operational = 0;
966 trx->nm_state.availability = 0;
967 trx->bb_transc.nm_state.operational = 0;
968 trx->bb_transc.nm_state.availability = 0;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200969 break;
970 default:
971 break;
972 }
973}
974
975static int bootstrap_bts(struct gsm_bts *bts)
976{
Sylvain Munaut50f81b02010-04-28 21:31:29 +0200977 int i, n;
978
Mike Habene2d82272009-10-02 12:19:34 +0100979 switch (bts->band) {
980 case GSM_BAND_1800:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200981 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100982 LOGP(DNM, LOGL_ERROR, "GSM1800 channel must be between 512-885.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200983 return -EINVAL;
984 }
985 break;
Mike Habene2d82272009-10-02 12:19:34 +0100986 case GSM_BAND_1900:
987 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 810) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100988 LOGP(DNM, LOGL_ERROR, "GSM1900 channel must be between 512-810.\n");
Mike Habene2d82272009-10-02 12:19:34 +0100989 return -EINVAL;
990 }
991 break;
992 case GSM_BAND_900:
Holger Hans Peter Freytherfb0b6fc2010-02-09 15:44:14 +0100993 if (bts->c0->arfcn < 1 ||
994 (bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
995 bts->c0->arfcn > 1023) {
996 LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200997 return -EINVAL;
998 }
999 break;
Mike Habene2d82272009-10-02 12:19:34 +01001000 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001001 LOGP(DNM, LOGL_ERROR, "Unsupported frequency band.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001002 return -EINVAL;
1003 }
1004
Harald Welted6aa5242009-12-12 13:44:19 +01001005 if (bts->network->auth_policy == GSM_AUTH_POLICY_ACCEPT_ALL &&
Harald Welte71355012009-12-21 23:08:18 +01001006 !bts->si_common.rach_control.cell_bar)
Harald Weltea992a362009-12-21 23:36:45 +01001007 LOGP(DNM, LOGL_ERROR, "\nWARNING: You are running an 'accept-all' "
Harald Welted6aa5242009-12-12 13:44:19 +01001008 "network on a BTS that is not barred. This "
1009 "configuration is likely to interfere with production "
1010 "GSM networks and should only be used in a RF "
1011 "shielded environment such as a faraday cage!\n\n");
1012
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001013 /* Control Channel Description */
Harald Weltea43f7892009-12-01 18:04:30 +05301014 bts->si_common.chan_desc.att = 1;
Harald Weltea43f7892009-12-01 18:04:30 +05301015 bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
Holger Hans Peter Freythera5811362010-04-30 13:32:05 +08001016 /* T3212 is set from vty/config */
Sylvain Munaut50f81b02010-04-28 21:31:29 +02001017
Holger Hans Peter Freythera5811362010-04-30 13:32:05 +08001018 /* Set ccch config by looking at ts config */
Sylvain Munaut50f81b02010-04-28 21:31:29 +02001019 for (n=0, i=0; i<8; i++)
1020 n += bts->c0->ts[i].pchan == GSM_PCHAN_CCCH ? 1 : 0;
1021
1022 switch (n) {
1023 case 0:
1024 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1025 break;
1026 case 1:
1027 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_NC;
1028 break;
1029 case 2:
1030 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_2_NC;
1031 break;
1032 case 3:
1033 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_3_NC;
1034 break;
1035 case 4:
1036 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_4_NC;
1037 break;
1038 default:
1039 LOGP(DNM, LOGL_ERROR, "Unsupported CCCH timeslot configuration\n");
1040 return -EINVAL;
1041 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001042
Harald Weltea43f7892009-12-01 18:04:30 +05301043 /* some defaults for our system information */
Harald Weltea43f7892009-12-01 18:04:30 +05301044 bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
1045 bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
1046 bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
1047
Harald Weltea43f7892009-12-01 18:04:30 +05301048 bts->si_common.cell_sel_par.acs = 0;
Harald Weltea43f7892009-12-01 18:04:30 +05301049
1050 bts->si_common.ncc_permitted = 0xff;
1051
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001052 paging_init(bts);
1053
1054 return 0;
1055}
1056
1057int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
1058 const char *config_file)
1059{
1060 struct gsm_bts *bts;
1061 int rc;
1062
1063 /* initialize our data structures */
1064 bsc_gsmnet = gsm_network_init(1, 1, mncc_recv);
1065 if (!bsc_gsmnet)
1066 return -ENOMEM;
1067
1068 bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
1069 bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
1070
1071 telnet_init(bsc_gsmnet, 4242);
1072 rc = vty_read_config_file(config_file);
1073 if (rc < 0) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001074 LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001075 return rc;
1076 }
1077
1078 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1079
1080 llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
1081 bootstrap_bts(bts);
1082 if (!is_ipaccess_bts(bts))
1083 rc = e1_reconfig_bts(bts);
1084
1085 if (rc < 0)
1086 exit (1);
1087 }
1088
1089 /* initialize nanoBTS support omce */
1090 rc = ipaccess_setup(bsc_gsmnet);
1091
1092 return 0;
1093}