blob: 02de542178460fe97b56ef3cdf492bf62f47603c [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";
Holger Hans Peter Freyther4fa91d02009-08-10 08:39:27 +020063static const char *config_file = "openbsc.cfg";
Harald Welte3c062072009-07-28 18:25:29 +020064extern int ipacc_rtp_direct;
Harald Welte59b04682009-06-10 05:40:52 +080065
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +020066
Harald Welte59b04682009-06-10 05:40:52 +080067/* The following definitions are for OM and NM packets that we cannot yet
68 * generate by code but we just pass on */
69
70// BTS Site Manager, SET ATTRIBUTES
71
72/*
73 Object Class: BTS Site Manager
74 Instance 1: FF
75 Instance 2: FF
76 Instance 3: FF
77SET ATTRIBUTES
78 sAbisExternalTime: 2007/09/08 14:36:11
79 omLAPDRelTimer: 30sec
80 shortLAPDIntTimer: 5sec
81 emergencyTimer1: 10 minutes
82 emergencyTimer2: 0 minutes
83*/
84
85unsigned char msg_1[] =
86{
Harald Weltef739ae62009-06-20 10:42:17 +020087 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +080088 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
89 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
90 0x02,
91 0x00, 0x1E,
92 NM_ATT_BS11_SH_LAPD_INT_TIMER,
93 0x01, 0x05,
94 0x42, 0x02, 0x00, 0x0A,
95 0x44, 0x02, 0x00, 0x00
96};
97
98// BTS, SET BTS ATTRIBUTES
99
100/*
101 Object Class: BTS
102 BTS relat. Number: 0
103 Instance 2: FF
104 Instance 3: FF
105SET BTS ATTRIBUTES
106 bsIdentityCode / BSIC:
107 PLMN_colour_code: 7h
108 BS_colour_code: 7h
109 BTS Air Timer T3105: 4 ,unit 10 ms
110 btsIsHopping: FALSE
111 periodCCCHLoadIndication: 1sec
112 thresholdCCCHLoadIndication: 0%
113 cellAllocationNumber: 00h = GSM 900
114 enableInterferenceClass: 00h = Disabled
115 fACCHQual: 6 (FACCH stealing flags minus 1)
116 intaveParameter: 31 SACCH multiframes
117 interferenceLevelBoundaries:
118 Interference Boundary 1: 0Ah
119 Interference Boundary 2: 0Fh
120 Interference Boundary 3: 14h
121 Interference Boundary 4: 19h
122 Interference Boundary 5: 1Eh
123 mSTxPwrMax: 11
124 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
125 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
126 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
127 30=33dBm, 31=32dBm
128 ny1:
129 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
130 powerOutputThresholds:
131 Out Power Fault Threshold: -10 dB
132 Red Out Power Threshold: - 6 dB
133 Excessive Out Power Threshold: 5 dB
134 rACHBusyThreshold: -127 dBm
135 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
136 rfResourceIndicationPeriod: 125 SACCH multiframes
137 T200:
138 SDCCH: 044 in 5 ms
139 FACCH/Full rate: 031 in 5 ms
140 FACCH/Half rate: 041 in 5 ms
141 SACCH with TCH SAPI0: 090 in 10 ms
142 SACCH with SDCCH: 090 in 10 ms
143 SDCCH with SAPI3: 090 in 5 ms
144 SACCH with TCH SAPI3: 135 in 10 ms
145 tSync: 9000 units of 10 msec
146 tTrau: 9000 units of 10 msec
147 enableUmLoopTest: 00h = disabled
148 enableExcessiveDistance: 00h = Disabled
149 excessiveDistance: 64km
150 hoppingMode: 00h = baseband hopping
151 cellType: 00h = Standard Cell
152 BCCH ARFCN / bCCHFrequency: 1
153*/
154
Harald Weltef739ae62009-06-20 10:42:17 +0200155static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800156{
Harald Welte59b04682009-06-10 05:40:52 +0800157 NM_ATT_BSIC, HARDCODED_BSIC,
158 NM_ATT_BTS_AIR_TIMER, 0x04,
159 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
160 NM_ATT_CCCH_L_I_P, 0x01,
161 NM_ATT_CCCH_L_T, 0x00,
162 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
163 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
164 NM_ATT_BS11_FACCH_QUAL, 0x06,
165 /* interference avg. period in numbers of SACCH multifr */
166 NM_ATT_INTAVE_PARAM, 0x1F,
167 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
168 NM_ATT_CCCH_L_T, 0x23,
169 NM_ATT_GSM_TIME, 0x28, 0x00,
170 NM_ATT_ADM_STATE, 0x03,
171 NM_ATT_RACH_B_THRESH, 0x7F,
172 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
173 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
174 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
175 NM_ATT_BS11_TSYNC, 0x23, 0x28,
176 NM_ATT_BS11_TTRAU, 0x23, 0x28,
177 NM_ATT_TEST_DUR, 0x01, 0x00,
178 NM_ATT_OUTST_ALARM, 0x01, 0x00,
179 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
180 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
181 NM_ATT_BS11_PLL, 0x01, 0x00,
182 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
183};
184
185// Handover Recognition, SET ATTRIBUTES
186
187/*
188Illegal Contents GSM Formatted O&M Msg
189 Object Class: Handover Recognition
190 BTS relat. Number: 0
191 Instance 2: FF
192 Instance 3: FF
193SET ATTRIBUTES
194 enableDelayPowerBudgetHO: 00h = Disabled
195 enableDistanceHO: 00h = Disabled
196 enableInternalInterCellHandover: 00h = Disabled
197 enableInternalIntraCellHandover: 00h = Disabled
198 enablePowerBudgetHO: 00h = Disabled
199 enableRXLEVHO: 00h = Disabled
200 enableRXQUALHO: 00h = Disabled
201 hoAveragingDistance: 8 SACCH multiframes
202 hoAveragingLev:
203 A_LEV_HO: 8 SACCH multiframes
204 W_LEV_HO: 1 SACCH multiframes
205 hoAveragingPowerBudget: 16 SACCH multiframes
206 hoAveragingQual:
207 A_QUAL_HO: 8 SACCH multiframes
208 W_QUAL_HO: 2 SACCH multiframes
209 hoLowerThresholdLevDL: (10 - 110) dBm
210 hoLowerThresholdLevUL: (5 - 110) dBm
211 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
212 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
213 hoThresholdLevDLintra : (20 - 110) dBm
214 hoThresholdLevULintra: (20 - 110) dBm
215 hoThresholdMsRangeMax: 20 km
216 nCell: 06h
217 timerHORequest: 3 ,unit 2 SACCH multiframes
218*/
219
220unsigned char msg_3[] =
221{
Harald Weltef739ae62009-06-20 10:42:17 +0200222 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Weltec7d75062009-07-18 16:18:11 +0200223 0xD0, 0x00, /* enableDelayPowerBudgetHO */
224 0x64, 0x00, /* enableDistanceHO */
225 0x67, 0x00, /* enableInternalInterCellHandover */
226 0x68, 0x00, /* enableInternalInterCellHandover */
227 0x6A, 0x00, /* enablePowerBudgetHO */
228 0x6C, 0x00, /* enableRXLEVHO */
229 0x6D, 0x00, /* enableRXQUALHO */
230 0x6F, 0x08, /* hoAveragingDistance */
231 0x70, 0x08, 0x01, /* hoAveragingLev */
Harald Welte59b04682009-06-10 05:40:52 +0800232 0x71, 0x10, 0x10, 0x10,
Harald Weltec7d75062009-07-18 16:18:11 +0200233 0x72, 0x08, 0x02, /* hoAveragingQual */
234 0x73, 0x0A, /* hoLowerThresholdLevDL */
235 0x74, 0x05, /* hoLowerThresholdLevUL */
236 0x75, 0x06, /* hoLowerThresholdQualDL */
237 0x76, 0x06, /* hoLowerThresholdQualUL */
238 0x78, 0x14, /* hoThresholdLevDLintra */
239 0x79, 0x14, /* hoThresholdLevULintra */
240 0x7A, 0x14, /* hoThresholdMsRangeMax */
241 0x7D, 0x06, /* nCell */
242 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
243 0x20, 0x01, 0x00,
Harald Welte59b04682009-06-10 05:40:52 +0800244 0x45, 0x01, 0x00,
245 0x48, 0x01, 0x00,
246 0x5A, 0x01, 0x00,
247 0x5B, 0x01, 0x05,
248 0x5E, 0x01, 0x1A,
249 0x5F, 0x01, 0x20,
250 0x9D, 0x01, 0x00,
251 0x47, 0x01, 0x00,
252 0x5C, 0x01, 0x64,
253 0x5D, 0x01, 0x1E,
254 0x97, 0x01, 0x20,
255 0xF7, 0x01, 0x3C,
256};
257
258// Power Control, SET ATTRIBUTES
259
260/*
261 Object Class: Power Control
262 BTS relat. Number: 0
263 Instance 2: FF
264 Instance 3: FF
265SET ATTRIBUTES
266 enableMsPowerControl: 00h = Disabled
267 enablePowerControlRLFW: 00h = Disabled
268 pcAveragingLev:
269 A_LEV_PC: 4 SACCH multiframes
270 W_LEV_PC: 1 SACCH multiframes
271 pcAveragingQual:
272 A_QUAL_PC: 4 SACCH multiframes
273 W_QUAL_PC: 2 SACCH multiframes
274 pcLowerThresholdLevDL: 0Fh
275 pcLowerThresholdLevUL: 0Ah
276 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
277 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
278 pcRLFThreshold: 0Ch
279 pcUpperThresholdLevDL: 14h
280 pcUpperThresholdLevUL: 0Fh
281 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
282 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
283 powerConfirm: 2 ,unit 2 SACCH multiframes
284 powerControlInterval: 2 ,unit 2 SACCH multiframes
285 powerIncrStepSize: 02h = 4 dB
286 powerRedStepSize: 01h = 2 dB
287 radioLinkTimeoutBs: 64 SACCH multiframes
288 enableBSPowerControl: 00h = disabled
289*/
290
291unsigned char msg_4[] =
292{
Harald Weltef739ae62009-06-20 10:42:17 +0200293 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800294 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
295 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Weltec7d75062009-07-18 16:18:11 +0200296 0x7E, 0x04, 0x01, /* pcAveragingLev */
297 0x7F, 0x04, 0x02, /* pcAveragingQual */
298 0x80, 0x0F, /* pcLowerThresholdLevDL */
299 0x81, 0x0A, /* pcLowerThresholdLevUL */
300 0x82, 0x05, /* pcLowerThresholdQualDL */
301 0x83, 0x05, /* pcLowerThresholdQualUL */
302 0x84, 0x0C, /* pcRLFThreshold */
303 0x85, 0x14, /* pcUpperThresholdLevDL */
304 0x86, 0x0F, /* pcUpperThresholdLevUL */
305 0x87, 0x04, /* pcUpperThresholdQualDL */
306 0x88, 0x04, /* pcUpperThresholdQualUL */
307 0x89, 0x02, /* powerConfirm */
308 0x8A, 0x02, /* powerConfirmInterval */
309 0x8B, 0x02, /* powerIncrStepSize */
310 0x8C, 0x01, /* powerRedStepSize */
311 0x8D, 0x40, /* radioLinkTimeoutBs */
Harald Welte59b04682009-06-10 05:40:52 +0800312 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
313};
314
315
316// Transceiver, SET TRX ATTRIBUTES (TRX 0)
317
318/*
319 Object Class: Transceiver
320 BTS relat. Number: 0
321 Tranceiver number: 0
322 Instance 3: FF
323SET TRX ATTRIBUTES
324 aRFCNList (HEX): 0001
325 txPwrMaxReduction: 00h = 30dB
326 radioMeasGran: 254 SACCH multiframes
327 radioMeasRep: 01h = enabled
328 memberOfEmergencyConfig: 01h = TRUE
329 trxArea: 00h = TRX doesn't belong to a concentric cell
330*/
331
Harald Weltef739ae62009-06-20 10:42:17 +0200332static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800333{
Harald Welte59b04682009-06-10 05:40:52 +0800334 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
335 NM_ATT_RF_MAXPOWR_R, 0x00,
336 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
337 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
338 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
339 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
340};
341
342static unsigned char nanobts_attr_bts[] = {
343 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
344 /* interference avg. period in numbers of SACCH multifr */
345 NM_ATT_INTAVE_PARAM, 0x06,
346 /* conn fail based on SACCH error rate */
347 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
348 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
349 NM_ATT_MAX_TA, 0x3f,
350 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
351 NM_ATT_CCCH_L_T, 10, /* percent */
352 NM_ATT_CCCH_L_I_P, 1, /* seconds */
353 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
354 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
355 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
356 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
357 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
358 NM_ATT_BSIC, HARDCODED_BSIC,
359};
360
361static unsigned char nanobts_attr_radio[] = {
362 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
363 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
364};
365
366static unsigned char nanobts_attr_e0[] = {
Harald Welte4206d982009-07-12 09:33:54 +0200367 NM_ATT_IPACC_STREAM_ID, 0x00,
368 NM_ATT_IPACC_DST_IP_PORT, 0x0b, 0xbb, /* TCP PORT for RSL */
Harald Welte59b04682009-06-10 05:40:52 +0800369};
370
371/* Callback function to be called whenever we get a GSM 12.21 state change event */
372int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
373 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
374{
375 struct gsm_bts *bts;
376 struct gsm_bts_trx *trx;
377 struct gsm_bts_trx_ts *ts;
378
379 /* This is currently only required on nanoBTS */
380
381 switch (evt) {
382 case EVT_STATECHG_OPER:
383 switch (obj_class) {
384 case NM_OC_SITE_MANAGER:
385 bts = container_of(obj, struct gsm_bts, site_mgr);
386 if (old_state->operational != 2 && new_state->operational == 2) {
387 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
388 }
389 break;
390 case NM_OC_BTS:
391 bts = obj;
392 if (new_state->availability == 5) {
393 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
394 sizeof(nanobts_attr_bts));
395 abis_nm_opstart(bts, NM_OC_BTS,
396 bts->bts_nr, 0xff, 0xff);
397 abis_nm_chg_adm_state(bts, NM_OC_BTS,
398 bts->bts_nr, 0xff, 0xff,
399 NM_STATE_UNLOCKED);
400 }
401 break;
402 case NM_OC_CHANNEL:
403 ts = obj;
404 trx = ts->trx;
405 if (new_state->availability == 5) {
406 if (ts->nr == 0 && trx == trx->bts->c0)
Harald Welte7f863f52009-08-09 22:01:26 +0200407 abis_nm_set_channel_attr(ts, NM_CHANC_BCCHComb);
Harald Welte59b04682009-06-10 05:40:52 +0800408 else
409 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
410 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
411 trx->bts->bts_nr, trx->nr, ts->nr);
412 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
413 trx->bts->bts_nr, trx->nr, ts->nr,
414 NM_STATE_UNLOCKED);
415 }
416 break;
417 default:
418 break;
419 }
420 break;
421 default:
422 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
423 break;
424 }
425 return 0;
426}
427
428/* Callback function to be called every time we receive a 12.21 SW activated report */
429static int sw_activ_rep(struct msgb *mb)
430{
431 struct abis_om_fom_hdr *foh = msgb_l3(mb);
432 struct gsm_bts_trx *trx = mb->trx;
433
434 switch (foh->obj_class) {
435 case NM_OC_BASEB_TRANSC:
436 /* TRX software is active, tell it to initiate RSL Link */
437 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
438 trx->bts->bts_nr, trx->nr, 0xff,
439 nanobts_attr_e0, sizeof(nanobts_attr_e0));
440 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
441 trx->bts->bts_nr, trx->nr, 0xff);
442 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
443 trx->bts->bts_nr, trx->nr, 0xff,
444 NM_STATE_UNLOCKED);
445 break;
446 case NM_OC_RADIO_CARRIER:
447 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
448 sizeof(nanobts_attr_radio));
449 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
450 trx->bts->bts_nr, trx->nr, 0xff);
451 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
452 trx->bts->bts_nr, trx->nr, 0xff,
453 NM_STATE_UNLOCKED);
454 break;
455 }
456 return 0;
457}
458
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200459/* Callback function for NACK on the OML NM */
460static int oml_msg_nack(int mt)
461{
462 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
463 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
464 "Was the bts type and frequency properly specified?\n");
465 exit(-1);
466 }
467
468 return 0;
469}
470
Harald Welte59b04682009-06-10 05:40:52 +0800471/* Callback function to be called every time we receive a signal from NM */
472static int nm_sig_cb(unsigned int subsys, unsigned int signal,
473 void *handler_data, void *signal_data)
474{
475 switch (signal) {
476 case S_NM_SW_ACTIV_REP:
477 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200478 case S_NM_NACK:
479 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800480 default:
481 break;
482 }
483 return 0;
484}
485
486static void bootstrap_om_nanobts(struct gsm_bts *bts)
487{
488 /* We don't do callback based bootstrapping, but event driven (see above) */
489}
490
491static void bootstrap_om_bs11(struct gsm_bts *bts)
492{
Harald Weltee712a5f2009-06-21 16:17:15 +0200493 struct gsm_bts_trx *trx = bts->c0;
Harald Weltecf833cd2009-08-06 17:40:24 +0200494 int base_ts;
495
496 switch (bts->nr) {
497 case 0:
498 /* First BTS uses E1 TS 01,02,03,04,05 */
499 base_ts = HARDCODED_BTS0_TS - 1;
500 break;
501 case 1:
502 /* Second BTS uses E1 TS 06,07,08,09,10 */
503 base_ts = HARDCODED_BTS1_TS - 1;
504 break;
505 case 2:
506 /* Third BTS uses E1 TS 11,12,13,14,15 */
507 base_ts = HARDCODED_BTS2_TS - 1;
508 default:
509 return;
510 }
Harald Welte59b04682009-06-10 05:40:52 +0800511
512 /* stop sending event reports */
513 abis_nm_event_reports(bts, 0);
514
515 /* begin DB transmission */
516 abis_nm_bs11_db_transmission(bts, 1);
517
518 /* end DB transmission */
519 abis_nm_bs11_db_transmission(bts, 0);
520
521 /* Reset BTS Site manager resource */
522 abis_nm_bs11_reset_resource(bts);
523
524 /* begin DB transmission */
525 abis_nm_bs11_db_transmission(bts, 1);
526
527 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltef739ae62009-06-20 10:42:17 +0200528 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800529 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
530 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
531
532 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200533 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Weltef739ae62009-06-20 10:42:17 +0200534 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800535
536 /* Use TEI 1 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200537 abis_nm_establish_tei(bts, 0, 0, base_ts+1, 0xff, 0x01);
Harald Welte7f863f52009-08-09 22:01:26 +0200538 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_BCCHComb);
Harald Welte59b04682009-06-10 05:40:52 +0800539
Harald Welte59b04682009-06-10 05:40:52 +0800540 /* SET CHANNEL ATTRIBUTE TS1 */
541 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
542 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200543 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+2, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800544
545 /* SET CHANNEL ATTRIBUTE TS2 */
546 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
547 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200548 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+2, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800549
550 /* SET CHANNEL ATTRIBUTE TS3 */
551 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
552 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200553 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+2, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800554
555 /* SET CHANNEL ATTRIBUTE TS4 */
556 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
557 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200558 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+3, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800559
560 /* SET CHANNEL ATTRIBUTE TS5 */
561 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
562 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200563 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+3, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800564
565 /* SET CHANNEL ATTRIBUTE TS6 */
566 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
567 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200568 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+3, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800569
570 /* SET CHANNEL ATTRIBUTE TS7 */
571 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
572 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200573 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+3, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800574
Harald Welte25b70c52009-07-29 16:42:16 +0200575 trx = gsm_bts_trx_num(bts, 1);
576 if (trx) {
577 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
578 u_int8_t arfcn_low = trx->arfcn & 0xff;
579 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
580 memcpy(trx1_attr_radio, bs11_attr_radio,
581 sizeof(trx1_attr_radio));
582
583 /* patch ARFCN into TRX Attributes */
584 trx1_attr_radio[2] &= 0xf0;
585 trx1_attr_radio[2] |= arfcn_high;
586 trx1_attr_radio[3] = arfcn_low;
587
588 /* Connect signalling of TRX1 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200589 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Welte25b70c52009-07-29 16:42:16 +0200590 /* FIXME: TRX ATTRIBUTE */
591 abis_nm_set_radio_attr(trx, trx1_attr_radio,
592 sizeof(trx1_attr_radio));
593
594 /* Use TEI 2 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200595 abis_nm_establish_tei(bts, 1, 0, base_ts+1, 0xff, 0x02);
Harald Welte25b70c52009-07-29 16:42:16 +0200596
Harald Welte1a503162009-08-04 01:31:53 +0200597 /* SET CHANNEL ATTRIBUTE TS0 */
Harald Welte7f863f52009-08-09 22:01:26 +0200598 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH);
Harald Welte1a503162009-08-04 01:31:53 +0200599 /* Connect traffic of bts0/trx0/ts0 to e1_0/ts4/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200600 abis_nm_conn_terr_traf(&trx->ts[0], 0, base_ts+4, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200601
602 /* SET CHANNEL ATTRIBUTE TS1 */
603 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
604 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200605 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+4, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200606
607 /* SET CHANNEL ATTRIBUTE TS2 */
608 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
609 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200610 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+4, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200611
612 /* SET CHANNEL ATTRIBUTE TS3 */
613 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
614 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200615 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+4, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200616
617 /* SET CHANNEL ATTRIBUTE TS4 */
618 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
619 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200620 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+5, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200621
622 /* SET CHANNEL ATTRIBUTE TS5 */
623 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
624 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200625 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+5, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200626
627 /* SET CHANNEL ATTRIBUTE TS6 */
628 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
629 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200630 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+5, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200631
632 /* SET CHANNEL ATTRIBUTE TS7 */
633 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
634 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200635 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+5, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200636 }
637
Harald Welte59b04682009-06-10 05:40:52 +0800638 /* end DB transmission */
639 abis_nm_bs11_db_transmission(bts, 0);
640
641 /* Reset BTS Site manager resource */
642 abis_nm_bs11_reset_resource(bts);
643
644 /* restart sending event reports */
645 abis_nm_event_reports(bts, 1);
646}
647
648static void bootstrap_om(struct gsm_bts *bts)
649{
650 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
651
652 switch (bts->type) {
653 case GSM_BTS_TYPE_BS11:
654 bootstrap_om_bs11(bts);
655 break;
656 case GSM_BTS_TYPE_NANOBTS_900:
657 case GSM_BTS_TYPE_NANOBTS_1800:
658 bootstrap_om_nanobts(bts);
659 break;
660 default:
661 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
662 }
663}
664
665static int shutdown_om(struct gsm_bts *bts)
666{
Harald Welte3b714502009-08-06 17:43:50 +0200667 fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
668
Harald Welte59b04682009-06-10 05:40:52 +0800669 /* stop sending event reports */
670 abis_nm_event_reports(bts, 0);
671
672 /* begin DB transmission */
673 abis_nm_bs11_db_transmission(bts, 1);
674
675 /* end DB transmission */
676 abis_nm_bs11_db_transmission(bts, 0);
677
678 /* Reset BTS Site manager resource */
679 abis_nm_bs11_reset_resource(bts);
680
681 return 0;
682}
683
684static int shutdown_net(struct gsm_network *net)
685{
Harald Weltee712a5f2009-06-21 16:17:15 +0200686 struct gsm_bts *bts;
687
688 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welte59b04682009-06-10 05:40:52 +0800689 int rc;
Harald Weltee712a5f2009-06-21 16:17:15 +0200690 rc = shutdown_om(bts);
Harald Welte59b04682009-06-10 05:40:52 +0800691 if (rc < 0)
692 return rc;
693 }
694
695 return 0;
696}
697
698struct bcch_info {
699 u_int8_t type;
700 u_int8_t len;
701 const u_int8_t *data;
702};
703
704/*
705SYSTEM INFORMATION TYPE 1
706 Cell channel description
707 Format-ID bit map 0
708 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
709 RACH Control Parameters
710 maximum 7 retransmissions
711 8 slots used to spread transmission
712 cell not barred for access
713 call reestablishment not allowed
714 Access Control Class = 0000
715*/
716static u_int8_t si1[] = {
717 /* header */0x55, 0x06, 0x19,
718 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
720 /* rach */0xD5, 0x00, 0x00,
721 /* s1 reset*/0x2B
722};
723
724/*
725 SYSTEM INFORMATION TYPE 2
726 Neighbour Cells Description
727 EXT-IND: Carries the complete BA
728 BA-IND = 0
729 Format-ID bit map 0
730 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
731 NCC permitted (NCC) = FF
732 RACH Control Parameters
733 maximum 7 retransmissions
734 8 slots used to spread transmission
735 cell not barred for access
736 call reestablishment not allowed
737 Access Control Class = 0000
738*/
739static u_int8_t si2[] = {
740 /* header */0x59, 0x06, 0x1A,
741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743 /* ncc */0xFF,
744 /* rach*/0xD5, 0x00, 0x00
745};
746
747/*
748SYSTEM INFORMATION TYPE 3
749 Cell identity = 00001 (1h)
750 Location area identification
751 Mobile Country Code (MCC): 001
752 Mobile Network Code (MNC): 01
753 Location Area Code (LAC): 00001 (1h)
754 Control Channel Description
755 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
756 0 blocks reserved for access grant
757 1 channel used for CCCH, with SDCCH
758 5 multiframes period for PAGING REQUEST
759 Time-out T3212 = 0
760 Cell Options BCCH
761 Power control indicator: not set
762 MSs shall not use uplink DTX
763 Radio link timeout = 36
764 Cell Selection Parameters
765 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
766 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
767 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
768 Half rate support (NECI): New establishment causes are not supported
769 min.RX signal level for MS = 0
770 RACH Control Parameters
771 maximum 7 retransmissions
772 8 slots used to spread transmission
773 cell not barred for access
774 call reestablishment not allowed
775 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200776 SI 3 Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800777*/
778static u_int8_t si3[] = {
779 /* header */0x49, 0x06, 0x1B,
780 /* cell */0x00, 0x01,
781 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
782 /* desc */0x01, 0x03, 0x00,
783 /* option*/0x28,
784 /* selection*/0x62, 0x00,
785 /* rach */0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200786 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800787};
788
789/*
790SYSTEM INFORMATION TYPE 4
791 Location area identification
792 Mobile Country Code (MCC): 001
793 Mobile Network Code (MNC): 01
794 Location Area Code (LAC): 00001 (1h)
795 Cell Selection Parameters
796 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
797 max.TX power level MS may use for CCH = 2
798 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
799 Half rate support (NECI): New establishment causes are not supported
800 min.RX signal level for MS = 0
801 RACH Control Parameters
802 maximum 7 retransmissions
803 8 slots used to spread transmission
804 cell not barred for access
805 call reestablishment not allowed
806 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200807 CBCH Channel Description
Harald Welte59b04682009-06-10 05:40:52 +0800808 Type = SDCCH/4[2]
809 Timeslot Number: 0
810 Training Sequence Code: 7h
811 ARFCN: 1
Harald Weltec1c4a952009-07-05 13:41:40 +0200812 SI Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800813*/
814static u_int8_t si4[] = {
815 /* header */0x41, 0x06, 0x1C,
816 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
817 /* sel */0x62, 0x00,
818 /* rach*/0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200819 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
820 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800821};
822
823/*
824 SYSTEM INFORMATION TYPE 5
825 Neighbour Cells Description
826 EXT-IND: Carries the complete BA
827 BA-IND = 0
828 Format-ID bit map 0
829 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
830*/
831
832static u_int8_t si5[] = {
833 /* header without l2 len*/0x06, 0x1D,
834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
836};
837
838// SYSTEM INFORMATION TYPE 6
839
840/*
841SACCH FILLING
842 System Info Type: SYSTEM INFORMATION 6
843 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
844
845SYSTEM INFORMATION TYPE 6
846 Cell identity = 00001 (1h)
847 Location area identification
848 Mobile Country Code (MCC): 001
849 Mobile Network Code (MNC): 01
850 Location Area Code (LAC): 00001 (1h)
851 Cell Options SACCH
852 Power control indicator: not set
853 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
854 Radio link timeout = 36
855 NCC permitted (NCC) = FF
856*/
857
858static u_int8_t si6[] = {
859 /* header */0x06, 0x1E,
860 /* cell id*/ 0x00, 0x01,
861 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
862 /* options */ 0x28,
863 /* ncc */ 0xFF,
864};
865
866
867
868static const struct bcch_info bcch_infos[] = {
869 {
870 .type = RSL_SYSTEM_INFO_1,
871 .len = sizeof(si1),
872 .data = si1,
873 }, {
874 .type = RSL_SYSTEM_INFO_2,
875 .len = sizeof(si2),
876 .data = si2,
877 }, {
878 .type = RSL_SYSTEM_INFO_3,
879 .len = sizeof(si3),
880 .data = si3,
881 }, {
882 .type = RSL_SYSTEM_INFO_4,
883 .len = sizeof(si4),
884 .data = si4,
885 },
886};
887
888static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
889static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
890static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
891static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
892static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
893static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
894
895/* set all system information types */
896static int set_system_infos(struct gsm_bts_trx *trx)
897{
898 int i;
899
Harald Welte6ab22d22009-08-06 17:41:19 +0200900 if (trx == trx->bts->c0) {
901 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
902 rsl_bcch_info(trx, bcch_infos[i].type,
903 bcch_infos[i].data,
904 bcch_infos[i].len);
905 }
Harald Welte59b04682009-06-10 05:40:52 +0800906 }
907 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
908 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
909
910 return 0;
911}
912
913/*
914 * Patch the various SYSTEM INFORMATION tables to update
915 * the LAI
916 */
917static void patch_tables(struct gsm_bts *bts)
918{
Harald Weltee712a5f2009-06-21 16:17:15 +0200919 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
920 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Harald Welte59b04682009-06-10 05:40:52 +0800921 /* covert the raw packet to the struct */
922 struct gsm48_system_information_type_3 *type_3 =
923 (struct gsm48_system_information_type_3*)&si3;
924 struct gsm48_system_information_type_4 *type_4 =
925 (struct gsm48_system_information_type_4*)&si4;
926 struct gsm48_system_information_type_6 *type_6 =
927 (struct gsm48_system_information_type_6*)&si6;
928 struct gsm48_loc_area_id lai;
929
930 gsm0408_generate_lai(&lai, bts->network->country_code,
931 bts->network->network_code,
932 bts->location_area_code);
933
934 /* assign the MCC and MNC */
935 type_3->lai = lai;
936 type_4->lai = lai;
937 type_6->lai = lai;
938
939 /* patch ARFCN into BTS Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200940 bs11_attr_bts[69] &= 0xf0;
941 bs11_attr_bts[69] |= arfcn_high;
942 bs11_attr_bts[70] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800943 nanobts_attr_bts[42] &= 0xf0;
944 nanobts_attr_bts[42] |= arfcn_high;
945 nanobts_attr_bts[43] = arfcn_low;
946
947 /* patch ARFCN into TRX Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200948 bs11_attr_radio[2] &= 0xf0;
949 bs11_attr_radio[2] |= arfcn_high;
950 bs11_attr_radio[3] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800951 nanobts_attr_radio[5] &= 0xf0;
952 nanobts_attr_radio[5] |= arfcn_high;
953 nanobts_attr_radio[6] = arfcn_low;
954
955 type_4->data[2] &= 0xf0;
956 type_4->data[2] |= arfcn_high;
957 type_4->data[3] = arfcn_low;
958
959 /* patch Control Channel Description 10.5.2.11 */
960 type_3->control_channel_desc = bts->chan_desc;
961
962 /* patch BSIC */
Harald Weltef739ae62009-06-20 10:42:17 +0200963 bs11_attr_bts[1] = bts->bsic;
Harald Welte59b04682009-06-10 05:40:52 +0800964 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
Harald Welte52281c12009-07-21 22:12:23 +0200965
966 /* patch TSC */
967 si4[15] &= ~0xe0;
968 si4[15] |= (bts->tsc & 7) << 5;
Harald Weltede009e62009-08-09 14:38:49 +0200969
970 /* patch MS max power for CCH */
971 type_4->cell_sel_par.ms_txpwr_max_ccch =
Harald Weltec4dcda02009-08-09 14:45:18 +0200972 ms_pwr_ctl_lvl(bts->band, 20 /* dBm == 100mW */);
Harald Welte59b04682009-06-10 05:40:52 +0800973}
974
975
976static void bootstrap_rsl(struct gsm_bts_trx *trx)
977{
978 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte52281c12009-07-21 22:12:23 +0200979 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
Harald Welte62868882009-08-08 16:12:58 +0200980 trx->bts->nr, trx->nr, gsmnet->country_code,
981 gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
Harald Welte59b04682009-06-10 05:40:52 +0800982 set_system_infos(trx);
983}
984
985void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
986{
987 switch (event) {
988 case EVT_E1_TEI_UP:
989 switch (type) {
990 case E1INP_SIGN_OML:
991 bootstrap_om(trx->bts);
992 break;
993 case E1INP_SIGN_RSL:
994 bootstrap_rsl(trx);
995 break;
996 default:
997 break;
998 }
999 break;
1000 case EVT_E1_TEI_DN:
1001 fprintf(stderr, "Lost some E1 TEI link\n");
1002 /* FIXME: deal with TEI or L1 link loss */
1003 break;
1004 default:
1005 break;
1006 }
1007}
1008
1009static int bootstrap_bts(struct gsm_bts *bts)
1010{
Harald Welte62868882009-08-08 16:12:58 +02001011 switch (bts->type) {
1012 case GSM_BTS_TYPE_NANOBTS_1800:
1013 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
1014 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
1015 return -EINVAL;
1016 }
1017 break;
1018 case GSM_BTS_TYPE_BS11:
1019 case GSM_BTS_TYPE_NANOBTS_900:
1020 /* Assume we have a P-GSM900 here */
1021 if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
1022 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1023 return -EINVAL;
1024 }
1025 break;
1026 case GSM_BTS_TYPE_UNKNOWN:
1027 fprintf(stderr, "Unknown BTS. Please specify\n");
1028 return -EINVAL;
1029 }
Harald Welte59b04682009-06-10 05:40:52 +08001030
1031 /* Control Channel Description */
1032 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
1033 bts->chan_desc.att = 1;
1034 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1035 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1036 bts->chan_desc.t3212 = 0;
1037
1038 patch_tables(bts);
1039
1040 paging_init(bts);
1041
Harald Welte59b04682009-06-10 05:40:52 +08001042 return 0;
1043}
1044
1045static int bootstrap_network(void)
1046{
Harald Welte62868882009-08-08 16:12:58 +02001047 struct gsm_bts *bts;
Harald Welteca9af2b2009-08-06 17:54:21 +02001048 int rc;
1049
Harald Welte59b04682009-06-10 05:40:52 +08001050 /* initialize our data structures */
Harald Weltee712a5f2009-06-21 16:17:15 +02001051 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +08001052 if (!gsmnet)
1053 return -ENOMEM;
1054
Harald Welte62868882009-08-08 16:12:58 +02001055 gsmnet->name_long = talloc_strdup(gsmnet, "OpenBSC");
1056 gsmnet->name_short = talloc_strdup(gsmnet, "OpenBSC");
Harald Welte59b04682009-06-10 05:40:52 +08001057
Harald Welte59b04682009-06-10 05:40:52 +08001058 if (db_init(database_name)) {
1059 printf("DB: Failed to init database. Please check the option settings.\n");
1060 return -1;
1061 }
1062 printf("DB: Database initialized.\n");
1063
1064 if (db_prepare()) {
1065 printf("DB: Failed to prepare database.\n");
1066 return -1;
1067 }
1068 printf("DB: Database prepared.\n");
1069
1070 telnet_init(gsmnet, 4242);
Holger Hans Peter Freyther4fa91d02009-08-10 08:39:27 +02001071 rc = vty_read_config_file(config_file);
Harald Welte62868882009-08-08 16:12:58 +02001072 if (rc < 0)
1073 return rc;
Harald Welte59b04682009-06-10 05:40:52 +08001074
1075 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1076
Harald Welte62868882009-08-08 16:12:58 +02001077 llist_for_each_entry(bts, &gsmnet->bts_list, list) {
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001078 bootstrap_bts(bts);
Harald Welte62868882009-08-08 16:12:58 +02001079 if (is_ipaccess_bts(bts))
1080 rc = ipaccess_setup(bts);
1081 else
1082 rc = e1_reconfig_bts(bts);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001083
Harald Welte62868882009-08-08 16:12:58 +02001084 if (rc < 0)
1085 exit (1);
Harald Welte59b04682009-06-10 05:40:52 +08001086 }
Harald Welte62868882009-08-08 16:12:58 +02001087
1088 return 0;
Harald Welte59b04682009-06-10 05:40:52 +08001089}
1090
1091static void create_pcap_file(char *file)
1092{
1093 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1094 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1095
1096 if (fd < 0) {
1097 perror("Failed to open file for pcap");
1098 return;
1099 }
1100
1101 e1_set_pcap_fd(fd);
1102}
1103
1104static void print_usage()
1105{
1106 printf("Usage: bsc_hack\n");
1107}
1108
1109static void print_help()
1110{
1111 printf(" Some useful help...\n");
Harald Welte62868882009-08-08 16:12:58 +02001112 printf(" -h --help this text\n");
Harald Welte59b04682009-06-10 05:40:52 +08001113 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1114 printf(" -s --disable-color\n");
Holger Hans Peter Freyther4fa91d02009-08-10 08:39:27 +02001115 printf(" -c --config-file filename The config file to use.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001116 printf(" -l --database db-name The database to use\n");
1117 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1118 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1119 printf(" -p --pcap file The filename of the pcap file\n");
Harald Welte59b04682009-06-10 05:40:52 +08001120 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1121 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001122}
1123
1124static void handle_options(int argc, char** argv)
1125{
1126 while (1) {
Harald Weltea8379772009-06-20 22:36:41 +02001127 int option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001128 static struct option long_options[] = {
1129 {"help", 0, 0, 'h'},
1130 {"debug", 1, 0, 'd'},
Holger Hans Peter Freyther4fa91d02009-08-10 08:39:27 +02001131 {"config-file", 1, 0, 'c'},
Harald Welte59b04682009-06-10 05:40:52 +08001132 {"disable-color", 0, 0, 's'},
Harald Welte59b04682009-06-10 05:40:52 +08001133 {"database", 1, 0, 'l'},
1134 {"authorize-everyone", 0, 0, 'a'},
1135 {"reject-cause", 1, 0, 'r'},
1136 {"pcap", 1, 0, 'p'},
Harald Welte59b04682009-06-10 05:40:52 +08001137 {"cardnr", 1, 0, 'C'},
1138 {"release-l2", 0, 0, 'R'},
1139 {"timestamp", 0, 0, 'T'},
Harald Welte3c062072009-07-28 18:25:29 +02001140 {"rtp-proxy", 0, 0, 'P'},
Harald Welte59b04682009-06-10 05:40:52 +08001141 {0, 0, 0, 0}
1142 };
1143
Holger Hans Peter Freyther4fa91d02009-08-10 08:39:27 +02001144 c = getopt_long(argc, argv, "hd:sl:ar:p:C:RTPc:",
Harald Welte59b04682009-06-10 05:40:52 +08001145 long_options, &option_index);
1146 if (c == -1)
1147 break;
1148
1149 switch (c) {
1150 case 'h':
1151 print_usage();
1152 print_help();
1153 exit(0);
1154 case 's':
1155 debug_use_color(0);
1156 break;
1157 case 'd':
1158 debug_parse_category_mask(optarg);
1159 break;
Harald Welte59b04682009-06-10 05:40:52 +08001160 case 'l':
1161 database_name = strdup(optarg);
1162 break;
Holger Hans Peter Freyther4fa91d02009-08-10 08:39:27 +02001163 case 'c':
1164 config_file = strdup(optarg);
1165 break;
Harald Welte59b04682009-06-10 05:40:52 +08001166 case 'a':
1167 gsm0408_allow_everyone(1);
1168 break;
1169 case 'r':
1170 gsm0408_set_reject_cause(atoi(optarg));
1171 break;
1172 case 'p':
1173 create_pcap_file(optarg);
1174 break;
1175 case 't':
1176 BTS_TYPE = parse_btstype(optarg);
1177 break;
1178 case 'C':
1179 cardnr = atoi(optarg);
1180 break;
1181 case 'R':
1182 release_l2 = 1;
1183 break;
1184 case 'T':
1185 debug_timestamp(1);
1186 break;
Harald Welte3c062072009-07-28 18:25:29 +02001187 case 'P':
1188 ipacc_rtp_direct = 0;
1189 break;
Harald Welte59b04682009-06-10 05:40:52 +08001190 default:
1191 /* ignore */
1192 break;
1193 }
1194 }
1195}
1196
1197static void signal_handler(int signal)
1198{
1199 fprintf(stdout, "signal %u received\n", signal);
1200
1201 switch (signal) {
Harald Welte3b714502009-08-06 17:43:50 +02001202 case SIGINT:
Harald Welte59b04682009-06-10 05:40:52 +08001203 shutdown_net(gsmnet);
Harald Welte3b714502009-08-06 17:43:50 +02001204 sleep(3);
1205 exit(0);
Harald Welte59b04682009-06-10 05:40:52 +08001206 break;
Harald Welte4d5e6d52009-08-07 00:29:44 +02001207 case SIGABRT:
1208 /* in case of abort, we want to obtain a talloc report
1209 * and then return to the caller, who will abort the process */
Harald Weltea8379772009-06-20 22:36:41 +02001210 case SIGUSR1:
1211 talloc_report_full(tall_bsc_ctx, stderr);
1212 break;
Harald Welte59b04682009-06-10 05:40:52 +08001213 default:
1214 break;
1215 }
1216}
1217
1218int main(int argc, char **argv)
1219{
1220 int rc;
1221
Harald Weltea8379772009-06-20 22:36:41 +02001222 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1223
Harald Welte59b04682009-06-10 05:40:52 +08001224 /* parse options */
1225 handle_options(argc, argv);
1226
1227 /* seed the PRNG */
1228 srand(time(NULL));
1229
1230 rc = bootstrap_network();
1231 if (rc < 0)
1232 exit(1);
1233
Harald Welte3b714502009-08-06 17:43:50 +02001234 signal(SIGINT, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001235 signal(SIGABRT, &signal_handler);
Harald Weltea8379772009-06-20 22:36:41 +02001236 signal(SIGUSR1, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001237
1238 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001239 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001240 bsc_select_main(0);
1241 }
1242}