blob: 824820439f121db443d513700b7ba8e3355d13e3 [file] [log] [blame]
Holger Hans Peter Freythercad370f2009-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
Harald Welte3055e332010-03-14 15:37:43 +080023#define GPRS
24
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +020025#include <openbsc/gsm_data.h>
Harald Weltef4625b12010-02-20 16:24:02 +010026#include <osmocore/gsm_utils.h>
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +020027#include <openbsc/gsm_04_08.h>
28#include <openbsc/abis_rsl.h>
29#include <openbsc/abis_nm.h>
30#include <openbsc/debug.h>
31#include <openbsc/misdn.h>
32#include <openbsc/telnet_interface.h>
Harald Weltea54a2bb2009-12-01 18:04:30 +053033#include <openbsc/system_information.h>
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +020034#include <openbsc/paging.h>
35#include <openbsc/signal.h>
Harald Weltef4625b12010-02-20 16:24:02 +010036#include <osmocore/talloc.h>
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +020037
38/* global pointer to the gsm network data structure */
39extern struct gsm_network *bsc_gsmnet;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +020040
41static void patch_nm_tables(struct gsm_bts *bts);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +020042
43/* The following definitions are for OM and NM packets that we cannot yet
44 * generate by code but we just pass on */
45
46// BTS Site Manager, SET ATTRIBUTES
47
48/*
49 Object Class: BTS Site Manager
50 Instance 1: FF
51 Instance 2: FF
52 Instance 3: FF
53SET ATTRIBUTES
54 sAbisExternalTime: 2007/09/08 14:36:11
55 omLAPDRelTimer: 30sec
56 shortLAPDIntTimer: 5sec
57 emergencyTimer1: 10 minutes
58 emergencyTimer2: 0 minutes
59*/
60
61unsigned char msg_1[] =
62{
63 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
64 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
65 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
66 0x02,
67 0x00, 0x1E,
68 NM_ATT_BS11_SH_LAPD_INT_TIMER,
69 0x01, 0x05,
70 0x42, 0x02, 0x00, 0x0A,
71 0x44, 0x02, 0x00, 0x00
72};
73
74// BTS, SET BTS ATTRIBUTES
75
76/*
77 Object Class: BTS
78 BTS relat. Number: 0
79 Instance 2: FF
80 Instance 3: FF
81SET BTS ATTRIBUTES
82 bsIdentityCode / BSIC:
83 PLMN_colour_code: 7h
84 BS_colour_code: 7h
85 BTS Air Timer T3105: 4 ,unit 10 ms
86 btsIsHopping: FALSE
87 periodCCCHLoadIndication: 1sec
88 thresholdCCCHLoadIndication: 0%
89 cellAllocationNumber: 00h = GSM 900
90 enableInterferenceClass: 00h = Disabled
91 fACCHQual: 6 (FACCH stealing flags minus 1)
92 intaveParameter: 31 SACCH multiframes
93 interferenceLevelBoundaries:
94 Interference Boundary 1: 0Ah
95 Interference Boundary 2: 0Fh
96 Interference Boundary 3: 14h
97 Interference Boundary 4: 19h
98 Interference Boundary 5: 1Eh
99 mSTxPwrMax: 11
100 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
101 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
102 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
103 30=33dBm, 31=32dBm
104 ny1:
105 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
106 powerOutputThresholds:
107 Out Power Fault Threshold: -10 dB
108 Red Out Power Threshold: - 6 dB
109 Excessive Out Power Threshold: 5 dB
110 rACHBusyThreshold: -127 dBm
111 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
112 rfResourceIndicationPeriod: 125 SACCH multiframes
113 T200:
114 SDCCH: 044 in 5 ms
115 FACCH/Full rate: 031 in 5 ms
116 FACCH/Half rate: 041 in 5 ms
117 SACCH with TCH SAPI0: 090 in 10 ms
118 SACCH with SDCCH: 090 in 10 ms
119 SDCCH with SAPI3: 090 in 5 ms
120 SACCH with TCH SAPI3: 135 in 10 ms
121 tSync: 9000 units of 10 msec
122 tTrau: 9000 units of 10 msec
123 enableUmLoopTest: 00h = disabled
124 enableExcessiveDistance: 00h = Disabled
125 excessiveDistance: 64km
126 hoppingMode: 00h = baseband hopping
127 cellType: 00h = Standard Cell
128 BCCH ARFCN / bCCHFrequency: 1
129*/
130
131static unsigned char bs11_attr_bts[] =
132{
133 NM_ATT_BSIC, HARDCODED_BSIC,
134 NM_ATT_BTS_AIR_TIMER, 0x04,
135 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
136 NM_ATT_CCCH_L_I_P, 0x01,
137 NM_ATT_CCCH_L_T, 0x00,
138 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
139 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
140 NM_ATT_BS11_FACCH_QUAL, 0x06,
141 /* interference avg. period in numbers of SACCH multifr */
142 NM_ATT_INTAVE_PARAM, 0x1F,
143 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
144 NM_ATT_CCCH_L_T, 0x23,
145 NM_ATT_GSM_TIME, 0x28, 0x00,
146 NM_ATT_ADM_STATE, 0x03,
147 NM_ATT_RACH_B_THRESH, 0x7F,
148 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
149 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
150 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
151 NM_ATT_BS11_TSYNC, 0x23, 0x28,
152 NM_ATT_BS11_TTRAU, 0x23, 0x28,
153 NM_ATT_TEST_DUR, 0x01, 0x00,
154 NM_ATT_OUTST_ALARM, 0x01, 0x00,
155 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
156 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
157 NM_ATT_BS11_PLL, 0x01, 0x00,
158 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
159};
160
161// Handover Recognition, SET ATTRIBUTES
162
163/*
164Illegal Contents GSM Formatted O&M Msg
165 Object Class: Handover Recognition
166 BTS relat. Number: 0
167 Instance 2: FF
168 Instance 3: FF
169SET ATTRIBUTES
170 enableDelayPowerBudgetHO: 00h = Disabled
171 enableDistanceHO: 00h = Disabled
172 enableInternalInterCellHandover: 00h = Disabled
173 enableInternalIntraCellHandover: 00h = Disabled
174 enablePowerBudgetHO: 00h = Disabled
175 enableRXLEVHO: 00h = Disabled
176 enableRXQUALHO: 00h = Disabled
177 hoAveragingDistance: 8 SACCH multiframes
178 hoAveragingLev:
179 A_LEV_HO: 8 SACCH multiframes
180 W_LEV_HO: 1 SACCH multiframes
181 hoAveragingPowerBudget: 16 SACCH multiframes
182 hoAveragingQual:
183 A_QUAL_HO: 8 SACCH multiframes
184 W_QUAL_HO: 2 SACCH multiframes
185 hoLowerThresholdLevDL: (10 - 110) dBm
186 hoLowerThresholdLevUL: (5 - 110) dBm
187 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
188 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
189 hoThresholdLevDLintra : (20 - 110) dBm
190 hoThresholdLevULintra: (20 - 110) dBm
191 hoThresholdMsRangeMax: 20 km
192 nCell: 06h
193 timerHORequest: 3 ,unit 2 SACCH multiframes
194*/
195
196unsigned char msg_3[] =
197{
198 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
199 0xD0, 0x00, /* enableDelayPowerBudgetHO */
200 0x64, 0x00, /* enableDistanceHO */
201 0x67, 0x00, /* enableInternalInterCellHandover */
202 0x68, 0x00, /* enableInternalInterCellHandover */
203 0x6A, 0x00, /* enablePowerBudgetHO */
204 0x6C, 0x00, /* enableRXLEVHO */
205 0x6D, 0x00, /* enableRXQUALHO */
206 0x6F, 0x08, /* hoAveragingDistance */
207 0x70, 0x08, 0x01, /* hoAveragingLev */
208 0x71, 0x10, 0x10, 0x10,
209 0x72, 0x08, 0x02, /* hoAveragingQual */
210 0x73, 0x0A, /* hoLowerThresholdLevDL */
211 0x74, 0x05, /* hoLowerThresholdLevUL */
212 0x75, 0x06, /* hoLowerThresholdQualDL */
213 0x76, 0x06, /* hoLowerThresholdQualUL */
214 0x78, 0x14, /* hoThresholdLevDLintra */
215 0x79, 0x14, /* hoThresholdLevULintra */
216 0x7A, 0x14, /* hoThresholdMsRangeMax */
217 0x7D, 0x06, /* nCell */
218 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
219 0x20, 0x01, 0x00,
220 0x45, 0x01, 0x00,
221 0x48, 0x01, 0x00,
222 0x5A, 0x01, 0x00,
223 0x5B, 0x01, 0x05,
224 0x5E, 0x01, 0x1A,
225 0x5F, 0x01, 0x20,
226 0x9D, 0x01, 0x00,
227 0x47, 0x01, 0x00,
228 0x5C, 0x01, 0x64,
229 0x5D, 0x01, 0x1E,
230 0x97, 0x01, 0x20,
231 0xF7, 0x01, 0x3C,
232};
233
234// Power Control, SET ATTRIBUTES
235
236/*
237 Object Class: Power Control
238 BTS relat. Number: 0
239 Instance 2: FF
240 Instance 3: FF
241SET ATTRIBUTES
242 enableMsPowerControl: 00h = Disabled
243 enablePowerControlRLFW: 00h = Disabled
244 pcAveragingLev:
245 A_LEV_PC: 4 SACCH multiframes
246 W_LEV_PC: 1 SACCH multiframes
247 pcAveragingQual:
248 A_QUAL_PC: 4 SACCH multiframes
249 W_QUAL_PC: 2 SACCH multiframes
250 pcLowerThresholdLevDL: 0Fh
251 pcLowerThresholdLevUL: 0Ah
252 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
253 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
254 pcRLFThreshold: 0Ch
255 pcUpperThresholdLevDL: 14h
256 pcUpperThresholdLevUL: 0Fh
257 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
258 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
259 powerConfirm: 2 ,unit 2 SACCH multiframes
260 powerControlInterval: 2 ,unit 2 SACCH multiframes
261 powerIncrStepSize: 02h = 4 dB
262 powerRedStepSize: 01h = 2 dB
263 radioLinkTimeoutBs: 64 SACCH multiframes
264 enableBSPowerControl: 00h = disabled
265*/
266
267unsigned char msg_4[] =
268{
269 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
270 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
271 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
272 0x7E, 0x04, 0x01, /* pcAveragingLev */
273 0x7F, 0x04, 0x02, /* pcAveragingQual */
274 0x80, 0x0F, /* pcLowerThresholdLevDL */
275 0x81, 0x0A, /* pcLowerThresholdLevUL */
276 0x82, 0x05, /* pcLowerThresholdQualDL */
277 0x83, 0x05, /* pcLowerThresholdQualUL */
278 0x84, 0x0C, /* pcRLFThreshold */
279 0x85, 0x14, /* pcUpperThresholdLevDL */
280 0x86, 0x0F, /* pcUpperThresholdLevUL */
281 0x87, 0x04, /* pcUpperThresholdQualDL */
282 0x88, 0x04, /* pcUpperThresholdQualUL */
283 0x89, 0x02, /* powerConfirm */
284 0x8A, 0x02, /* powerConfirmInterval */
285 0x8B, 0x02, /* powerIncrStepSize */
286 0x8C, 0x01, /* powerRedStepSize */
287 0x8D, 0x40, /* radioLinkTimeoutBs */
288 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
289};
290
291
292// Transceiver, SET TRX ATTRIBUTES (TRX 0)
293
294/*
295 Object Class: Transceiver
296 BTS relat. Number: 0
297 Tranceiver number: 0
298 Instance 3: FF
299SET TRX ATTRIBUTES
300 aRFCNList (HEX): 0001
301 txPwrMaxReduction: 00h = 30dB
302 radioMeasGran: 254 SACCH multiframes
303 radioMeasRep: 01h = enabled
304 memberOfEmergencyConfig: 01h = TRUE
305 trxArea: 00h = TRX doesn't belong to a concentric cell
306*/
307
308static unsigned char bs11_attr_radio[] =
309{
310 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
311 NM_ATT_RF_MAXPOWR_R, 0x00,
312 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0x05,
313 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
314 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
315 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
316};
317
318static unsigned char nanobts_attr_bts[] = {
319 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
320 /* interference avg. period in numbers of SACCH multifr */
321 NM_ATT_INTAVE_PARAM, 0x06,
322 /* conn fail based on SACCH error rate */
323 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
324 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
325 NM_ATT_MAX_TA, 0x3f,
326 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
327 NM_ATT_CCCH_L_T, 10, /* percent */
328 NM_ATT_CCCH_L_I_P, 1, /* seconds */
329 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
330 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
331 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
332 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
333 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
334 NM_ATT_BSIC, HARDCODED_BSIC,
Harald Welte3055e332010-03-14 15:37:43 +0800335 /* FIXME: do not hardcode the CGI */
336 NM_ATT_IPACC_CGI, 0, 7, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00,
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200337};
338
339static unsigned char nanobts_attr_radio[] = {
340 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
341 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
342};
343
Harald Welte3055e332010-03-14 15:37:43 +0800344static unsigned char nanobts_attr_nse[] = {
345 NM_ATT_IPACC_NSEI, 0, 2, 0x03, 0x9d, /* NSEI 925 */
346 NM_ATT_IPACC_NS_CFG, 0, 7, 3, /* (un)blocking timer (Tns-block) */
347 3, /* (un)blocking retries */
348 3, /* reset timer (Tns-reset) */
349 3, /* reset retries */
350 30, /* test timer (Tns-test) */
351 3, /* alive timer (Tns-alive) */
352 10, /* alive retrires */
353 NM_ATT_IPACC_BSSGP_CFG, 0, 11,
354 3, /* blockimg timer (T1) */
355 3, /* blocking retries */
356 3, /* unblocking retries */
357 3, /* reset timer */
358 3, /* reset retries */
359 10, /* suspend timer (T3) in 100ms */
360 3, /* suspend retries */
361 10, /* resume timer (T4) in 100ms */
362 3, /* resume retries */
363 10, /* capability update timer (T5) */
364 3, /* capability update retries */
365};
366
367static unsigned char nanobts_attr_cell[] = {
368 NM_ATT_IPACC_RAC, 0, 1, 1, /* routing area code */
369 NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2,
370 5, /* repeat time (50ms) */
371 3, /* repeat count */
372 NM_ATT_IPACC_BVCI, 0, 2, 0x03, 0x9d, /* BVCI 925 */
373 NM_ATT_IPACC_RLC_CFG, 0, 9,
374 20, /* T3142 */
375 5, /* T3169 */
376 5, /* T3191 */
377 200, /* T3193 */
378 5, /* T3195 */
379 10, /* N3101 */
380 4, /* N3103 */
381 8, /* N3105 */
382 15, /* RLC CV countdown */
383 NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00,
384 NM_ATT_IPACC_RLC_CFG_2, 0, 5,
385 0x00, 250,
386 0x00, 250,
387 2, /* MCS2 */
388#if 0
389 /* EDGE model only, breaks older models.
390 * Should inquire the BTS capabilities */
391 NM_ATT_IPACC_RLC_CFG_3, 0, 1,
392 2, /* MCS2 */
393#endif
394};
395
396static unsigned char nanobts_attr_nsvc0[] = {
397 NM_ATT_IPACC_NSVCI, 0, 2, 0x03, 0x9d, /* 925 */
398 NM_ATT_IPACC_NS_LINK_CFG, 0, 8,
399 0x59, 0xd8, /* remote udp port (23000) */
400 192, 168, 100, 11, /* remote ip address */
401 0x59, 0xd8, /* local udp port (23000) */
402};
403
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200404/* Callback function to be called whenever we get a GSM 12.21 state change event */
405int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
406 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
407{
408 struct gsm_bts *bts;
409 struct gsm_bts_trx *trx;
410 struct gsm_bts_trx_ts *ts;
Harald Welte3055e332010-03-14 15:37:43 +0800411 struct gsm_bts_gprs_nsvc *nsvc;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200412
Harald Welte9c913c42009-10-20 17:31:00 +0200413 /* This event-driven BTS setup is currently only required on nanoBTS */
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200414
Harald Welte9c913c42009-10-20 17:31:00 +0200415 /* EVT_STATECHG_ADM is called after we call chg_adm_state() and would create
416 * endless loop */
417 if (evt != EVT_STATECHG_OPER)
418 return 0;
419
420 switch (obj_class) {
421 case NM_OC_SITE_MANAGER:
422 bts = container_of(obj, struct gsm_bts, site_mgr);
Sylvain Munautda1b1342009-12-18 17:45:45 +0100423 if ((new_state->operational == 2 &&
424 new_state->availability == NM_AVSTATE_OK) ||
425 (new_state->operational == 1 &&
426 new_state->availability == NM_AVSTATE_OFF_LINE))
Harald Welte9c913c42009-10-20 17:31:00 +0200427 abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
428 break;
429 case NM_OC_BTS:
430 bts = obj;
431 if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
432 patch_nm_tables(bts);
433 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
434 sizeof(nanobts_attr_bts));
435 abis_nm_chg_adm_state(bts, obj_class,
436 bts->bts_nr, 0xff, 0xff,
437 NM_STATE_UNLOCKED);
438 abis_nm_opstart(bts, obj_class,
439 bts->bts_nr, 0xff, 0xff);
440 }
441 break;
442 case NM_OC_CHANNEL:
443 ts = obj;
444 trx = ts->trx;
445 if (new_state->operational == 1 &&
446 new_state->availability == NM_AVSTATE_DEPENDENCY) {
Harald Weltec696d2f2009-10-26 20:14:33 +0100447 patch_nm_tables(trx->bts);
Harald Weltecfb781c2009-10-24 09:09:05 +0200448 enum abis_nm_chan_comb ccomb =
449 abis_nm_chcomb4pchan(ts->pchan);
450 abis_nm_set_channel_attr(ts, ccomb);
Harald Welte9c913c42009-10-20 17:31:00 +0200451 abis_nm_chg_adm_state(trx->bts, obj_class,
452 trx->bts->bts_nr, trx->nr, ts->nr,
453 NM_STATE_UNLOCKED);
454 abis_nm_opstart(trx->bts, obj_class,
455 trx->bts->bts_nr, trx->nr, ts->nr);
456 }
457 break;
458 case NM_OC_RADIO_CARRIER:
459 trx = obj;
460 if (new_state->operational == 1 &&
Harald Welte9c913c42009-10-20 17:31:00 +0200461 new_state->availability == NM_AVSTATE_OK)
462 abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
463 trx->nr, 0xff);
464 break;
Harald Welte3055e332010-03-14 15:37:43 +0800465#ifdef GPRS
466 case NM_OC_GPRS_NSE:
467 bts = container_of(obj, struct gsm_bts, gprs.nse);
468 if (new_state->availability == 5) {
469 abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
470 0xff, 0xff, nanobts_attr_nse,
471 sizeof(nanobts_attr_nse));
472 abis_nm_opstart(bts, obj_class, bts->bts_nr,
473 0xff, 0xff);
474 abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
475 0xff, 0xff, NM_STATE_UNLOCKED);
476 }
477 break;
478 case NM_OC_GPRS_CELL:
479 bts = container_of(obj, struct gsm_bts, gprs.cell);
480 if (new_state->availability == 5) {
481 abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
482 0, 0xff, nanobts_attr_cell,
483 sizeof(nanobts_attr_cell));
484 abis_nm_opstart(bts, obj_class, bts->bts_nr,
485 0, 0xff);
486 abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
487 0, 0xff, NM_STATE_UNLOCKED);
488 }
489 break;
490 case NM_OC_GPRS_NSVC:
491 nsvc = obj;
492 bts = nsvc->bts;
493 /* We skip NSVC1 since we only use NSVC0 */
494 if (nsvc->id == 1)
495 break;
496 if (new_state->availability == NM_AVSTATE_OFF_LINE) {
497 abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
498 nsvc->id, 0xff,
499 nanobts_attr_nsvc0,
500 sizeof(nanobts_attr_nsvc0));
501 abis_nm_opstart(bts, obj_class, bts->bts_nr,
502 nsvc->id, 0xff);
503 abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
504 nsvc->id, 0xff,
505 NM_STATE_UNLOCKED);
506 }
507#endif
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200508 default:
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200509 break;
510 }
511 return 0;
512}
513
514/* Callback function to be called every time we receive a 12.21 SW activated report */
515static int sw_activ_rep(struct msgb *mb)
516{
517 struct abis_om_fom_hdr *foh = msgb_l3(mb);
Harald Weltef5093402009-10-19 21:47:54 +0200518 struct gsm_bts *bts = mb->trx->bts;
519 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
520
Harald Welte053ade52009-12-23 18:24:31 +0100521 if (!trx)
522 return -EINVAL;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200523
524 switch (foh->obj_class) {
Holger Hans Peter Freyther7622a992009-11-19 19:18:29 +0100525 case NM_OC_BASEB_TRANSC:
526 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
527 trx->bts->bts_nr, trx->nr, 0xff,
528 NM_STATE_UNLOCKED);
529 abis_nm_opstart(trx->bts, foh->obj_class,
530 trx->bts->bts_nr, trx->nr, 0xff);
531 /* TRX software is active, tell it to initiate RSL Link */
532 abis_nm_ipaccess_rsl_connect(trx, 0, 3003, trx->rsl_tei);
533 break;
Holger Hans Peter Freyther1c8b4802009-11-11 11:54:24 +0100534 case NM_OC_RADIO_CARRIER: {
535 /*
536 * Locking the radio carrier will make it go
537 * offline again and we would come here. The
538 * framework should determine that there was
539 * no change and avoid recursion.
540 *
541 * This code is here to make sure that on start
542 * a TRX remains locked.
543 */
Holger Hans Peter Freyther677bb2f2009-12-31 03:05:52 +0100544 int rc_state = trx->nm_state.administrative;
Holger Hans Peter Freyther7622a992009-11-19 19:18:29 +0100545 /* Patch ARFCN into radio attribute */
546 nanobts_attr_radio[5] &= 0xf0;
547 nanobts_attr_radio[5] |= trx->arfcn >> 8;
548 nanobts_attr_radio[6] = trx->arfcn & 0xff;
549 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
550 sizeof(nanobts_attr_radio));
551 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
552 trx->bts->bts_nr, trx->nr, 0xff,
Holger Hans Peter Freyther1c8b4802009-11-11 11:54:24 +0100553 rc_state);
Holger Hans Peter Freyther7622a992009-11-19 19:18:29 +0100554 abis_nm_opstart(trx->bts, foh->obj_class, trx->bts->bts_nr,
555 trx->nr, 0xff);
556 break;
Holger Hans Peter Freyther1c8b4802009-11-11 11:54:24 +0100557 }
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200558 }
559 return 0;
560}
561
562/* Callback function for NACK on the OML NM */
Harald Welte6a21c732009-11-17 06:09:56 +0100563static int oml_msg_nack(u_int8_t mt)
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200564{
565 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100566 LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200567 "Was the bts type and frequency properly specified?\n");
568 exit(-1);
569 }
570
571 return 0;
572}
573
574/* Callback function to be called every time we receive a signal from NM */
575static int nm_sig_cb(unsigned int subsys, unsigned int signal,
576 void *handler_data, void *signal_data)
577{
Harald Welte6a21c732009-11-17 06:09:56 +0100578 u_int8_t *msg_type;
579
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200580 switch (signal) {
581 case S_NM_SW_ACTIV_REP:
582 return sw_activ_rep(signal_data);
583 case S_NM_NACK:
Harald Welte6a21c732009-11-17 06:09:56 +0100584 msg_type = signal_data;
585 return oml_msg_nack(*msg_type);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200586 default:
587 break;
588 }
589 return 0;
590}
591
592static void bootstrap_om_nanobts(struct gsm_bts *bts)
593{
594 /* We don't do callback based bootstrapping, but event driven (see above) */
595}
596
597static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
598{
599 enum abis_nm_chan_comb ccomb = abis_nm_chcomb4pchan(ts->pchan);
600 struct gsm_e1_subslot *e1l = &ts->e1_link;
601
602 abis_nm_set_channel_attr(ts, ccomb);
603
604 if (is_ipaccess_bts(ts->trx->bts))
605 return;
606
607 switch (ts->pchan) {
608 case GSM_PCHAN_TCH_F:
609 case GSM_PCHAN_TCH_H:
610 abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts,
611 e1l->e1_ts_ss);
612 break;
613 default:
614 break;
615 }
616}
617
618static void nm_reconfig_trx(struct gsm_bts_trx *trx)
619{
620 struct gsm_e1_subslot *e1l = &trx->rsl_e1_link;
621 int i;
622
623 patch_nm_tables(trx->bts);
624
625 switch (trx->bts->type) {
626 case GSM_BTS_TYPE_BS11:
627 /* FIXME: discover this by fetching an attribute */
628#if 0
629 trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
630#else
631 trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
632#endif
633 abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
634 e1l->e1_ts_ss);
635 abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
636 e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei);
637
638 /* Set Radio Attributes */
639 if (trx == trx->bts->c0)
640 abis_nm_set_radio_attr(trx, bs11_attr_radio,
641 sizeof(bs11_attr_radio));
642 else {
643 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
644 u_int8_t arfcn_low = trx->arfcn & 0xff;
645 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
646 memcpy(trx1_attr_radio, bs11_attr_radio,
647 sizeof(trx1_attr_radio));
648
649 /* patch ARFCN into TRX Attributes */
650 trx1_attr_radio[2] &= 0xf0;
651 trx1_attr_radio[2] |= arfcn_high;
652 trx1_attr_radio[3] = arfcn_low;
653
654 abis_nm_set_radio_attr(trx, trx1_attr_radio,
655 sizeof(trx1_attr_radio));
656 }
657 break;
Mike Haben66e0ba02009-10-02 12:19:34 +0100658 case GSM_BTS_TYPE_NANOBTS:
Harald Welte97be68a2009-10-19 21:47:31 +0200659 switch (trx->bts->band) {
660 case GSM_BAND_850:
661 case GSM_BAND_900:
662 trx->nominal_power = 20;
663 break;
664 case GSM_BAND_1800:
665 case GSM_BAND_1900:
666 trx->nominal_power = 23;
667 break;
Holger Hans Peter Freyther604326f2009-10-22 15:46:16 +0200668 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100669 LOGP(DNM, LOGL_ERROR, "Unsupported nanoBTS GSM band %s\n",
Harald Welte97be68a2009-10-19 21:47:31 +0200670 gsm_band_name(trx->bts->band));
671 break;
672 }
673 break;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200674 default:
675 break;
676 }
677
678 for (i = 0; i < TRX_NR_TS; i++)
679 nm_reconfig_ts(&trx->ts[i]);
680}
681
682static void nm_reconfig_bts(struct gsm_bts *bts)
683{
684 struct gsm_bts_trx *trx;
685
686 switch (bts->type) {
687 case GSM_BTS_TYPE_BS11:
Harald Welte238cd5a2009-12-14 17:49:52 +0100688 patch_nm_tables(bts);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200689 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
690 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
691 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
692 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
693 break;
694 default:
695 break;
696 }
697
698 llist_for_each_entry(trx, &bts->trx_list, list)
699 nm_reconfig_trx(trx);
700}
701
702static void bootstrap_om_bs11(struct gsm_bts *bts)
703{
704 /* stop sending event reports */
705 abis_nm_event_reports(bts, 0);
706
707 /* begin DB transmission */
708 abis_nm_bs11_db_transmission(bts, 1);
709
710 /* end DB transmission */
711 abis_nm_bs11_db_transmission(bts, 0);
712
713 /* Reset BTS Site manager resource */
714 abis_nm_bs11_reset_resource(bts);
715
716 /* begin DB transmission */
717 abis_nm_bs11_db_transmission(bts, 1);
718
719 /* reconfigure BTS with all TRX and all TS */
720 nm_reconfig_bts(bts);
721
722 /* end DB transmission */
723 abis_nm_bs11_db_transmission(bts, 0);
724
725 /* Reset BTS Site manager resource */
726 abis_nm_bs11_reset_resource(bts);
727
728 /* restart sending event reports */
729 abis_nm_event_reports(bts, 1);
730}
731
732static void bootstrap_om(struct gsm_bts *bts)
733{
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100734 LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for BTS %u\n", bts->nr);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200735
736 switch (bts->type) {
737 case GSM_BTS_TYPE_BS11:
738 bootstrap_om_bs11(bts);
739 break;
Mike Haben66e0ba02009-10-02 12:19:34 +0100740 case GSM_BTS_TYPE_NANOBTS:
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200741 bootstrap_om_nanobts(bts);
742 break;
743 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100744 LOGP(DNM, LOGL_ERROR, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200745 }
746}
747
748static int shutdown_om(struct gsm_bts *bts)
749{
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100750 LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200751
752 /* stop sending event reports */
753 abis_nm_event_reports(bts, 0);
754
755 /* begin DB transmission */
756 abis_nm_bs11_db_transmission(bts, 1);
757
758 /* end DB transmission */
759 abis_nm_bs11_db_transmission(bts, 0);
760
761 /* Reset BTS Site manager resource */
762 abis_nm_bs11_reset_resource(bts);
763
764 return 0;
765}
766
767int bsc_shutdown_net(struct gsm_network *net)
768{
769 struct gsm_bts *bts;
770
771 llist_for_each_entry(bts, &net->bts_list, list) {
772 int rc;
773 rc = shutdown_om(bts);
774 if (rc < 0)
775 return rc;
776 }
777
778 return 0;
779}
780
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200781/* set all system information types */
782static int set_system_infos(struct gsm_bts_trx *trx)
783{
Harald Weltea54a2bb2009-12-01 18:04:30 +0530784 int i, rc;
785 u_int8_t si_tmp[23];
Harald Welte36e5a792009-12-21 23:12:19 +0100786 struct gsm_bts *bts = trx->bts;
787
788 bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
789 ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
790 bts->si_common.cell_sel_par.neci = bts->network->neci;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200791
792 if (trx == trx->bts->c0) {
Harald Weltea54a2bb2009-12-01 18:04:30 +0530793 for (i = 1; i <= 4; i++) {
794 rc = gsm_generate_si(si_tmp, trx->bts, i);
795 if (rc < 0)
796 goto err_out;
Harald Welted7f36482009-12-19 21:29:00 +0100797 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea54a2bb2009-12-01 18:04:30 +0530798 rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200799 }
Harald Weltea54a2bb2009-12-01 18:04:30 +0530800#ifdef GPRS
Harald Weltea2068e72009-12-22 13:16:27 +0100801 i = 13;
Harald Welte28fc9632009-12-21 17:02:32 +0100802 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
803 if (rc < 0)
804 goto err_out;
805 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
806 rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
Harald Weltea54a2bb2009-12-01 18:04:30 +0530807#endif
Harald Welte28fc9632009-12-21 17:02:32 +0100808 }
809
Harald Welted7f36482009-12-19 21:29:00 +0100810 i = 5;
811 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_5);
812 if (rc < 0)
Harald Weltea54a2bb2009-12-01 18:04:30 +0530813 goto err_out;
Harald Welted7f36482009-12-19 21:29:00 +0100814 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea54a2bb2009-12-01 18:04:30 +0530815 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si_tmp, rc);
816
Harald Welted7f36482009-12-19 21:29:00 +0100817 i = 6;
818 rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_6);
819 if (rc < 0)
Harald Weltea54a2bb2009-12-01 18:04:30 +0530820 goto err_out;
Harald Welted7f36482009-12-19 21:29:00 +0100821 DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
Harald Weltea54a2bb2009-12-01 18:04:30 +0530822 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si_tmp, rc);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200823
Harald Welte3055e332010-03-14 15:37:43 +0800824#ifdef GPRS
825 rsl_ipacc_pdch_activate(&trx->ts[7].lchan[0]);
826#endif
827
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200828 return 0;
Harald Weltea54a2bb2009-12-01 18:04:30 +0530829err_out:
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100830 LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
Harald Weltea54a2bb2009-12-01 18:04:30 +0530831 "a problem with neighbor cell list generation\n",
Harald Weltee285bad2009-12-16 11:57:48 +0100832 i, trx->bts->nr);
Harald Weltea54a2bb2009-12-01 18:04:30 +0530833 return rc;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200834}
835
836/*
837 * Patch the various SYSTEM INFORMATION tables to update
838 * the LAI
839 */
840static void patch_nm_tables(struct gsm_bts *bts)
841{
842 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
843 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
844
845 /* patch ARFCN into BTS Attributes */
846 bs11_attr_bts[69] &= 0xf0;
847 bs11_attr_bts[69] |= arfcn_high;
848 bs11_attr_bts[70] = arfcn_low;
849 nanobts_attr_bts[42] &= 0xf0;
850 nanobts_attr_bts[42] |= arfcn_high;
851 nanobts_attr_bts[43] = arfcn_low;
852
853 /* patch ARFCN into TRX Attributes */
854 bs11_attr_radio[2] &= 0xf0;
855 bs11_attr_radio[2] |= arfcn_high;
856 bs11_attr_radio[3] = arfcn_low;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200857
858 /* patch BSIC */
859 bs11_attr_bts[1] = bts->bsic;
Harald Welte3055e332010-03-14 15:37:43 +0800860 nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;
861
862 /* patch CGI */
863 abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200864
865 /* patch the power reduction */
866 bs11_attr_radio[5] = bts->c0->max_power_red / 2;
867 nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
Harald Welte3055e332010-03-14 15:37:43 +0800868
869 /* patch NSVCI */
870 nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
871 nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;
872
Harald Welte410575a2010-03-14 23:30:30 +0800873 /* patch IP address as SGSN IP */
874 *(u_int16_t *)(nanobts_attr_nsvc0+8) =
875 htons(bts->gprs.nsvc[0].remote_port);
876 *(u_int32_t *)(nanobts_attr_nsvc0+10) =
877 htonl(bts->gprs.nsvc[0].remote_ip);
878 *(u_int16_t *)(nanobts_attr_nsvc0+14) =
879 htons(bts->gprs.nsvc[0].local_port);
Harald Welte3055e332010-03-14 15:37:43 +0800880
881 /* patch BVCI */
882 nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
883 nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
884 /* patch RAC */
885 nanobts_attr_cell[3] = bts->gprs.rac;
886
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200887}
888
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200889static void bootstrap_rsl(struct gsm_bts_trx *trx)
890{
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100891 LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte424873e2009-12-24 13:39:34 +0100892 "on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
893 trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
894 bsc_gsmnet->network_code, trx->bts->location_area_code,
895 trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200896 set_system_infos(trx);
897}
898
899void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
900{
901 switch (event) {
902 case EVT_E1_TEI_UP:
903 switch (type) {
904 case E1INP_SIGN_OML:
905 bootstrap_om(trx->bts);
906 break;
907 case E1INP_SIGN_RSL:
908 bootstrap_rsl(trx);
909 break;
910 default:
911 break;
912 }
913 break;
914 case EVT_E1_TEI_DN:
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100915 LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n");
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200916 /* FIXME: deal with TEI or L1 link loss */
917 break;
918 default:
919 break;
920 }
921}
922
923static int bootstrap_bts(struct gsm_bts *bts)
924{
Mike Haben66e0ba02009-10-02 12:19:34 +0100925 switch (bts->band) {
926 case GSM_BAND_1800:
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200927 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100928 LOGP(DNM, LOGL_ERROR, "GSM1800 channel must be between 512-885.\n");
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200929 return -EINVAL;
930 }
931 break;
Mike Haben66e0ba02009-10-02 12:19:34 +0100932 case GSM_BAND_1900:
933 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 810) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100934 LOGP(DNM, LOGL_ERROR, "GSM1900 channel must be between 512-810.\n");
Mike Haben66e0ba02009-10-02 12:19:34 +0100935 return -EINVAL;
936 }
937 break;
938 case GSM_BAND_900:
Holger Hans Peter Freyther2ba2b332010-02-09 15:44:14 +0100939 if (bts->c0->arfcn < 1 ||
940 (bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
941 bts->c0->arfcn > 1023) {
942 LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200943 return -EINVAL;
944 }
945 break;
Mike Haben66e0ba02009-10-02 12:19:34 +0100946 default:
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100947 LOGP(DNM, LOGL_ERROR, "Unsupported frequency band.\n");
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200948 return -EINVAL;
949 }
950
Harald Welte395cb6b2009-12-12 13:44:19 +0100951 if (bts->network->auth_policy == GSM_AUTH_POLICY_ACCEPT_ALL &&
Harald Welte8c973ba2009-12-21 23:08:18 +0100952 !bts->si_common.rach_control.cell_bar)
Harald Welte36ab5452009-12-21 23:36:45 +0100953 LOGP(DNM, LOGL_ERROR, "\nWARNING: You are running an 'accept-all' "
Harald Welte395cb6b2009-12-12 13:44:19 +0100954 "network on a BTS that is not barred. This "
955 "configuration is likely to interfere with production "
956 "GSM networks and should only be used in a RF "
957 "shielded environment such as a faraday cage!\n\n");
958
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200959 /* Control Channel Description */
Harald Weltea54a2bb2009-12-01 18:04:30 +0530960 bts->si_common.chan_desc.att = 1;
961 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
962 bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200963 /* T3212 is set from vty/config */
964
Harald Weltea54a2bb2009-12-01 18:04:30 +0530965 /* some defaults for our system information */
Harald Weltea54a2bb2009-12-01 18:04:30 +0530966 bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
967 bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
968 bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
969
Harald Weltea54a2bb2009-12-01 18:04:30 +0530970 bts->si_common.cell_sel_par.acs = 0;
Harald Weltea54a2bb2009-12-01 18:04:30 +0530971
972 bts->si_common.ncc_permitted = 0xff;
973
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200974 paging_init(bts);
975
976 return 0;
977}
978
979int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
980 const char *config_file)
981{
982 struct gsm_bts *bts;
983 int rc;
984
985 /* initialize our data structures */
986 bsc_gsmnet = gsm_network_init(1, 1, mncc_recv);
987 if (!bsc_gsmnet)
988 return -ENOMEM;
989
990 bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
991 bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
992
993 telnet_init(bsc_gsmnet, 4242);
994 rc = vty_read_config_file(config_file);
995 if (rc < 0) {
Harald Weltecf2ec4a2009-12-17 23:10:46 +0100996 LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
Holger Hans Peter Freythercad370f2009-08-17 06:55:10 +0200997 return rc;
998 }
999
1000 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1001
1002 llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
1003 bootstrap_bts(bts);
1004 if (!is_ipaccess_bts(bts))
1005 rc = e1_reconfig_bts(bts);
1006
1007 if (rc < 0)
1008 exit (1);
1009 }
1010
1011 /* initialize nanoBTS support omce */
1012 rc = ipaccess_setup(bsc_gsmnet);
1013
1014 return 0;
1015}