blob: 56684cc31232a0c29338b4643e4fb7c8cc8b57cd [file] [log] [blame]
Harald Welte59b04682009-06-10 05:40:52 +08001/* 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 <unistd.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <stdarg.h>
27#include <time.h>
28#include <string.h>
29#include <errno.h>
30#include <signal.h>
31#include <fcntl.h>
32#include <sys/stat.h>
33
34#define _GNU_SOURCE
35#include <getopt.h>
36
37#include <openbsc/db.h>
38#include <openbsc/timer.h>
39#include <openbsc/gsm_data.h>
Harald Weltec4dcda02009-08-09 14:45:18 +020040#include <openbsc/gsm_utils.h>
Harald Welte59b04682009-06-10 05:40:52 +080041#include <openbsc/gsm_04_08.h>
42#include <openbsc/select.h>
43#include <openbsc/abis_rsl.h>
44#include <openbsc/abis_nm.h>
45#include <openbsc/debug.h>
46#include <openbsc/misdn.h>
47#include <openbsc/telnet_interface.h>
48#include <openbsc/paging.h>
49#include <openbsc/e1_input.h>
50#include <openbsc/signal.h>
Harald Weltea8379772009-06-20 22:36:41 +020051#include <openbsc/talloc.h>
52
Harald Welte59b04682009-06-10 05:40:52 +080053/* global pointer to the gsm network data structure */
54static struct gsm_network *gsmnet;
55
56/* MCC and MNC for the Location Area Identifier */
57static int MCC = 1;
58static int MNC = 1;
Harald Welte59b04682009-06-10 05:40:52 +080059static int cardnr = 0;
60static int release_l2 = 0;
61static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
62static const char *database_name = "hlr.sqlite3";
Harald Welte3c062072009-07-28 18:25:29 +020063extern int ipacc_rtp_direct;
Harald Welte59b04682009-06-10 05:40:52 +080064
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +020065
Harald Welte59b04682009-06-10 05:40:52 +080066/* The following definitions are for OM and NM packets that we cannot yet
67 * generate by code but we just pass on */
68
69// BTS Site Manager, SET ATTRIBUTES
70
71/*
72 Object Class: BTS Site Manager
73 Instance 1: FF
74 Instance 2: FF
75 Instance 3: FF
76SET ATTRIBUTES
77 sAbisExternalTime: 2007/09/08 14:36:11
78 omLAPDRelTimer: 30sec
79 shortLAPDIntTimer: 5sec
80 emergencyTimer1: 10 minutes
81 emergencyTimer2: 0 minutes
82*/
83
84unsigned char msg_1[] =
85{
Harald Weltef739ae62009-06-20 10:42:17 +020086 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +080087 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
88 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
89 0x02,
90 0x00, 0x1E,
91 NM_ATT_BS11_SH_LAPD_INT_TIMER,
92 0x01, 0x05,
93 0x42, 0x02, 0x00, 0x0A,
94 0x44, 0x02, 0x00, 0x00
95};
96
97// BTS, SET BTS ATTRIBUTES
98
99/*
100 Object Class: BTS
101 BTS relat. Number: 0
102 Instance 2: FF
103 Instance 3: FF
104SET BTS ATTRIBUTES
105 bsIdentityCode / BSIC:
106 PLMN_colour_code: 7h
107 BS_colour_code: 7h
108 BTS Air Timer T3105: 4 ,unit 10 ms
109 btsIsHopping: FALSE
110 periodCCCHLoadIndication: 1sec
111 thresholdCCCHLoadIndication: 0%
112 cellAllocationNumber: 00h = GSM 900
113 enableInterferenceClass: 00h = Disabled
114 fACCHQual: 6 (FACCH stealing flags minus 1)
115 intaveParameter: 31 SACCH multiframes
116 interferenceLevelBoundaries:
117 Interference Boundary 1: 0Ah
118 Interference Boundary 2: 0Fh
119 Interference Boundary 3: 14h
120 Interference Boundary 4: 19h
121 Interference Boundary 5: 1Eh
122 mSTxPwrMax: 11
123 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
124 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
125 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
126 30=33dBm, 31=32dBm
127 ny1:
128 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
129 powerOutputThresholds:
130 Out Power Fault Threshold: -10 dB
131 Red Out Power Threshold: - 6 dB
132 Excessive Out Power Threshold: 5 dB
133 rACHBusyThreshold: -127 dBm
134 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
135 rfResourceIndicationPeriod: 125 SACCH multiframes
136 T200:
137 SDCCH: 044 in 5 ms
138 FACCH/Full rate: 031 in 5 ms
139 FACCH/Half rate: 041 in 5 ms
140 SACCH with TCH SAPI0: 090 in 10 ms
141 SACCH with SDCCH: 090 in 10 ms
142 SDCCH with SAPI3: 090 in 5 ms
143 SACCH with TCH SAPI3: 135 in 10 ms
144 tSync: 9000 units of 10 msec
145 tTrau: 9000 units of 10 msec
146 enableUmLoopTest: 00h = disabled
147 enableExcessiveDistance: 00h = Disabled
148 excessiveDistance: 64km
149 hoppingMode: 00h = baseband hopping
150 cellType: 00h = Standard Cell
151 BCCH ARFCN / bCCHFrequency: 1
152*/
153
Harald Weltef739ae62009-06-20 10:42:17 +0200154static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800155{
Harald Welte59b04682009-06-10 05:40:52 +0800156 NM_ATT_BSIC, HARDCODED_BSIC,
157 NM_ATT_BTS_AIR_TIMER, 0x04,
158 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
159 NM_ATT_CCCH_L_I_P, 0x01,
160 NM_ATT_CCCH_L_T, 0x00,
161 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
162 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
163 NM_ATT_BS11_FACCH_QUAL, 0x06,
164 /* interference avg. period in numbers of SACCH multifr */
165 NM_ATT_INTAVE_PARAM, 0x1F,
166 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
167 NM_ATT_CCCH_L_T, 0x23,
168 NM_ATT_GSM_TIME, 0x28, 0x00,
169 NM_ATT_ADM_STATE, 0x03,
170 NM_ATT_RACH_B_THRESH, 0x7F,
171 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
172 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
173 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
174 NM_ATT_BS11_TSYNC, 0x23, 0x28,
175 NM_ATT_BS11_TTRAU, 0x23, 0x28,
176 NM_ATT_TEST_DUR, 0x01, 0x00,
177 NM_ATT_OUTST_ALARM, 0x01, 0x00,
178 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
179 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
180 NM_ATT_BS11_PLL, 0x01, 0x00,
181 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
182};
183
184// Handover Recognition, SET ATTRIBUTES
185
186/*
187Illegal Contents GSM Formatted O&M Msg
188 Object Class: Handover Recognition
189 BTS relat. Number: 0
190 Instance 2: FF
191 Instance 3: FF
192SET ATTRIBUTES
193 enableDelayPowerBudgetHO: 00h = Disabled
194 enableDistanceHO: 00h = Disabled
195 enableInternalInterCellHandover: 00h = Disabled
196 enableInternalIntraCellHandover: 00h = Disabled
197 enablePowerBudgetHO: 00h = Disabled
198 enableRXLEVHO: 00h = Disabled
199 enableRXQUALHO: 00h = Disabled
200 hoAveragingDistance: 8 SACCH multiframes
201 hoAveragingLev:
202 A_LEV_HO: 8 SACCH multiframes
203 W_LEV_HO: 1 SACCH multiframes
204 hoAveragingPowerBudget: 16 SACCH multiframes
205 hoAveragingQual:
206 A_QUAL_HO: 8 SACCH multiframes
207 W_QUAL_HO: 2 SACCH multiframes
208 hoLowerThresholdLevDL: (10 - 110) dBm
209 hoLowerThresholdLevUL: (5 - 110) dBm
210 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
211 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
212 hoThresholdLevDLintra : (20 - 110) dBm
213 hoThresholdLevULintra: (20 - 110) dBm
214 hoThresholdMsRangeMax: 20 km
215 nCell: 06h
216 timerHORequest: 3 ,unit 2 SACCH multiframes
217*/
218
219unsigned char msg_3[] =
220{
Harald Weltef739ae62009-06-20 10:42:17 +0200221 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Weltec7d75062009-07-18 16:18:11 +0200222 0xD0, 0x00, /* enableDelayPowerBudgetHO */
223 0x64, 0x00, /* enableDistanceHO */
224 0x67, 0x00, /* enableInternalInterCellHandover */
225 0x68, 0x00, /* enableInternalInterCellHandover */
226 0x6A, 0x00, /* enablePowerBudgetHO */
227 0x6C, 0x00, /* enableRXLEVHO */
228 0x6D, 0x00, /* enableRXQUALHO */
229 0x6F, 0x08, /* hoAveragingDistance */
230 0x70, 0x08, 0x01, /* hoAveragingLev */
Harald Welte59b04682009-06-10 05:40:52 +0800231 0x71, 0x10, 0x10, 0x10,
Harald Weltec7d75062009-07-18 16:18:11 +0200232 0x72, 0x08, 0x02, /* hoAveragingQual */
233 0x73, 0x0A, /* hoLowerThresholdLevDL */
234 0x74, 0x05, /* hoLowerThresholdLevUL */
235 0x75, 0x06, /* hoLowerThresholdQualDL */
236 0x76, 0x06, /* hoLowerThresholdQualUL */
237 0x78, 0x14, /* hoThresholdLevDLintra */
238 0x79, 0x14, /* hoThresholdLevULintra */
239 0x7A, 0x14, /* hoThresholdMsRangeMax */
240 0x7D, 0x06, /* nCell */
241 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
242 0x20, 0x01, 0x00,
Harald Welte59b04682009-06-10 05:40:52 +0800243 0x45, 0x01, 0x00,
244 0x48, 0x01, 0x00,
245 0x5A, 0x01, 0x00,
246 0x5B, 0x01, 0x05,
247 0x5E, 0x01, 0x1A,
248 0x5F, 0x01, 0x20,
249 0x9D, 0x01, 0x00,
250 0x47, 0x01, 0x00,
251 0x5C, 0x01, 0x64,
252 0x5D, 0x01, 0x1E,
253 0x97, 0x01, 0x20,
254 0xF7, 0x01, 0x3C,
255};
256
257// Power Control, SET ATTRIBUTES
258
259/*
260 Object Class: Power Control
261 BTS relat. Number: 0
262 Instance 2: FF
263 Instance 3: FF
264SET ATTRIBUTES
265 enableMsPowerControl: 00h = Disabled
266 enablePowerControlRLFW: 00h = Disabled
267 pcAveragingLev:
268 A_LEV_PC: 4 SACCH multiframes
269 W_LEV_PC: 1 SACCH multiframes
270 pcAveragingQual:
271 A_QUAL_PC: 4 SACCH multiframes
272 W_QUAL_PC: 2 SACCH multiframes
273 pcLowerThresholdLevDL: 0Fh
274 pcLowerThresholdLevUL: 0Ah
275 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
276 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
277 pcRLFThreshold: 0Ch
278 pcUpperThresholdLevDL: 14h
279 pcUpperThresholdLevUL: 0Fh
280 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
281 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
282 powerConfirm: 2 ,unit 2 SACCH multiframes
283 powerControlInterval: 2 ,unit 2 SACCH multiframes
284 powerIncrStepSize: 02h = 4 dB
285 powerRedStepSize: 01h = 2 dB
286 radioLinkTimeoutBs: 64 SACCH multiframes
287 enableBSPowerControl: 00h = disabled
288*/
289
290unsigned char msg_4[] =
291{
Harald Weltef739ae62009-06-20 10:42:17 +0200292 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800293 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
294 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Weltec7d75062009-07-18 16:18:11 +0200295 0x7E, 0x04, 0x01, /* pcAveragingLev */
296 0x7F, 0x04, 0x02, /* pcAveragingQual */
297 0x80, 0x0F, /* pcLowerThresholdLevDL */
298 0x81, 0x0A, /* pcLowerThresholdLevUL */
299 0x82, 0x05, /* pcLowerThresholdQualDL */
300 0x83, 0x05, /* pcLowerThresholdQualUL */
301 0x84, 0x0C, /* pcRLFThreshold */
302 0x85, 0x14, /* pcUpperThresholdLevDL */
303 0x86, 0x0F, /* pcUpperThresholdLevUL */
304 0x87, 0x04, /* pcUpperThresholdQualDL */
305 0x88, 0x04, /* pcUpperThresholdQualUL */
306 0x89, 0x02, /* powerConfirm */
307 0x8A, 0x02, /* powerConfirmInterval */
308 0x8B, 0x02, /* powerIncrStepSize */
309 0x8C, 0x01, /* powerRedStepSize */
310 0x8D, 0x40, /* radioLinkTimeoutBs */
Harald Welte59b04682009-06-10 05:40:52 +0800311 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
312};
313
314
315// Transceiver, SET TRX ATTRIBUTES (TRX 0)
316
317/*
318 Object Class: Transceiver
319 BTS relat. Number: 0
320 Tranceiver number: 0
321 Instance 3: FF
322SET TRX ATTRIBUTES
323 aRFCNList (HEX): 0001
324 txPwrMaxReduction: 00h = 30dB
325 radioMeasGran: 254 SACCH multiframes
326 radioMeasRep: 01h = enabled
327 memberOfEmergencyConfig: 01h = TRUE
328 trxArea: 00h = TRX doesn't belong to a concentric cell
329*/
330
Harald Weltef739ae62009-06-20 10:42:17 +0200331static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800332{
Harald Welte59b04682009-06-10 05:40:52 +0800333 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
334 NM_ATT_RF_MAXPOWR_R, 0x00,
335 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
336 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
337 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
338 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
339};
340
341static unsigned char nanobts_attr_bts[] = {
342 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
343 /* interference avg. period in numbers of SACCH multifr */
344 NM_ATT_INTAVE_PARAM, 0x06,
345 /* conn fail based on SACCH error rate */
346 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
347 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
348 NM_ATT_MAX_TA, 0x3f,
349 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
350 NM_ATT_CCCH_L_T, 10, /* percent */
351 NM_ATT_CCCH_L_I_P, 1, /* seconds */
352 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
353 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
354 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
355 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
356 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
357 NM_ATT_BSIC, HARDCODED_BSIC,
358};
359
360static unsigned char nanobts_attr_radio[] = {
361 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
362 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
363};
364
365static unsigned char nanobts_attr_e0[] = {
Harald Welte4206d982009-07-12 09:33:54 +0200366 NM_ATT_IPACC_STREAM_ID, 0x00,
367 NM_ATT_IPACC_DST_IP_PORT, 0x0b, 0xbb, /* TCP PORT for RSL */
Harald Welte59b04682009-06-10 05:40:52 +0800368};
369
370/* Callback function to be called whenever we get a GSM 12.21 state change event */
371int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
372 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
373{
374 struct gsm_bts *bts;
375 struct gsm_bts_trx *trx;
376 struct gsm_bts_trx_ts *ts;
377
378 /* This is currently only required on nanoBTS */
379
380 switch (evt) {
381 case EVT_STATECHG_OPER:
382 switch (obj_class) {
383 case NM_OC_SITE_MANAGER:
384 bts = container_of(obj, struct gsm_bts, site_mgr);
385 if (old_state->operational != 2 && new_state->operational == 2) {
386 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
387 }
388 break;
389 case NM_OC_BTS:
390 bts = obj;
391 if (new_state->availability == 5) {
392 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
393 sizeof(nanobts_attr_bts));
394 abis_nm_opstart(bts, NM_OC_BTS,
395 bts->bts_nr, 0xff, 0xff);
396 abis_nm_chg_adm_state(bts, NM_OC_BTS,
397 bts->bts_nr, 0xff, 0xff,
398 NM_STATE_UNLOCKED);
399 }
400 break;
401 case NM_OC_CHANNEL:
402 ts = obj;
403 trx = ts->trx;
404 if (new_state->availability == 5) {
405 if (ts->nr == 0 && trx == trx->bts->c0)
Harald Welte7f863f52009-08-09 22:01:26 +0200406 abis_nm_set_channel_attr(ts, NM_CHANC_BCCHComb);
Harald Welte59b04682009-06-10 05:40:52 +0800407 else
408 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
409 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
410 trx->bts->bts_nr, trx->nr, ts->nr);
411 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
412 trx->bts->bts_nr, trx->nr, ts->nr,
413 NM_STATE_UNLOCKED);
414 }
415 break;
416 default:
417 break;
418 }
419 break;
420 default:
421 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
422 break;
423 }
424 return 0;
425}
426
427/* Callback function to be called every time we receive a 12.21 SW activated report */
428static int sw_activ_rep(struct msgb *mb)
429{
430 struct abis_om_fom_hdr *foh = msgb_l3(mb);
431 struct gsm_bts_trx *trx = mb->trx;
432
433 switch (foh->obj_class) {
434 case NM_OC_BASEB_TRANSC:
435 /* TRX software is active, tell it to initiate RSL Link */
436 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
437 trx->bts->bts_nr, trx->nr, 0xff,
438 nanobts_attr_e0, sizeof(nanobts_attr_e0));
439 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
440 trx->bts->bts_nr, trx->nr, 0xff);
441 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
442 trx->bts->bts_nr, trx->nr, 0xff,
443 NM_STATE_UNLOCKED);
444 break;
445 case NM_OC_RADIO_CARRIER:
446 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
447 sizeof(nanobts_attr_radio));
448 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
449 trx->bts->bts_nr, trx->nr, 0xff);
450 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
451 trx->bts->bts_nr, trx->nr, 0xff,
452 NM_STATE_UNLOCKED);
453 break;
454 }
455 return 0;
456}
457
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200458/* Callback function for NACK on the OML NM */
459static int oml_msg_nack(int mt)
460{
461 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
462 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
463 "Was the bts type and frequency properly specified?\n");
464 exit(-1);
465 }
466
467 return 0;
468}
469
Harald Welte59b04682009-06-10 05:40:52 +0800470/* Callback function to be called every time we receive a signal from NM */
471static int nm_sig_cb(unsigned int subsys, unsigned int signal,
472 void *handler_data, void *signal_data)
473{
474 switch (signal) {
475 case S_NM_SW_ACTIV_REP:
476 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200477 case S_NM_NACK:
478 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800479 default:
480 break;
481 }
482 return 0;
483}
484
485static void bootstrap_om_nanobts(struct gsm_bts *bts)
486{
487 /* We don't do callback based bootstrapping, but event driven (see above) */
488}
489
490static void bootstrap_om_bs11(struct gsm_bts *bts)
491{
Harald Weltee712a5f2009-06-21 16:17:15 +0200492 struct gsm_bts_trx *trx = bts->c0;
Harald Weltecf833cd2009-08-06 17:40:24 +0200493 int base_ts;
494
495 switch (bts->nr) {
496 case 0:
497 /* First BTS uses E1 TS 01,02,03,04,05 */
498 base_ts = HARDCODED_BTS0_TS - 1;
499 break;
500 case 1:
501 /* Second BTS uses E1 TS 06,07,08,09,10 */
502 base_ts = HARDCODED_BTS1_TS - 1;
503 break;
504 case 2:
505 /* Third BTS uses E1 TS 11,12,13,14,15 */
506 base_ts = HARDCODED_BTS2_TS - 1;
507 default:
508 return;
509 }
Harald Welte59b04682009-06-10 05:40:52 +0800510
511 /* stop sending event reports */
512 abis_nm_event_reports(bts, 0);
513
514 /* begin DB transmission */
515 abis_nm_bs11_db_transmission(bts, 1);
516
517 /* end DB transmission */
518 abis_nm_bs11_db_transmission(bts, 0);
519
520 /* Reset BTS Site manager resource */
521 abis_nm_bs11_reset_resource(bts);
522
523 /* begin DB transmission */
524 abis_nm_bs11_db_transmission(bts, 1);
525
526 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltef739ae62009-06-20 10:42:17 +0200527 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800528 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
529 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
530
531 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200532 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Weltef739ae62009-06-20 10:42:17 +0200533 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800534
535 /* Use TEI 1 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200536 abis_nm_establish_tei(bts, 0, 0, base_ts+1, 0xff, 0x01);
Harald Welte7f863f52009-08-09 22:01:26 +0200537 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_BCCHComb);
Harald Welte59b04682009-06-10 05:40:52 +0800538
Harald Welte59b04682009-06-10 05:40:52 +0800539 /* SET CHANNEL ATTRIBUTE TS1 */
540 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
541 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200542 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+2, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800543
544 /* SET CHANNEL ATTRIBUTE TS2 */
545 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
546 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200547 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+2, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800548
549 /* SET CHANNEL ATTRIBUTE TS3 */
550 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
551 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200552 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+2, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800553
554 /* SET CHANNEL ATTRIBUTE TS4 */
555 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
556 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200557 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+3, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800558
559 /* SET CHANNEL ATTRIBUTE TS5 */
560 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
561 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200562 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+3, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800563
564 /* SET CHANNEL ATTRIBUTE TS6 */
565 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
566 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200567 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+3, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800568
569 /* SET CHANNEL ATTRIBUTE TS7 */
570 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
571 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200572 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+3, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800573
Harald Welte25b70c52009-07-29 16:42:16 +0200574 trx = gsm_bts_trx_num(bts, 1);
575 if (trx) {
576 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
577 u_int8_t arfcn_low = trx->arfcn & 0xff;
578 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
579 memcpy(trx1_attr_radio, bs11_attr_radio,
580 sizeof(trx1_attr_radio));
581
582 /* patch ARFCN into TRX Attributes */
583 trx1_attr_radio[2] &= 0xf0;
584 trx1_attr_radio[2] |= arfcn_high;
585 trx1_attr_radio[3] = arfcn_low;
586
587 /* Connect signalling of TRX1 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200588 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Welte25b70c52009-07-29 16:42:16 +0200589 /* FIXME: TRX ATTRIBUTE */
590 abis_nm_set_radio_attr(trx, trx1_attr_radio,
591 sizeof(trx1_attr_radio));
592
593 /* Use TEI 2 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200594 abis_nm_establish_tei(bts, 1, 0, base_ts+1, 0xff, 0x02);
Harald Welte25b70c52009-07-29 16:42:16 +0200595
Harald Welte1a503162009-08-04 01:31:53 +0200596 /* SET CHANNEL ATTRIBUTE TS0 */
Harald Welte7f863f52009-08-09 22:01:26 +0200597 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH);
Harald Welte1a503162009-08-04 01:31:53 +0200598 /* Connect traffic of bts0/trx0/ts0 to e1_0/ts4/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200599 abis_nm_conn_terr_traf(&trx->ts[0], 0, base_ts+4, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200600
601 /* SET CHANNEL ATTRIBUTE TS1 */
602 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
603 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200604 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+4, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200605
606 /* SET CHANNEL ATTRIBUTE TS2 */
607 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
608 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200609 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+4, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200610
611 /* SET CHANNEL ATTRIBUTE TS3 */
612 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
613 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200614 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+4, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200615
616 /* SET CHANNEL ATTRIBUTE TS4 */
617 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
618 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200619 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+5, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200620
621 /* SET CHANNEL ATTRIBUTE TS5 */
622 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
623 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200624 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+5, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200625
626 /* SET CHANNEL ATTRIBUTE TS6 */
627 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
628 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200629 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+5, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200630
631 /* SET CHANNEL ATTRIBUTE TS7 */
632 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
633 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200634 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+5, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200635 }
636
Harald Welte59b04682009-06-10 05:40:52 +0800637 /* end DB transmission */
638 abis_nm_bs11_db_transmission(bts, 0);
639
640 /* Reset BTS Site manager resource */
641 abis_nm_bs11_reset_resource(bts);
642
643 /* restart sending event reports */
644 abis_nm_event_reports(bts, 1);
645}
646
647static void bootstrap_om(struct gsm_bts *bts)
648{
649 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
650
651 switch (bts->type) {
652 case GSM_BTS_TYPE_BS11:
653 bootstrap_om_bs11(bts);
654 break;
655 case GSM_BTS_TYPE_NANOBTS_900:
656 case GSM_BTS_TYPE_NANOBTS_1800:
657 bootstrap_om_nanobts(bts);
658 break;
659 default:
660 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
661 }
662}
663
664static int shutdown_om(struct gsm_bts *bts)
665{
Harald Welte3b714502009-08-06 17:43:50 +0200666 fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
667
Harald Welte59b04682009-06-10 05:40:52 +0800668 /* stop sending event reports */
669 abis_nm_event_reports(bts, 0);
670
671 /* begin DB transmission */
672 abis_nm_bs11_db_transmission(bts, 1);
673
674 /* end DB transmission */
675 abis_nm_bs11_db_transmission(bts, 0);
676
677 /* Reset BTS Site manager resource */
678 abis_nm_bs11_reset_resource(bts);
679
680 return 0;
681}
682
683static int shutdown_net(struct gsm_network *net)
684{
Harald Weltee712a5f2009-06-21 16:17:15 +0200685 struct gsm_bts *bts;
686
687 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welte59b04682009-06-10 05:40:52 +0800688 int rc;
Harald Weltee712a5f2009-06-21 16:17:15 +0200689 rc = shutdown_om(bts);
Harald Welte59b04682009-06-10 05:40:52 +0800690 if (rc < 0)
691 return rc;
692 }
693
694 return 0;
695}
696
697struct bcch_info {
698 u_int8_t type;
699 u_int8_t len;
700 const u_int8_t *data;
701};
702
703/*
704SYSTEM INFORMATION TYPE 1
705 Cell channel description
706 Format-ID bit map 0
707 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
708 RACH Control Parameters
709 maximum 7 retransmissions
710 8 slots used to spread transmission
711 cell not barred for access
712 call reestablishment not allowed
713 Access Control Class = 0000
714*/
715static u_int8_t si1[] = {
716 /* header */0x55, 0x06, 0x19,
717 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
719 /* rach */0xD5, 0x00, 0x00,
720 /* s1 reset*/0x2B
721};
722
723/*
724 SYSTEM INFORMATION TYPE 2
725 Neighbour Cells Description
726 EXT-IND: Carries the complete BA
727 BA-IND = 0
728 Format-ID bit map 0
729 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
730 NCC permitted (NCC) = FF
731 RACH Control Parameters
732 maximum 7 retransmissions
733 8 slots used to spread transmission
734 cell not barred for access
735 call reestablishment not allowed
736 Access Control Class = 0000
737*/
738static u_int8_t si2[] = {
739 /* header */0x59, 0x06, 0x1A,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742 /* ncc */0xFF,
743 /* rach*/0xD5, 0x00, 0x00
744};
745
746/*
747SYSTEM INFORMATION TYPE 3
748 Cell identity = 00001 (1h)
749 Location area identification
750 Mobile Country Code (MCC): 001
751 Mobile Network Code (MNC): 01
752 Location Area Code (LAC): 00001 (1h)
753 Control Channel Description
754 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
755 0 blocks reserved for access grant
756 1 channel used for CCCH, with SDCCH
757 5 multiframes period for PAGING REQUEST
758 Time-out T3212 = 0
759 Cell Options BCCH
760 Power control indicator: not set
761 MSs shall not use uplink DTX
762 Radio link timeout = 36
763 Cell Selection Parameters
764 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
765 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
766 Additional Reselect Parameter Indication (ACS) = only SYSTEM INFO 4: The SI rest octets, if present, shall be used to derive the value of PI and possibly C2 parameters
767 Half rate support (NECI): New establishment causes are not supported
768 min.RX signal level for MS = 0
769 RACH Control Parameters
770 maximum 7 retransmissions
771 8 slots used to spread transmission
772 cell not barred for access
773 call reestablishment not allowed
774 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200775 SI 3 Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800776*/
777static u_int8_t si3[] = {
778 /* header */0x49, 0x06, 0x1B,
779 /* cell */0x00, 0x01,
780 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
781 /* desc */0x01, 0x03, 0x00,
782 /* option*/0x28,
783 /* selection*/0x62, 0x00,
784 /* rach */0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200785 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800786};
787
788/*
789SYSTEM INFORMATION TYPE 4
790 Location area identification
791 Mobile Country Code (MCC): 001
792 Mobile Network Code (MNC): 01
793 Location Area Code (LAC): 00001 (1h)
794 Cell Selection Parameters
795 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
796 max.TX power level MS may use for CCH = 2
797 Additional Reselect Parameter Indication (ACS) = only SYSTEM INFO 4: The SI rest octets, if present, shall be used to derive the value of PI and possibly C2 parameters
798 Half rate support (NECI): New establishment causes are not supported
799 min.RX signal level for MS = 0
800 RACH Control Parameters
801 maximum 7 retransmissions
802 8 slots used to spread transmission
803 cell not barred for access
804 call reestablishment not allowed
805 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200806 CBCH Channel Description
Harald Welte59b04682009-06-10 05:40:52 +0800807 Type = SDCCH/4[2]
808 Timeslot Number: 0
809 Training Sequence Code: 7h
810 ARFCN: 1
Harald Weltec1c4a952009-07-05 13:41:40 +0200811 SI Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800812*/
813static u_int8_t si4[] = {
814 /* header */0x41, 0x06, 0x1C,
815 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
816 /* sel */0x62, 0x00,
817 /* rach*/0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200818 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
819 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800820};
821
822/*
823 SYSTEM INFORMATION TYPE 5
824 Neighbour Cells Description
825 EXT-IND: Carries the complete BA
826 BA-IND = 0
827 Format-ID bit map 0
828 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
829*/
830
831static u_int8_t si5[] = {
832 /* header without l2 len*/0x06, 0x1D,
833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
835};
836
837// SYSTEM INFORMATION TYPE 6
838
839/*
840SACCH FILLING
841 System Info Type: SYSTEM INFORMATION 6
842 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
843
844SYSTEM INFORMATION TYPE 6
845 Cell identity = 00001 (1h)
846 Location area identification
847 Mobile Country Code (MCC): 001
848 Mobile Network Code (MNC): 01
849 Location Area Code (LAC): 00001 (1h)
850 Cell Options SACCH
851 Power control indicator: not set
852 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
853 Radio link timeout = 36
854 NCC permitted (NCC) = FF
855*/
856
857static u_int8_t si6[] = {
858 /* header */0x06, 0x1E,
859 /* cell id*/ 0x00, 0x01,
860 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
861 /* options */ 0x28,
862 /* ncc */ 0xFF,
863};
864
865
866
867static const struct bcch_info bcch_infos[] = {
868 {
869 .type = RSL_SYSTEM_INFO_1,
870 .len = sizeof(si1),
871 .data = si1,
872 }, {
873 .type = RSL_SYSTEM_INFO_2,
874 .len = sizeof(si2),
875 .data = si2,
876 }, {
877 .type = RSL_SYSTEM_INFO_3,
878 .len = sizeof(si3),
879 .data = si3,
880 }, {
881 .type = RSL_SYSTEM_INFO_4,
882 .len = sizeof(si4),
883 .data = si4,
884 },
885};
886
887static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
888static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
889static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
890static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
891static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
892static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
893
894/* set all system information types */
895static int set_system_infos(struct gsm_bts_trx *trx)
896{
897 int i;
898
Harald Welte6ab22d22009-08-06 17:41:19 +0200899 if (trx == trx->bts->c0) {
900 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
901 rsl_bcch_info(trx, bcch_infos[i].type,
902 bcch_infos[i].data,
903 bcch_infos[i].len);
904 }
Harald Welte59b04682009-06-10 05:40:52 +0800905 }
906 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
907 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
908
909 return 0;
910}
911
912/*
913 * Patch the various SYSTEM INFORMATION tables to update
914 * the LAI
915 */
916static void patch_tables(struct gsm_bts *bts)
917{
Harald Weltee712a5f2009-06-21 16:17:15 +0200918 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
919 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Harald Welte59b04682009-06-10 05:40:52 +0800920 /* covert the raw packet to the struct */
921 struct gsm48_system_information_type_3 *type_3 =
922 (struct gsm48_system_information_type_3*)&si3;
923 struct gsm48_system_information_type_4 *type_4 =
924 (struct gsm48_system_information_type_4*)&si4;
925 struct gsm48_system_information_type_6 *type_6 =
926 (struct gsm48_system_information_type_6*)&si6;
927 struct gsm48_loc_area_id lai;
928
929 gsm0408_generate_lai(&lai, bts->network->country_code,
930 bts->network->network_code,
931 bts->location_area_code);
932
933 /* assign the MCC and MNC */
934 type_3->lai = lai;
935 type_4->lai = lai;
936 type_6->lai = lai;
937
938 /* patch ARFCN into BTS Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200939 bs11_attr_bts[69] &= 0xf0;
940 bs11_attr_bts[69] |= arfcn_high;
941 bs11_attr_bts[70] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800942 nanobts_attr_bts[42] &= 0xf0;
943 nanobts_attr_bts[42] |= arfcn_high;
944 nanobts_attr_bts[43] = arfcn_low;
945
946 /* patch ARFCN into TRX Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200947 bs11_attr_radio[2] &= 0xf0;
948 bs11_attr_radio[2] |= arfcn_high;
949 bs11_attr_radio[3] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800950 nanobts_attr_radio[5] &= 0xf0;
951 nanobts_attr_radio[5] |= arfcn_high;
952 nanobts_attr_radio[6] = arfcn_low;
953
954 type_4->data[2] &= 0xf0;
955 type_4->data[2] |= arfcn_high;
956 type_4->data[3] = arfcn_low;
957
958 /* patch Control Channel Description 10.5.2.11 */
959 type_3->control_channel_desc = bts->chan_desc;
960
961 /* patch BSIC */
Harald Weltef739ae62009-06-20 10:42:17 +0200962 bs11_attr_bts[1] = bts->bsic;
Harald Welte59b04682009-06-10 05:40:52 +0800963 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
Harald Welte52281c12009-07-21 22:12:23 +0200964
965 /* patch TSC */
966 si4[15] &= ~0xe0;
967 si4[15] |= (bts->tsc & 7) << 5;
Harald Weltede009e62009-08-09 14:38:49 +0200968
969 /* patch MS max power for CCH */
970 type_4->cell_sel_par.ms_txpwr_max_ccch =
Harald Weltec4dcda02009-08-09 14:45:18 +0200971 ms_pwr_ctl_lvl(bts->band, 20 /* dBm == 100mW */);
Harald Welte59b04682009-06-10 05:40:52 +0800972}
973
974
975static void bootstrap_rsl(struct gsm_bts_trx *trx)
976{
977 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte52281c12009-07-21 22:12:23 +0200978 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
Harald Welte62868882009-08-08 16:12:58 +0200979 trx->bts->nr, trx->nr, gsmnet->country_code,
980 gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
Harald Welte59b04682009-06-10 05:40:52 +0800981 set_system_infos(trx);
982}
983
984void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
985{
986 switch (event) {
987 case EVT_E1_TEI_UP:
988 switch (type) {
989 case E1INP_SIGN_OML:
990 bootstrap_om(trx->bts);
991 break;
992 case E1INP_SIGN_RSL:
993 bootstrap_rsl(trx);
994 break;
995 default:
996 break;
997 }
998 break;
999 case EVT_E1_TEI_DN:
1000 fprintf(stderr, "Lost some E1 TEI link\n");
1001 /* FIXME: deal with TEI or L1 link loss */
1002 break;
1003 default:
1004 break;
1005 }
1006}
1007
1008static int bootstrap_bts(struct gsm_bts *bts)
1009{
Harald Welte62868882009-08-08 16:12:58 +02001010 switch (bts->type) {
1011 case GSM_BTS_TYPE_NANOBTS_1800:
1012 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
1013 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
1014 return -EINVAL;
1015 }
1016 break;
1017 case GSM_BTS_TYPE_BS11:
1018 case GSM_BTS_TYPE_NANOBTS_900:
1019 /* Assume we have a P-GSM900 here */
1020 if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
1021 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1022 return -EINVAL;
1023 }
1024 break;
1025 case GSM_BTS_TYPE_UNKNOWN:
1026 fprintf(stderr, "Unknown BTS. Please specify\n");
1027 return -EINVAL;
1028 }
Harald Welte59b04682009-06-10 05:40:52 +08001029
1030 /* Control Channel Description */
1031 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
1032 bts->chan_desc.att = 1;
1033 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1034 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1035 bts->chan_desc.t3212 = 0;
1036
1037 patch_tables(bts);
1038
1039 paging_init(bts);
1040
Harald Welte59b04682009-06-10 05:40:52 +08001041 return 0;
1042}
1043
1044static int bootstrap_network(void)
1045{
Harald Welte62868882009-08-08 16:12:58 +02001046 struct gsm_bts *bts;
Harald Welteca9af2b2009-08-06 17:54:21 +02001047 int rc;
1048
Harald Welte59b04682009-06-10 05:40:52 +08001049 /* initialize our data structures */
Harald Weltee712a5f2009-06-21 16:17:15 +02001050 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +08001051 if (!gsmnet)
1052 return -ENOMEM;
1053
Harald Welte62868882009-08-08 16:12:58 +02001054 gsmnet->name_long = talloc_strdup(gsmnet, "OpenBSC");
1055 gsmnet->name_short = talloc_strdup(gsmnet, "OpenBSC");
Harald Welte59b04682009-06-10 05:40:52 +08001056
Harald Welte59b04682009-06-10 05:40:52 +08001057 if (db_init(database_name)) {
1058 printf("DB: Failed to init database. Please check the option settings.\n");
1059 return -1;
1060 }
1061 printf("DB: Database initialized.\n");
1062
1063 if (db_prepare()) {
1064 printf("DB: Failed to prepare database.\n");
1065 return -1;
1066 }
1067 printf("DB: Database prepared.\n");
1068
1069 telnet_init(gsmnet, 4242);
Harald Welte62868882009-08-08 16:12:58 +02001070 rc = vty_read_config_file("openbsc.cfg");
1071 if (rc < 0)
1072 return rc;
Harald Welte59b04682009-06-10 05:40:52 +08001073
1074 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1075
Harald Welte62868882009-08-08 16:12:58 +02001076 llist_for_each_entry(bts, &gsmnet->bts_list, list) {
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001077 bootstrap_bts(bts);
Harald Welte62868882009-08-08 16:12:58 +02001078 if (is_ipaccess_bts(bts))
1079 rc = ipaccess_setup(bts);
1080 else
1081 rc = e1_reconfig_bts(bts);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001082
Harald Welte62868882009-08-08 16:12:58 +02001083 if (rc < 0)
1084 exit (1);
Harald Welte59b04682009-06-10 05:40:52 +08001085 }
Harald Welte62868882009-08-08 16:12:58 +02001086
1087 return 0;
Harald Welte59b04682009-06-10 05:40:52 +08001088}
1089
1090static void create_pcap_file(char *file)
1091{
1092 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1093 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1094
1095 if (fd < 0) {
1096 perror("Failed to open file for pcap");
1097 return;
1098 }
1099
1100 e1_set_pcap_fd(fd);
1101}
1102
1103static void print_usage()
1104{
1105 printf("Usage: bsc_hack\n");
1106}
1107
1108static void print_help()
1109{
1110 printf(" Some useful help...\n");
Harald Welte62868882009-08-08 16:12:58 +02001111 printf(" -h --help this text\n");
Harald Welte59b04682009-06-10 05:40:52 +08001112 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1113 printf(" -s --disable-color\n");
Harald Welte59b04682009-06-10 05:40:52 +08001114 printf(" -l --database db-name The database to use\n");
1115 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1116 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1117 printf(" -p --pcap file The filename of the pcap file\n");
Harald Welte59b04682009-06-10 05:40:52 +08001118 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1119 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001120}
1121
1122static void handle_options(int argc, char** argv)
1123{
1124 while (1) {
Harald Weltea8379772009-06-20 22:36:41 +02001125 int option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001126 static struct option long_options[] = {
1127 {"help", 0, 0, 'h'},
1128 {"debug", 1, 0, 'd'},
1129 {"disable-color", 0, 0, 's'},
Harald Welte59b04682009-06-10 05:40:52 +08001130 {"database", 1, 0, 'l'},
1131 {"authorize-everyone", 0, 0, 'a'},
1132 {"reject-cause", 1, 0, 'r'},
1133 {"pcap", 1, 0, 'p'},
Harald Welte59b04682009-06-10 05:40:52 +08001134 {"cardnr", 1, 0, 'C'},
1135 {"release-l2", 0, 0, 'R'},
1136 {"timestamp", 0, 0, 'T'},
Harald Welte3c062072009-07-28 18:25:29 +02001137 {"rtp-proxy", 0, 0, 'P'},
Harald Welte59b04682009-06-10 05:40:52 +08001138 {0, 0, 0, 0}
1139 };
1140
Harald Welte62868882009-08-08 16:12:58 +02001141 c = getopt_long(argc, argv, "hd:sl:ar:p:C:RTP",
Harald Welte59b04682009-06-10 05:40:52 +08001142 long_options, &option_index);
1143 if (c == -1)
1144 break;
1145
1146 switch (c) {
1147 case 'h':
1148 print_usage();
1149 print_help();
1150 exit(0);
1151 case 's':
1152 debug_use_color(0);
1153 break;
1154 case 'd':
1155 debug_parse_category_mask(optarg);
1156 break;
Harald Welte59b04682009-06-10 05:40:52 +08001157 case 'l':
1158 database_name = strdup(optarg);
1159 break;
1160 case 'a':
1161 gsm0408_allow_everyone(1);
1162 break;
1163 case 'r':
1164 gsm0408_set_reject_cause(atoi(optarg));
1165 break;
1166 case 'p':
1167 create_pcap_file(optarg);
1168 break;
1169 case 't':
1170 BTS_TYPE = parse_btstype(optarg);
1171 break;
1172 case 'C':
1173 cardnr = atoi(optarg);
1174 break;
1175 case 'R':
1176 release_l2 = 1;
1177 break;
1178 case 'T':
1179 debug_timestamp(1);
1180 break;
Harald Welte3c062072009-07-28 18:25:29 +02001181 case 'P':
1182 ipacc_rtp_direct = 0;
1183 break;
Harald Welte59b04682009-06-10 05:40:52 +08001184 default:
1185 /* ignore */
1186 break;
1187 }
1188 }
1189}
1190
1191static void signal_handler(int signal)
1192{
1193 fprintf(stdout, "signal %u received\n", signal);
1194
1195 switch (signal) {
Harald Welte3b714502009-08-06 17:43:50 +02001196 case SIGINT:
Harald Welte59b04682009-06-10 05:40:52 +08001197 shutdown_net(gsmnet);
Harald Welte3b714502009-08-06 17:43:50 +02001198 sleep(3);
1199 exit(0);
Harald Welte59b04682009-06-10 05:40:52 +08001200 break;
Harald Welte4d5e6d52009-08-07 00:29:44 +02001201 case SIGABRT:
1202 /* in case of abort, we want to obtain a talloc report
1203 * and then return to the caller, who will abort the process */
Harald Weltea8379772009-06-20 22:36:41 +02001204 case SIGUSR1:
1205 talloc_report_full(tall_bsc_ctx, stderr);
1206 break;
Harald Welte59b04682009-06-10 05:40:52 +08001207 default:
1208 break;
1209 }
1210}
1211
1212int main(int argc, char **argv)
1213{
1214 int rc;
1215
Harald Weltea8379772009-06-20 22:36:41 +02001216 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1217
Harald Welte59b04682009-06-10 05:40:52 +08001218 /* parse options */
1219 handle_options(argc, argv);
1220
1221 /* seed the PRNG */
1222 srand(time(NULL));
1223
1224 rc = bootstrap_network();
1225 if (rc < 0)
1226 exit(1);
1227
Harald Welte3b714502009-08-06 17:43:50 +02001228 signal(SIGINT, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001229 signal(SIGABRT, &signal_handler);
Harald Weltea8379772009-06-20 22:36:41 +02001230 signal(SIGUSR1, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001231
1232 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001233 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001234 bsc_select_main(0);
1235 }
1236}