blob: 13a9677e9db41eda92e2cd19f9c72a03733659aa [file] [log] [blame]
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001/* A hackish minimal BSC (+MSC +HLR) implementation */
2
Harald Weltedcccb182010-05-16 20:52:23 +02003/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02004 * (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
Harald Welte9af6ddf2011-01-01 15:25:50 +01008 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020010 * (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
Harald Welte9af6ddf2011-01-01 15:25:50 +010015 * GNU Affero General Public License for more details.
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020016 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020019 *
20 */
21
22#include <openbsc/gsm_data.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010023#include <osmocore/gsm_utils.h>
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020024#include <openbsc/gsm_04_08.h>
25#include <openbsc/abis_rsl.h>
26#include <openbsc/abis_nm.h>
27#include <openbsc/debug.h>
28#include <openbsc/misdn.h>
Harald Welte4b037e42010-05-19 19:45:32 +020029#include <osmocom/vty/telnet_interface.h>
Harald Weltea43f7892009-12-01 18:04:30 +053030#include <openbsc/system_information.h>
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +020031#include <openbsc/paging.h>
32#include <openbsc/signal.h>
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +020033#include <openbsc/chan_alloc.h>
Harald Weltedfe6c7d2010-02-20 16:24:02 +010034#include <osmocore/talloc.h>
Holger Hans Peter Freyther39e6ba02010-11-15 20:43:02 +010035#include <openbsc/ipaccess.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,
Holger Hans Peter Freytheraa0db802010-05-13 00:37:48 +0800404 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
405 struct abis_om_obj_inst *obj_inst)
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200406{
407 struct gsm_bts *bts;
408 struct gsm_bts_trx *trx;
409 struct gsm_bts_trx_ts *ts;
Harald Welte97a282b2010-03-14 15:37:43 +0800410 struct gsm_bts_gprs_nsvc *nsvc;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200411
Harald Welte8406ec22009-10-20 17:31:00 +0200412 /* This event-driven BTS setup is currently only required on nanoBTS */
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200413
Harald Welte8406ec22009-10-20 17:31:00 +0200414 /* EVT_STATECHG_ADM is called after we call chg_adm_state() and would create
415 * endless loop */
416 if (evt != EVT_STATECHG_OPER)
417 return 0;
418
419 switch (obj_class) {
420 case NM_OC_SITE_MANAGER:
421 bts = container_of(obj, struct gsm_bts, site_mgr);
Holger Hans Peter Freytheraef49cc2010-04-26 10:32:34 +0800422 if ((new_state->operational == NM_OPSTATE_ENABLED &&
Sylvain Munaut7de67962009-12-18 17:45:45 +0100423 new_state->availability == NM_AVSTATE_OK) ||
Holger Hans Peter Freytheraef49cc2010-04-26 10:32:34 +0800424 (new_state->operational == NM_OPSTATE_DISABLED &&
Sylvain Munaut7de67962009-12-18 17:45:45 +0100425 new_state->availability == NM_AVSTATE_OFF_LINE))
Harald Welte8406ec22009-10-20 17:31:00 +0200426 abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
427 break;
428 case NM_OC_BTS:
429 bts = obj;
430 if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
431 patch_nm_tables(bts);
432 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
433 sizeof(nanobts_attr_bts));
434 abis_nm_chg_adm_state(bts, obj_class,
435 bts->bts_nr, 0xff, 0xff,
436 NM_STATE_UNLOCKED);
437 abis_nm_opstart(bts, obj_class,
438 bts->bts_nr, 0xff, 0xff);
439 }
440 break;
441 case NM_OC_CHANNEL:
442 ts = obj;
443 trx = ts->trx;
Holger Hans Peter Freytheraef49cc2010-04-26 10:32:34 +0800444 if (new_state->operational == NM_OPSTATE_DISABLED &&
Harald Welte8406ec22009-10-20 17:31:00 +0200445 new_state->availability == NM_AVSTATE_DEPENDENCY) {
Harald Welte65bdc912009-10-26 20:14:33 +0100446 patch_nm_tables(trx->bts);
Harald Welte0f890b02009-10-24 09:09:05 +0200447 enum abis_nm_chan_comb ccomb =
448 abis_nm_chcomb4pchan(ts->pchan);
449 abis_nm_set_channel_attr(ts, ccomb);
Harald Welte8406ec22009-10-20 17:31:00 +0200450 abis_nm_chg_adm_state(trx->bts, obj_class,
451 trx->bts->bts_nr, trx->nr, ts->nr,
452 NM_STATE_UNLOCKED);
453 abis_nm_opstart(trx->bts, obj_class,
454 trx->bts->bts_nr, trx->nr, ts->nr);
455 }
456 break;
457 case NM_OC_RADIO_CARRIER:
458 trx = obj;
Holger Hans Peter Freytheraef49cc2010-04-26 10:32:34 +0800459 if (new_state->operational == NM_OPSTATE_DISABLED &&
Harald Welte8406ec22009-10-20 17:31:00 +0200460 new_state->availability == NM_AVSTATE_OK)
461 abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
462 trx->nr, 0xff);
463 break;
Harald Welte97a282b2010-03-14 15:37:43 +0800464 case NM_OC_GPRS_NSE:
465 bts = container_of(obj, struct gsm_bts, gprs.nse);
Harald Welte4511d892010-04-18 15:51:20 +0200466 if (bts->gprs.mode == BTS_GPRS_NONE)
Harald Weltefa586252010-03-14 23:33:36 +0800467 break;
Holger Hans Peter Freytheraef49cc2010-04-26 10:32:34 +0800468 if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
Harald Welte97a282b2010-03-14 15:37:43 +0800469 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);
Harald Welte97a282b2010-03-14 15:37:43 +0800474 }
475 break;
476 case NM_OC_GPRS_CELL:
477 bts = container_of(obj, struct gsm_bts, gprs.cell);
Harald Welte4511d892010-04-18 15:51:20 +0200478 if (bts->gprs.mode == BTS_GPRS_NONE)
Harald Weltefa586252010-03-14 23:33:36 +0800479 break;
Holger Hans Peter Freytheraef49cc2010-04-26 10:32:34 +0800480 if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
Harald Welte97a282b2010-03-14 15:37:43 +0800481 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);
Holger Hans Peter Freytherc7a1a1f2010-10-02 04:38:04 +0800488 abis_nm_chg_adm_state(bts, NM_OC_GPRS_NSE, bts->bts_nr,
489 0xff, 0xff, NM_STATE_UNLOCKED);
Harald Welte97a282b2010-03-14 15:37:43 +0800490 }
491 break;
492 case NM_OC_GPRS_NSVC:
493 nsvc = obj;
494 bts = nsvc->bts;
Harald Welte4511d892010-04-18 15:51:20 +0200495 if (bts->gprs.mode == BTS_GPRS_NONE)
Harald Weltefa586252010-03-14 23:33:36 +0800496 break;
Holger Hans Peter Freythera5811362010-04-30 13:32:05 +0800497 /* We skip NSVC1 since we only use NSVC0 */
Harald Welte97a282b2010-03-14 15:37:43 +0800498 if (nsvc->id == 1)
499 break;
500 if (new_state->availability == NM_AVSTATE_OFF_LINE) {
501 abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
502 nsvc->id, 0xff,
503 nanobts_attr_nsvc0,
504 sizeof(nanobts_attr_nsvc0));
505 abis_nm_opstart(bts, obj_class, bts->bts_nr,
506 nsvc->id, 0xff);
507 abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
508 nsvc->id, 0xff,
509 NM_STATE_UNLOCKED);
510 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200511 default:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200512 break;
513 }
514 return 0;
515}
516
517/* Callback function to be called every time we receive a 12.21 SW activated report */
518static int sw_activ_rep(struct msgb *mb)
519{
520 struct abis_om_fom_hdr *foh = msgb_l3(mb);
Harald Welted004a642009-10-19 21:47:54 +0200521 struct gsm_bts *bts = mb->trx->bts;
522 struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
523
Harald Welteb7bcb792009-12-23 18:24:31 +0100524 if (!trx)
525 return -EINVAL;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200526
527 switch (foh->obj_class) {
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100528 case NM_OC_BASEB_TRANSC:
529 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
530 trx->bts->bts_nr, trx->nr, 0xff,
531 NM_STATE_UNLOCKED);
532 abis_nm_opstart(trx->bts, foh->obj_class,
533 trx->bts->bts_nr, trx->nr, 0xff);
534 /* TRX software is active, tell it to initiate RSL Link */
535 abis_nm_ipaccess_rsl_connect(trx, 0, 3003, trx->rsl_tei);
536 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100537 case NM_OC_RADIO_CARRIER: {
538 /*
539 * Locking the radio carrier will make it go
540 * offline again and we would come here. The
541 * framework should determine that there was
542 * no change and avoid recursion.
543 *
544 * This code is here to make sure that on start
545 * a TRX remains locked.
546 */
Holger Hans Peter Freytherf31e4742009-12-31 03:05:52 +0100547 int rc_state = trx->nm_state.administrative;
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100548 /* Patch ARFCN into radio attribute */
549 nanobts_attr_radio[5] &= 0xf0;
550 nanobts_attr_radio[5] |= trx->arfcn >> 8;
551 nanobts_attr_radio[6] = trx->arfcn & 0xff;
552 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
553 sizeof(nanobts_attr_radio));
554 abis_nm_chg_adm_state(trx->bts, foh->obj_class,
555 trx->bts->bts_nr, trx->nr, 0xff,
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100556 rc_state);
Holger Hans Peter Freyther1ce10f32009-11-19 19:18:29 +0100557 abis_nm_opstart(trx->bts, foh->obj_class, trx->bts->bts_nr,
558 trx->nr, 0xff);
559 break;
Holger Hans Peter Freyther2d501ea2009-11-11 11:54:24 +0100560 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200561 }
562 return 0;
563}
564
565/* Callback function for NACK on the OML NM */
Holger Hans Peter Freyther6d2b66e2010-07-14 02:08:35 +0800566static int oml_msg_nack(struct nm_nack_signal_data *nack)
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200567{
Holger Hans Peter Freyther39e6ba02010-11-15 20:43:02 +0100568 int i;
569
Holger Hans Peter Freyther6d2b66e2010-07-14 02:08:35 +0800570 if (nack->mt == NM_MT_SET_BTS_ATTR_NACK) {
Holger Hans Peter Freyther39e6ba02010-11-15 20:43:02 +0100571
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100572 LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200573 "Was the bts type and frequency properly specified?\n");
574 exit(-1);
Holger Hans Peter Freyther39e6ba02010-11-15 20:43:02 +0100575 } else {
576 LOGP(DNM, LOGL_ERROR, "Got a NACK going to drop the OML links.\n");
577 for (i = 0; i < bsc_gsmnet->num_bts; ++i) {
578 struct gsm_bts *bts = gsm_bts_num(bsc_gsmnet, i);
579 if (is_ipaccess_bts(bts))
580 ipaccess_drop_oml(bts);
581 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200582 }
583
584 return 0;
585}
586
587/* Callback function to be called every time we receive a signal from NM */
588static int nm_sig_cb(unsigned int subsys, unsigned int signal,
589 void *handler_data, void *signal_data)
590{
Holger Hans Peter Freyther6d2b66e2010-07-14 02:08:35 +0800591 struct nm_nack_signal_data *nack;
Harald Welted8cfc902009-11-17 06:09:56 +0100592
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200593 switch (signal) {
594 case S_NM_SW_ACTIV_REP:
595 return sw_activ_rep(signal_data);
596 case S_NM_NACK:
Holger Hans Peter Freyther6d2b66e2010-07-14 02:08:35 +0800597 nack = signal_data;
598 return oml_msg_nack(nack);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200599 default:
600 break;
601 }
602 return 0;
603}
604
605static void bootstrap_om_nanobts(struct gsm_bts *bts)
606{
607 /* We don't do callback based bootstrapping, but event driven (see above) */
608}
609
610static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
611{
612 enum abis_nm_chan_comb ccomb = abis_nm_chcomb4pchan(ts->pchan);
613 struct gsm_e1_subslot *e1l = &ts->e1_link;
614
615 abis_nm_set_channel_attr(ts, ccomb);
616
617 if (is_ipaccess_bts(ts->trx->bts))
618 return;
619
620 switch (ts->pchan) {
621 case GSM_PCHAN_TCH_F:
622 case GSM_PCHAN_TCH_H:
623 abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts,
624 e1l->e1_ts_ss);
625 break;
626 default:
627 break;
628 }
629}
630
631static void nm_reconfig_trx(struct gsm_bts_trx *trx)
632{
633 struct gsm_e1_subslot *e1l = &trx->rsl_e1_link;
634 int i;
635
636 patch_nm_tables(trx->bts);
637
638 switch (trx->bts->type) {
639 case GSM_BTS_TYPE_BS11:
640 /* FIXME: discover this by fetching an attribute */
641#if 0
642 trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
643#else
644 trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
645#endif
646 abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
647 e1l->e1_ts_ss);
648 abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
649 e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei);
650
651 /* Set Radio Attributes */
652 if (trx == trx->bts->c0)
653 abis_nm_set_radio_attr(trx, bs11_attr_radio,
654 sizeof(bs11_attr_radio));
655 else {
656 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
657 u_int8_t arfcn_low = trx->arfcn & 0xff;
658 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
659 memcpy(trx1_attr_radio, bs11_attr_radio,
660 sizeof(trx1_attr_radio));
661
662 /* patch ARFCN into TRX Attributes */
663 trx1_attr_radio[2] &= 0xf0;
664 trx1_attr_radio[2] |= arfcn_high;
665 trx1_attr_radio[3] = arfcn_low;
666
667 abis_nm_set_radio_attr(trx, trx1_attr_radio,
668 sizeof(trx1_attr_radio));
669 }
670 break;
Mike Habene2d82272009-10-02 12:19:34 +0100671 case GSM_BTS_TYPE_NANOBTS:
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200672 switch (trx->bts->band) {
673 case GSM_BAND_850:
674 case GSM_BAND_900:
675 trx->nominal_power = 20;
676 break;
677 case GSM_BAND_1800:
678 case GSM_BAND_1900:
679 trx->nominal_power = 23;
680 break;
Holger Hans Peter Freyther555eba12009-10-22 15:46:16 +0200681 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100682 LOGP(DNM, LOGL_ERROR, "Unsupported nanoBTS GSM band %s\n",
Harald Welteaf7b2fa2009-10-19 21:47:31 +0200683 gsm_band_name(trx->bts->band));
684 break;
685 }
686 break;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200687 default:
688 break;
689 }
690
691 for (i = 0; i < TRX_NR_TS; i++)
692 nm_reconfig_ts(&trx->ts[i]);
693}
694
695static void nm_reconfig_bts(struct gsm_bts *bts)
696{
697 struct gsm_bts_trx *trx;
698
699 switch (bts->type) {
700 case GSM_BTS_TYPE_BS11:
Harald Welteade7a142009-12-14 17:49:52 +0100701 patch_nm_tables(bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200702 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
703 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
704 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
705 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
706 break;
707 default:
708 break;
709 }
710
711 llist_for_each_entry(trx, &bts->trx_list, list)
712 nm_reconfig_trx(trx);
713}
714
715static void bootstrap_om_bs11(struct gsm_bts *bts)
716{
717 /* stop sending event reports */
718 abis_nm_event_reports(bts, 0);
719
720 /* begin DB transmission */
721 abis_nm_bs11_db_transmission(bts, 1);
722
723 /* end DB transmission */
724 abis_nm_bs11_db_transmission(bts, 0);
725
726 /* Reset BTS Site manager resource */
727 abis_nm_bs11_reset_resource(bts);
728
729 /* begin DB transmission */
730 abis_nm_bs11_db_transmission(bts, 1);
731
732 /* reconfigure BTS with all TRX and all TS */
733 nm_reconfig_bts(bts);
734
735 /* end DB transmission */
736 abis_nm_bs11_db_transmission(bts, 0);
737
738 /* Reset BTS Site manager resource */
739 abis_nm_bs11_reset_resource(bts);
740
741 /* restart sending event reports */
742 abis_nm_event_reports(bts, 1);
743}
744
745static void bootstrap_om(struct gsm_bts *bts)
746{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100747 LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200748
749 switch (bts->type) {
750 case GSM_BTS_TYPE_BS11:
751 bootstrap_om_bs11(bts);
752 break;
Mike Habene2d82272009-10-02 12:19:34 +0100753 case GSM_BTS_TYPE_NANOBTS:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200754 bootstrap_om_nanobts(bts);
755 break;
756 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100757 LOGP(DNM, LOGL_ERROR, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200758 }
759}
760
761static int shutdown_om(struct gsm_bts *bts)
762{
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100763 LOGP(DNM, LOGL_NOTICE, "shutting down OML for BTS %u\n", bts->nr);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200764
765 /* stop sending event reports */
766 abis_nm_event_reports(bts, 0);
767
768 /* begin DB transmission */
769 abis_nm_bs11_db_transmission(bts, 1);
770
771 /* end DB transmission */
772 abis_nm_bs11_db_transmission(bts, 0);
773
774 /* Reset BTS Site manager resource */
775 abis_nm_bs11_reset_resource(bts);
776
777 return 0;
778}
779
780int bsc_shutdown_net(struct gsm_network *net)
781{
782 struct gsm_bts *bts;
783
784 llist_for_each_entry(bts, &net->bts_list, list) {
785 int rc;
786 rc = shutdown_om(bts);
787 if (rc < 0)
788 return rc;
789 }
790
791 return 0;
792}
793
Harald Welte7401ae62010-06-15 16:44:12 +0200794static int generate_and_rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i)
795{
796 struct gsm_bts *bts = trx->bts;
797 int rc;
798
Harald Welte9fbff4a2010-07-30 11:50:09 +0200799 /* Only generate SI if this SI is not in "static" (user-defined) mode */
800 if (!(bts->si_mode_static & (1 << i))) {
801 rc = gsm_generate_si(bts, i);
802 if (rc < 0)
803 return rc;
804 }
Harald Welte7401ae62010-06-15 16:44:12 +0200805
806 DEBUGP(DRR, "SI%s: %s\n", gsm_sitype_name(i),
807 hexdump(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN));
808
809 switch (i) {
810 case SYSINFO_TYPE_5:
811 case SYSINFO_TYPE_5bis:
812 case SYSINFO_TYPE_5ter:
813 case SYSINFO_TYPE_6:
814 rc = rsl_sacch_filling(trx, gsm_sitype2rsl(i),
815 GSM_BTS_SI(bts, i), rc);
816 break;
817 default:
818 rc = rsl_bcch_info(trx, gsm_sitype2rsl(i),
819 GSM_BTS_SI(bts, i), rc);
820 break;
821 }
822
823 return rc;
824}
825
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200826/* set all system information types */
827static int set_system_infos(struct gsm_bts_trx *trx)
828{
Harald Weltea43f7892009-12-01 18:04:30 +0530829 int i, rc;
Harald Welte73d4fce2009-12-21 23:12:19 +0100830 struct gsm_bts *bts = trx->bts;
831
832 bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
833 ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
834 bts->si_common.cell_sel_par.neci = bts->network->neci;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200835
Harald Welte9fbff4a2010-07-30 11:50:09 +0200836 /* First, we determine which of the SI messages we actually need */
837
Harald Welte7401ae62010-06-15 16:44:12 +0200838 if (trx == bts->c0) {
Harald Welte9fbff4a2010-07-30 11:50:09 +0200839 /* 1...4 are always present on a C0 TRX */
840 for (i = SYSINFO_TYPE_1; i <= SYSINFO_TYPE_4; i++)
841 bts->si_valid |= (1 << i);
842
843 /* 13 is always present on a C0 TRX of a GPRS BTS */
844 if (bts->gprs.mode != BTS_GPRS_NONE)
845 bts->si_valid |= (1 << SYSINFO_TYPE_13);
Harald Welte6a22c012009-12-21 17:02:32 +0100846 }
847
Harald Welte9fbff4a2010-07-30 11:50:09 +0200848 /* 5 and 6 are always present on every TRX */
849 bts->si_valid |= (1 << SYSINFO_TYPE_5);
850 bts->si_valid |= (1 << SYSINFO_TYPE_6);
Harald Weltea43f7892009-12-01 18:04:30 +0530851
Harald Welte9fbff4a2010-07-30 11:50:09 +0200852 /* Second, we generate and send the selected SI via RSL */
853 for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
854 if (!(bts->si_valid & (1 << i)))
855 continue;
856
857 rc = generate_and_rsl_si(trx, i);
858 if (rc < 0)
859 goto err_out;
860 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200861
862 return 0;
Harald Weltea43f7892009-12-01 18:04:30 +0530863err_out:
Harald Welteb1d4c8e2009-12-17 23:10:46 +0100864 LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
Harald Weltea43f7892009-12-01 18:04:30 +0530865 "a problem with neighbor cell list generation\n",
Harald Welte7401ae62010-06-15 16:44:12 +0200866 i, bts->nr);
Harald Weltea43f7892009-12-01 18:04:30 +0530867 return rc;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200868}
869
Holger Hans Peter Freyther34949ae2010-06-21 10:15:27 +0800870static void patch_16(uint8_t *data, const uint16_t val)
871{
872 memcpy(data, &val, sizeof(val));
873}
874
875static void patch_32(uint8_t *data, const uint32_t val)
876{
877 memcpy(data, &val, sizeof(val));
878}
879
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200880/*
881 * Patch the various SYSTEM INFORMATION tables to update
882 * the LAI
883 */
884static void patch_nm_tables(struct gsm_bts *bts)
885{
886 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
887 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
888
889 /* patch ARFCN into BTS Attributes */
890 bs11_attr_bts[69] &= 0xf0;
891 bs11_attr_bts[69] |= arfcn_high;
892 bs11_attr_bts[70] = arfcn_low;
893 nanobts_attr_bts[42] &= 0xf0;
894 nanobts_attr_bts[42] |= arfcn_high;
895 nanobts_attr_bts[43] = arfcn_low;
896
897 /* patch ARFCN into TRX Attributes */
898 bs11_attr_radio[2] &= 0xf0;
899 bs11_attr_radio[2] |= arfcn_high;
900 bs11_attr_radio[3] = arfcn_low;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200901
Holger Hans Peter Freyther95c22902010-04-25 23:08:39 +0800902 /* patch the RACH attributes */
903 if (bts->rach_b_thresh != -1) {
904 nanobts_attr_bts[33] = bts->rach_b_thresh & 0xff;
905 bs11_attr_bts[33] = bts->rach_b_thresh & 0xff;
906 }
907
908 if (bts->rach_ldavg_slots != -1) {
909 u_int8_t avg_high = bts->rach_ldavg_slots & 0xff;
910 u_int8_t avg_low = (bts->rach_ldavg_slots >> 8) & 0x0f;
911
912 nanobts_attr_bts[35] = avg_high;
913 nanobts_attr_bts[36] = avg_low;
914 bs11_attr_bts[35] = avg_high;
915 bs11_attr_bts[36] = avg_low;
916 }
917
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200918 /* patch BSIC */
919 bs11_attr_bts[1] = bts->bsic;
Harald Welte97a282b2010-03-14 15:37:43 +0800920 nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;
921
922 /* patch CGI */
923 abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200924
925 /* patch the power reduction */
926 bs11_attr_radio[5] = bts->c0->max_power_red / 2;
927 nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
Harald Welte97a282b2010-03-14 15:37:43 +0800928
Harald Weltea5731cf2010-03-22 11:48:36 +0800929 /* patch NSEI */
930 nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8;
931 nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff;
Harald Welte615e9562010-05-11 23:50:21 +0200932 memcpy(nanobts_attr_nse+8, bts->gprs.nse.timer,
933 ARRAY_SIZE(bts->gprs.nse.timer));
934 memcpy(nanobts_attr_nse+18, bts->gprs.cell.timer,
935 ARRAY_SIZE(bts->gprs.cell.timer));
Harald Weltea5731cf2010-03-22 11:48:36 +0800936
Harald Welte97a282b2010-03-14 15:37:43 +0800937 /* patch NSVCI */
938 nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
939 nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;
940
Harald Welteaf387632010-03-14 23:30:30 +0800941 /* patch IP address as SGSN IP */
Holger Hans Peter Freyther34949ae2010-06-21 10:15:27 +0800942 patch_16(nanobts_attr_nsvc0 + 8,
943 htons(bts->gprs.nsvc[0].remote_port));
944 patch_32(nanobts_attr_nsvc0 + 10,
945 htonl(bts->gprs.nsvc[0].remote_ip));
946 patch_16(nanobts_attr_nsvc0 + 14,
947 htons(bts->gprs.nsvc[0].local_port));
Harald Welte97a282b2010-03-14 15:37:43 +0800948
949 /* patch BVCI */
950 nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
951 nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
952 /* patch RAC */
953 nanobts_attr_cell[3] = bts->gprs.rac;
954
Harald Welte439bb822010-04-18 16:50:11 +0200955 if (bts->gprs.mode == BTS_GPRS_EGPRS) {
956 /* patch EGPRS coding schemes MCS 1..9 */
957 nanobts_attr_cell[29] = 0x8f;
958 nanobts_attr_cell[30] = 0xff;
959 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +0200960}
961
Harald Weltefd370892010-06-15 08:52:12 +0200962/* Produce a MA as specified in 10.5.2.21 */
963static int generate_ma_for_ts(struct gsm_bts_trx_ts *ts)
964{
965 /* we have three bitvecs: the per-timeslot ARFCNs, the cell chan ARFCNs
966 * and the MA */
967 struct bitvec *cell_chan = &ts->trx->bts->si_common.cell_alloc;
968 struct bitvec *ts_arfcn = &ts->hopping.arfcns;
969 struct bitvec *ma = &ts->hopping.ma;
Harald Welte29aca172010-06-15 16:45:51 +0200970 unsigned int num_cell_arfcns, bitnum, n_chan;
Harald Weltefd370892010-06-15 08:52:12 +0200971 int i;
972
973 /* re-set the MA to all-zero */
974 ma->cur_bit = 0;
Harald Welte29aca172010-06-15 16:45:51 +0200975 ts->hopping.ma_len = 0;
Harald Weltefd370892010-06-15 08:52:12 +0200976 memset(ma->data, 0, ma->data_len);
977
978 if (!ts->hopping.enabled)
979 return 0;
980
Harald Welte29aca172010-06-15 16:45:51 +0200981 /* count the number of ARFCNs in the cell channel allocation */
982 num_cell_arfcns = 0;
983 for (i = 1; i < 1024; i++) {
984 if (bitvec_get_bit_pos(cell_chan, i))
985 num_cell_arfcns++;
986 }
987
988 /* pad it to octet-aligned number of bits */
989 ts->hopping.ma_len = num_cell_arfcns / 8;
990 if (num_cell_arfcns % 8)
991 ts->hopping.ma_len++;
992
993 n_chan = 0;
Harald Weltefd370892010-06-15 08:52:12 +0200994 for (i = 1; i < 1024; i++) {
995 if (!bitvec_get_bit_pos(cell_chan, i))
996 continue;
Harald Welte29aca172010-06-15 16:45:51 +0200997 /* set the corresponding bit in the MA */
998 bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
Harald Weltefd370892010-06-15 08:52:12 +0200999 if (bitvec_get_bit_pos(ts_arfcn, i))
Harald Welte29aca172010-06-15 16:45:51 +02001000 bitvec_set_bit_pos(ma, bitnum, 1);
Harald Weltefd370892010-06-15 08:52:12 +02001001 else
Harald Welte29aca172010-06-15 16:45:51 +02001002 bitvec_set_bit_pos(ma, bitnum, 0);
laforgeabeb9512010-06-20 15:56:50 +02001003 n_chan++;
Harald Weltefd370892010-06-15 08:52:12 +02001004 }
1005
1006 /* ARFCN 0 is special: It is coded last in the bitmask */
1007 if (bitvec_get_bit_pos(cell_chan, 0)) {
Harald Welte29aca172010-06-15 16:45:51 +02001008 n_chan++;
1009 /* set the corresponding bit in the MA */
1010 bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
Harald Weltefd370892010-06-15 08:52:12 +02001011 if (bitvec_get_bit_pos(ts_arfcn, 0))
Harald Welte29aca172010-06-15 16:45:51 +02001012 bitvec_set_bit_pos(ma, bitnum, 1);
Harald Weltefd370892010-06-15 08:52:12 +02001013 else
Harald Welte29aca172010-06-15 16:45:51 +02001014 bitvec_set_bit_pos(ma, bitnum, 0);
Harald Weltefd370892010-06-15 08:52:12 +02001015 }
1016
1017 return 0;
1018}
1019
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001020static void bootstrap_rsl(struct gsm_bts_trx *trx)
1021{
Harald Weltefd370892010-06-15 08:52:12 +02001022 unsigned int i;
1023
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001024 LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte19a3f0b2009-12-24 13:39:34 +01001025 "on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
1026 trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
1027 bsc_gsmnet->network_code, trx->bts->location_area_code,
1028 trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001029 set_system_infos(trx);
Harald Weltefd370892010-06-15 08:52:12 +02001030
1031 for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
1032 generate_ma_for_ts(&trx->ts[i]);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001033}
1034
1035void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
1036{
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +02001037 int ts_no, lchan_no;
1038
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001039 switch (event) {
1040 case EVT_E1_TEI_UP:
1041 switch (type) {
1042 case E1INP_SIGN_OML:
1043 bootstrap_om(trx->bts);
1044 break;
1045 case E1INP_SIGN_RSL:
1046 bootstrap_rsl(trx);
1047 break;
1048 default:
1049 break;
1050 }
1051 break;
1052 case EVT_E1_TEI_DN:
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +02001053 LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx);
1054
Holger Hans Peter Freytherbb110f92010-04-12 10:45:52 +02001055 if (type == E1INP_SIGN_OML)
1056 counter_inc(trx->bts->network->stats.bts.oml_fail);
1057 else if (type == E1INP_SIGN_RSL)
1058 counter_inc(trx->bts->network->stats.bts.rsl_fail);
1059
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +02001060 /*
1061 * free all allocated channels. change the nm_state so the
1062 * trx and trx_ts becomes unusable and chan_alloc.c can not
1063 * allocate from it.
1064 */
1065 for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
1066 struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
1067
1068 for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
Holger Hans Peter Freyther4dc025b2010-08-25 12:29:24 +08001069 if (ts->lchan[lchan_no].state != LCHAN_S_NONE)
Holger Hans Peter Freyther135f7972010-04-15 11:21:02 +02001070 lchan_free(&ts->lchan[lchan_no]);
1071 lchan_reset(&ts->lchan[lchan_no]);
1072 }
1073
1074 ts->nm_state.operational = 0;
1075 ts->nm_state.availability = 0;
1076 }
1077
1078 trx->nm_state.operational = 0;
1079 trx->nm_state.availability = 0;
1080 trx->bb_transc.nm_state.operational = 0;
1081 trx->bb_transc.nm_state.availability = 0;
Holger Hans Peter Freyther6f615552010-11-15 20:50:42 +01001082
1083 abis_nm_clear_queue(trx->bts);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001084 break;
1085 default:
1086 break;
1087 }
1088}
1089
1090static int bootstrap_bts(struct gsm_bts *bts)
1091{
Sylvain Munaut50f81b02010-04-28 21:31:29 +02001092 int i, n;
1093
Harald Welte71b822b2010-05-26 17:14:42 +02001094 /* FIXME: What about secondary TRX of a BTS? What about a BTS that has TRX
1095 * in different bands? Why is 'band' a parameter of the BTS and not of the TRX? */
Mike Habene2d82272009-10-02 12:19:34 +01001096 switch (bts->band) {
1097 case GSM_BAND_1800:
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001098 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001099 LOGP(DNM, LOGL_ERROR, "GSM1800 channel must be between 512-885.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001100 return -EINVAL;
1101 }
1102 break;
Mike Habene2d82272009-10-02 12:19:34 +01001103 case GSM_BAND_1900:
1104 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 810) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001105 LOGP(DNM, LOGL_ERROR, "GSM1900 channel must be between 512-810.\n");
Mike Habene2d82272009-10-02 12:19:34 +01001106 return -EINVAL;
1107 }
1108 break;
1109 case GSM_BAND_900:
Holger Hans Peter Freytherfb0b6fc2010-02-09 15:44:14 +01001110 if (bts->c0->arfcn < 1 ||
1111 (bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
1112 bts->c0->arfcn > 1023) {
1113 LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001114 return -EINVAL;
1115 }
1116 break;
Harald Welte71b822b2010-05-26 17:14:42 +02001117 case GSM_BAND_850:
1118 if (bts->c0->arfcn < 128 || bts->c0->arfcn > 251) {
1119 LOGP(DNM, LOGL_ERROR, "GSM850 channel must be between 128-251.\n");
1120 return -EINVAL;
1121 }
1122 break;
Mike Habene2d82272009-10-02 12:19:34 +01001123 default:
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001124 LOGP(DNM, LOGL_ERROR, "Unsupported frequency band.\n");
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001125 return -EINVAL;
1126 }
1127
Harald Welted6aa5242009-12-12 13:44:19 +01001128 if (bts->network->auth_policy == GSM_AUTH_POLICY_ACCEPT_ALL &&
Harald Welte71355012009-12-21 23:08:18 +01001129 !bts->si_common.rach_control.cell_bar)
Harald Weltea992a362009-12-21 23:36:45 +01001130 LOGP(DNM, LOGL_ERROR, "\nWARNING: You are running an 'accept-all' "
Harald Welted6aa5242009-12-12 13:44:19 +01001131 "network on a BTS that is not barred. This "
1132 "configuration is likely to interfere with production "
1133 "GSM networks and should only be used in a RF "
1134 "shielded environment such as a faraday cage!\n\n");
1135
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001136 /* Control Channel Description */
Harald Weltea43f7892009-12-01 18:04:30 +05301137 bts->si_common.chan_desc.att = 1;
Harald Weltea43f7892009-12-01 18:04:30 +05301138 bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
Harald Welteaace9fc2011-01-13 23:20:45 +01001139 bts->si_common.chan_desc.bs_ag_blks_res = 1;
1140
Holger Hans Peter Freythera5811362010-04-30 13:32:05 +08001141 /* T3212 is set from vty/config */
Sylvain Munaut50f81b02010-04-28 21:31:29 +02001142
Holger Hans Peter Freythera5811362010-04-30 13:32:05 +08001143 /* Set ccch config by looking at ts config */
Sylvain Munaut50f81b02010-04-28 21:31:29 +02001144 for (n=0, i=0; i<8; i++)
1145 n += bts->c0->ts[i].pchan == GSM_PCHAN_CCCH ? 1 : 0;
1146
1147 switch (n) {
1148 case 0:
1149 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1150 break;
1151 case 1:
1152 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_NC;
1153 break;
1154 case 2:
1155 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_2_NC;
1156 break;
1157 case 3:
1158 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_3_NC;
1159 break;
1160 case 4:
1161 bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_4_NC;
1162 break;
1163 default:
1164 LOGP(DNM, LOGL_ERROR, "Unsupported CCCH timeslot configuration\n");
1165 return -EINVAL;
1166 }
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001167
Harald Weltea43f7892009-12-01 18:04:30 +05301168 /* some defaults for our system information */
Holger Hans Peter Freyther5a3a61d2010-09-06 09:25:48 +08001169 bts->si_common.cell_options.radio_link_timeout = 7; /* 12 */
1170
1171 /* allow/disallow DTXu */
1172 if (bts->network->dtx_enabled)
1173 bts->si_common.cell_options.dtx = 0;
1174 else
1175 bts->si_common.cell_options.dtx = 2;
1176
Harald Weltea43f7892009-12-01 18:04:30 +05301177 bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
1178
Harald Weltea43f7892009-12-01 18:04:30 +05301179 bts->si_common.cell_sel_par.acs = 0;
Harald Weltea43f7892009-12-01 18:04:30 +05301180
1181 bts->si_common.ncc_permitted = 0xff;
1182
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001183 paging_init(bts);
1184
1185 return 0;
1186}
1187
Harald Welte29b64e92010-12-23 01:07:46 +01001188int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *),
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001189 const char *config_file)
1190{
Harald Weltedcccb182010-05-16 20:52:23 +02001191 struct telnet_connection dummy_conn;
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001192 struct gsm_bts *bts;
1193 int rc;
1194
1195 /* initialize our data structures */
1196 bsc_gsmnet = gsm_network_init(1, 1, mncc_recv);
1197 if (!bsc_gsmnet)
1198 return -ENOMEM;
1199
1200 bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
1201 bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
1202
Harald Weltedcccb182010-05-16 20:52:23 +02001203 /* our vty command code expects vty->priv to point to a telnet_connection */
1204 dummy_conn.priv = bsc_gsmnet;
1205 rc = vty_read_config_file(config_file, &dummy_conn);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001206 if (rc < 0) {
Harald Welteb1d4c8e2009-12-17 23:10:46 +01001207 LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001208 return rc;
1209 }
1210
Harald Weltedcccb182010-05-16 20:52:23 +02001211 rc = telnet_init(tall_bsc_ctx, bsc_gsmnet, 4242);
1212 if (rc < 0)
1213 return rc;
1214
Holger Hans Peter Freyther8b457fb2009-08-17 06:55:10 +02001215 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1216
1217 llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
1218 bootstrap_bts(bts);
1219 if (!is_ipaccess_bts(bts))
1220 rc = e1_reconfig_bts(bts);
1221
1222 if (rc < 0)
1223 exit (1);
1224 }
1225
1226 /* initialize nanoBTS support omce */
1227 rc = ipaccess_setup(bsc_gsmnet);
1228
1229 return 0;
1230}