blob: 1e33c5d21b366301bd23b9870d5a5c16b203b708 [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001/* A hackish minimal BSC (+MSC +HLR) implementation */
2
Harald Welte32201c12009-03-10 12:15:10 +00003/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
Holger Freyther219518d2009-01-02 22:04:43 +00004 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
Harald Welte52b1f982008-12-23 20:25:15 +00005 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
Harald Weltef6b7a902008-12-26 00:05:11 +000023#include <unistd.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <stdarg.h>
27#include <time.h>
28#include <string.h>
Harald Weltead384642008-12-26 10:20:07 +000029#include <errno.h>
Harald Welted1252502009-01-01 01:50:32 +000030#include <signal.h>
Holger Freyther9a3ee0f2009-01-02 00:40:15 +000031#include <fcntl.h>
32#include <sys/stat.h>
Harald Welte52b1f982008-12-23 20:25:15 +000033
Holger Freytherb332f612008-12-27 12:46:51 +000034#define _GNU_SOURCE
35#include <getopt.h>
36
Harald Welte255539c2008-12-28 02:26:27 +000037#include <openbsc/db.h>
38#include <openbsc/timer.h>
Harald Welte8470bf22008-12-25 23:28:35 +000039#include <openbsc/gsm_data.h>
Harald Welte66b6a8d2009-08-09 14:45:18 +020040#include <openbsc/gsm_utils.h>
Harald Welte255539c2008-12-28 02:26:27 +000041#include <openbsc/gsm_04_08.h>
Harald Weltead384642008-12-26 10:20:07 +000042#include <openbsc/select.h>
Harald Welte8470bf22008-12-25 23:28:35 +000043#include <openbsc/abis_rsl.h>
44#include <openbsc/abis_nm.h>
Harald Welte702d8702008-12-26 20:25:35 +000045#include <openbsc/debug.h>
Holger Freyther5677ae32008-12-27 09:41:03 +000046#include <openbsc/misdn.h>
Holger Freyther219518d2009-01-02 22:04:43 +000047#include <openbsc/telnet_interface.h>
Harald Welte38c2f132009-01-06 23:10:57 +000048#include <openbsc/paging.h>
Harald Welte1fa60c82009-02-09 18:13:26 +000049#include <openbsc/e1_input.h>
Harald Welteb4630602009-05-01 15:43:22 +000050#include <openbsc/signal.h>
Harald Welte2cf161b2009-06-20 22:36:41 +020051#include <openbsc/talloc.h>
52
Harald Welte52b1f982008-12-23 20:25:15 +000053/* global pointer to the gsm network data structure */
Harald Welte879c85a2009-05-01 15:00:20 +000054static struct gsm_network *gsmnet;
Harald Welte52b1f982008-12-23 20:25:15 +000055
Holger Freytherefde7fb2008-12-28 14:14:56 +000056/* MCC and MNC for the Location Area Identifier */
57static int MCC = 1;
58static int MNC = 1;
Holger Freytherdda22c12009-04-22 22:07:31 +000059static int cardnr = 0;
Holger Freytherb5c00f52009-04-22 22:08:07 +000060static int release_l2 = 0;
Harald Welte8c1d0e42009-02-15 03:38:12 +000061static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
Holger Freytherbde36102008-12-28 22:51:39 +000062static const char *database_name = "hlr.sqlite3";
Holger Hans Peter Freytherd5d1cef2009-08-10 08:39:27 +020063static const char *config_file = "openbsc.cfg";
Harald Welte805f6442009-07-28 18:25:29 +020064extern int ipacc_rtp_direct;
Holger Freytherefde7fb2008-12-28 14:14:56 +000065
Holger Hans Peter Freyther03582a82009-07-16 15:24:27 +020066
Harald Welte52b1f982008-12-23 20:25:15 +000067/* 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 Weltea865f1b2009-06-20 10:42:17 +020087 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte110c0ab2009-05-23 16:27:05 +000088 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,
Harald Weltecd993872009-02-15 16:16:28 +000094 0x42, 0x02, 0x00, 0x0A,
95 0x44, 0x02, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +000096};
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
Harald Welte83282292009-02-01 16:22:19 +0000111 periodCCCHLoadIndication: 1sec
Holger Freyther3b910432009-02-11 00:43:48 +0000112 thresholdCCCHLoadIndication: 0%
Harald Welte52b1f982008-12-23 20:25:15 +0000113 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 Weltea865f1b2009-06-20 10:42:17 +0200155static unsigned char bs11_attr_bts[] =
Harald Welte52b1f982008-12-23 20:25:15 +0000156{
Harald Welte060f6df2009-05-23 17:50:53 +0000157 NM_ATT_BSIC, HARDCODED_BSIC,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000158 NM_ATT_BTS_AIR_TIMER, 0x04,
Harald Weltecd993872009-02-15 16:16:28 +0000159 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000160 NM_ATT_CCCH_L_I_P, 0x01,
161 NM_ATT_CCCH_L_T, 0x00,
Harald Welte7b26bcb2009-05-28 11:39:21 +0000162 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
163 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
Harald Weltecd993872009-02-15 16:16:28 +0000164 NM_ATT_BS11_FACCH_QUAL, 0x06,
Harald Weltefe609d82009-05-23 18:14:31 +0000165 /* interference avg. period in numbers of SACCH multifr */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000166 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,
Harald Weltecd993872009-02-15 16:16:28 +0000173 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000174 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
Harald Weltecd993872009-02-15 16:16:28 +0000175 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,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000182 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
Harald Welte52b1f982008-12-23 20:25:15 +0000183};
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 Weltea865f1b2009-06-20 10:42:17 +0200222 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Welte56554712009-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 Weltecd993872009-02-15 16:16:28 +0000232 0x71, 0x10, 0x10, 0x10,
Harald Welte56554712009-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 Weltecd993872009-02-15 16:16:28 +0000244 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,
Harald Welte52b1f982008-12-23 20:25:15 +0000256};
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 Weltea865f1b2009-06-20 10:42:17 +0200293 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Weltecd993872009-02-15 16:16:28 +0000294 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
295 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Welte56554712009-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 Weltecd993872009-02-15 16:16:28 +0000312 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
Harald Welte52b1f982008-12-23 20:25:15 +0000313};
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
Harald Weltecd993872009-02-15 16:16:28 +0000325 txPwrMaxReduction: 00h = 30dB
Harald Welte52b1f982008-12-23 20:25:15 +0000326 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 Weltea865f1b2009-06-20 10:42:17 +0200332static unsigned char bs11_attr_radio[] =
Harald Welte52b1f982008-12-23 20:25:15 +0000333{
Harald Weltecd993872009-02-15 16:16:28 +0000334 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
Harald Welte311d0cf2009-02-17 17:45:59 +0000335 NM_ATT_RF_MAXPOWR_R, 0x00,
Harald Weltee991c262009-08-10 14:09:28 +0200336 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0x05,
Harald Weltecd993872009-02-15 16:16:28 +0000337 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,
Harald Welte52b1f982008-12-23 20:25:15 +0000340};
341
Harald Welte8c1d0e42009-02-15 03:38:12 +0000342static unsigned char nanobts_attr_bts[] = {
343 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
Harald Weltefe609d82009-05-23 18:14:31 +0000344 /* interference avg. period in numbers of SACCH multifr */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000345 NM_ATT_INTAVE_PARAM, 0x06,
Harald Welted0fbab52009-06-09 20:04:44 +0000346 /* conn fail based on SACCH error rate */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000347 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,
Harald Welte311d0cf2009-02-17 17:45:59 +0000350 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 */
Harald Weltefe609d82009-05-23 18:14:31 +0000353 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
Harald Welted0fbab52009-06-09 20:04:44 +0000354 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
Harald Weltefe609d82009-05-23 18:14:31 +0000355 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
356 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000357 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
Harald Welte060f6df2009-05-23 17:50:53 +0000358 NM_ATT_BSIC, HARDCODED_BSIC,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000359};
Harald Welte52b1f982008-12-23 20:25:15 +0000360
Harald Welte8c1d0e42009-02-15 03:38:12 +0000361static unsigned char nanobts_attr_radio[] = {
Harald Welted0fbab52009-06-09 20:04:44 +0000362 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000363 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
364};
365
Harald Welte5c1e4582009-02-15 11:57:29 +0000366static unsigned char nanobts_attr_e0[] = {
Harald Welte0efe9b72009-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 Welte5c1e4582009-02-15 11:57:29 +0000369};
370
Harald Welteb4630602009-05-01 15:43:22 +0000371/* Callback function to be called whenever we get a GSM 12.21 state change event */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000372int 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,
Harald Welte191280d2009-05-01 13:20:04 +0000396 bts->bts_nr, 0xff, 0xff);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000397 abis_nm_chg_adm_state(bts, NM_OC_BTS,
Harald Welte191280d2009-05-01 13:20:04 +0000398 bts->bts_nr, 0xff, 0xff,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000399 NM_STATE_UNLOCKED);
400 }
401 break;
Harald Welte8c1d0e42009-02-15 03:38:12 +0000402 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 Welte89e9d592009-08-09 22:01:26 +0200407 abis_nm_set_channel_attr(ts, NM_CHANC_BCCHComb);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000408 else
409 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
410 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
Harald Welte191280d2009-05-01 13:20:04 +0000411 trx->bts->bts_nr, trx->nr, ts->nr);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000412 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
Harald Welte191280d2009-05-01 13:20:04 +0000413 trx->bts->bts_nr, trx->nr, ts->nr,
Harald Welte8c1d0e42009-02-15 03:38:12 +0000414 NM_STATE_UNLOCKED);
415 }
416 break;
Harald Weltea994a482009-05-01 15:54:23 +0000417 default:
Harald Welte8c1d0e42009-02-15 03:38:12 +0000418 break;
419 }
420 break;
Harald Weltea994a482009-05-01 15:54:23 +0000421 default:
422 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
Holger Freytherff9592f2009-03-09 16:17:14 +0000423 break;
Harald Welte8c1d0e42009-02-15 03:38:12 +0000424 }
425 return 0;
426}
427
Harald Welteb4630602009-05-01 15:43:22 +0000428/* 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 Freyther500f3ca2009-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 Welteb4630602009-05-01 15:43:22 +0000471/* 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 Freyther500f3ca2009-06-10 10:48:14 +0200478 case S_NM_NACK:
479 return oml_msg_nack((int)signal_data);
Harald Welteb4630602009-05-01 15:43:22 +0000480 default:
481 break;
482 }
483 return 0;
484}
485
Harald Welte8c1d0e42009-02-15 03:38:12 +0000486static void bootstrap_om_nanobts(struct gsm_bts *bts)
487{
Harald Weltee1bd2412009-02-15 14:40:09 +0000488 /* We don't do callback based bootstrapping, but event driven (see above) */
Harald Welte8c1d0e42009-02-15 03:38:12 +0000489}
490
Harald Welte349aba62009-08-10 12:31:31 +0200491static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
Harald Welte52b1f982008-12-23 20:25:15 +0000492{
Harald Welte349aba62009-08-10 12:31:31 +0200493 enum abis_nm_chan_comb ccomb = abis_nm_chcomb4pchan(ts->pchan);
494 struct gsm_e1_subslot *e1l = &ts->e1_link;
Harald Welteac56e8b2009-08-06 17:40:24 +0200495
Harald Welte349aba62009-08-10 12:31:31 +0200496 abis_nm_set_channel_attr(ts, ccomb);
497
498 if (is_ipaccess_bts(ts->trx->bts))
Harald Welteac56e8b2009-08-06 17:40:24 +0200499 return;
Harald Welte349aba62009-08-10 12:31:31 +0200500
501 switch (ts->pchan) {
502 case GSM_PCHAN_TCH_F:
503 case GSM_PCHAN_TCH_H:
504 abis_nm_conn_terr_traf(ts, e1l->e1_nr, e1l->e1_ts,
505 e1l->e1_ts_ss);
506 break;
507 default:
508 break;
509 }
510}
511
512static void nm_reconfig_trx(struct gsm_bts_trx *trx)
513{
514 struct gsm_e1_subslot *e1l = &trx->rsl_e1_link;
515 int i;
516
517 switch (trx->bts->type) {
518 case GSM_BTS_TYPE_BS11:
Harald Welte (local)7f28cd52009-08-12 10:40:17 +0200519 /* FIXME: discover this by fetching an attribute */
520#if 0
521 trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
522#else
523 trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
524#endif
Harald Welte349aba62009-08-10 12:31:31 +0200525 abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
526 e1l->e1_ts_ss);
527 abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
528 e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei);
529
530 /* Set Radio Attributes */
531 if (trx == trx->bts->c0)
532 abis_nm_set_radio_attr(trx, bs11_attr_radio,
533 sizeof(bs11_attr_radio));
534 else {
535 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
536 u_int8_t arfcn_low = trx->arfcn & 0xff;
537 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
538 memcpy(trx1_attr_radio, bs11_attr_radio,
539 sizeof(trx1_attr_radio));
540
541 /* patch ARFCN into TRX Attributes */
542 trx1_attr_radio[2] &= 0xf0;
543 trx1_attr_radio[2] |= arfcn_high;
544 trx1_attr_radio[3] = arfcn_low;
545
546 abis_nm_set_radio_attr(trx, trx1_attr_radio,
547 sizeof(trx1_attr_radio));
548 }
549 break;
Harald Welte (local)7f28cd52009-08-12 10:40:17 +0200550 case GSM_BTS_TYPE_NANOBTS_900:
551 case GSM_BTS_TYPE_NANOBTS_1800:
552 trx->nominal_power = 20;
Harald Welte349aba62009-08-10 12:31:31 +0200553 default:
554 break;
Harald Welteac56e8b2009-08-06 17:40:24 +0200555 }
Harald Welte52b1f982008-12-23 20:25:15 +0000556
Harald Welte349aba62009-08-10 12:31:31 +0200557 for (i = 0; i < TRX_NR_TS; i++)
558 nm_reconfig_ts(&trx->ts[i]);
559}
560
561static void nm_reconfig_bts(struct gsm_bts *bts)
562{
563 struct gsm_bts_trx *trx;
564
565 switch (bts->type) {
566 case GSM_BTS_TYPE_BS11:
567 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
568 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
569 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
570 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
571 break;
572 default:
573 break;
574 }
575
576 llist_for_each_entry(trx, &bts->trx_list, list)
577 nm_reconfig_trx(trx);
578}
579
580static void bootstrap_om_bs11(struct gsm_bts *bts)
581{
Harald Welte52b1f982008-12-23 20:25:15 +0000582 /* stop sending event reports */
583 abis_nm_event_reports(bts, 0);
584
585 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000586 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000587
Harald Welte702d8702008-12-26 20:25:35 +0000588 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000589 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte702d8702008-12-26 20:25:35 +0000590
591 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000592 abis_nm_bs11_reset_resource(bts);
Harald Welte702d8702008-12-26 20:25:35 +0000593
594 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000595 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte702d8702008-12-26 20:25:35 +0000596
Harald Welte349aba62009-08-10 12:31:31 +0200597 /* reconfigure BTS with all TRX and all TS */
598 nm_reconfig_bts(bts);
Harald Welte67b4c302009-07-29 16:42:16 +0200599
Harald Welte52b1f982008-12-23 20:25:15 +0000600 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000601 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000602
603 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000604 abis_nm_bs11_reset_resource(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000605
606 /* restart sending event reports */
607 abis_nm_event_reports(bts, 1);
608}
609
Harald Welte8c1d0e42009-02-15 03:38:12 +0000610static void bootstrap_om(struct gsm_bts *bts)
611{
Harald Welteedb37782009-05-01 14:59:07 +0000612 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
Harald Welte8c1d0e42009-02-15 03:38:12 +0000613
614 switch (bts->type) {
615 case GSM_BTS_TYPE_BS11:
616 bootstrap_om_bs11(bts);
617 break;
618 case GSM_BTS_TYPE_NANOBTS_900:
619 case GSM_BTS_TYPE_NANOBTS_1800:
620 bootstrap_om_nanobts(bts);
621 break;
622 default:
623 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
624 }
625}
626
Harald Welted1252502009-01-01 01:50:32 +0000627static int shutdown_om(struct gsm_bts *bts)
628{
Harald Weltef294f452009-08-06 17:43:50 +0200629 fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
630
Harald Welted1252502009-01-01 01:50:32 +0000631 /* stop sending event reports */
632 abis_nm_event_reports(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000633
Harald Welted1252502009-01-01 01:50:32 +0000634 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000635 abis_nm_bs11_db_transmission(bts, 1);
Harald Welted1252502009-01-01 01:50:32 +0000636
637 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000638 abis_nm_bs11_db_transmission(bts, 0);
Harald Welted1252502009-01-01 01:50:32 +0000639
640 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000641 abis_nm_bs11_reset_resource(bts);
Harald Welted1252502009-01-01 01:50:32 +0000642
643 return 0;
644}
645
646static int shutdown_net(struct gsm_network *net)
647{
Harald Weltee441d9c2009-06-21 16:17:15 +0200648 struct gsm_bts *bts;
649
650 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welted1252502009-01-01 01:50:32 +0000651 int rc;
Harald Weltee441d9c2009-06-21 16:17:15 +0200652 rc = shutdown_om(bts);
Harald Welted1252502009-01-01 01:50:32 +0000653 if (rc < 0)
654 return rc;
655 }
656
657 return 0;
658}
Harald Welte52b1f982008-12-23 20:25:15 +0000659
660struct bcch_info {
661 u_int8_t type;
662 u_int8_t len;
663 const u_int8_t *data;
664};
665
666/*
667SYSTEM INFORMATION TYPE 1
668 Cell channel description
669 Format-ID bit map 0
670 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
671 RACH Control Parameters
672 maximum 7 retransmissions
673 8 slots used to spread transmission
674 cell not barred for access
675 call reestablishment not allowed
676 Access Control Class = 0000
677*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000678static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000679 /* header */0x55, 0x06, 0x19,
680 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
682 /* rach */0xD5, 0x00, 0x00,
683 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000684};
685
686/*
687 SYSTEM INFORMATION TYPE 2
688 Neighbour Cells Description
689 EXT-IND: Carries the complete BA
690 BA-IND = 0
691 Format-ID bit map 0
692 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
693 NCC permitted (NCC) = FF
694 RACH Control Parameters
695 maximum 7 retransmissions
696 8 slots used to spread transmission
697 cell not barred for access
698 call reestablishment not allowed
699 Access Control Class = 0000
700*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000701static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000702 /* header */0x59, 0x06, 0x1A,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 /* ncc */0xFF,
706 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000707};
708
709/*
710SYSTEM INFORMATION TYPE 3
711 Cell identity = 00001 (1h)
712 Location area identification
713 Mobile Country Code (MCC): 001
714 Mobile Network Code (MNC): 01
715 Location Area Code (LAC): 00001 (1h)
716 Control Channel Description
717 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
718 0 blocks reserved for access grant
719 1 channel used for CCCH, with SDCCH
720 5 multiframes period for PAGING REQUEST
721 Time-out T3212 = 0
722 Cell Options BCCH
723 Power control indicator: not set
724 MSs shall not use uplink DTX
725 Radio link timeout = 36
726 Cell Selection Parameters
727 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000728 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000729 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
730 Half rate support (NECI): New establishment causes are not supported
731 min.RX signal level for MS = 0
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
Harald Welte53833f62009-07-05 13:41:40 +0200738 SI 3 Rest Octets (not present)
Harald Welte52b1f982008-12-23 20:25:15 +0000739*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000740static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000741 /* header */0x49, 0x06, 0x1B,
742 /* cell */0x00, 0x01,
743 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
744 /* desc */0x01, 0x03, 0x00,
745 /* option*/0x28,
746 /* selection*/0x62, 0x00,
747 /* rach */0xD5, 0x00, 0x00,
Harald Welte53833f62009-07-05 13:41:40 +0200748 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000749};
750
751/*
752SYSTEM INFORMATION TYPE 4
753 Location area identification
754 Mobile Country Code (MCC): 001
755 Mobile Network Code (MNC): 01
756 Location Area Code (LAC): 00001 (1h)
757 Cell Selection Parameters
758 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
759 max.TX power level MS may use for CCH = 2
760 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
761 Half rate support (NECI): New establishment causes are not supported
762 min.RX signal level for MS = 0
763 RACH Control Parameters
764 maximum 7 retransmissions
765 8 slots used to spread transmission
766 cell not barred for access
767 call reestablishment not allowed
768 Access Control Class = 0000
Harald Welte53833f62009-07-05 13:41:40 +0200769 CBCH Channel Description
Harald Welte52b1f982008-12-23 20:25:15 +0000770 Type = SDCCH/4[2]
771 Timeslot Number: 0
772 Training Sequence Code: 7h
773 ARFCN: 1
Harald Welte53833f62009-07-05 13:41:40 +0200774 SI Rest Octets (not present)
Harald Welte52b1f982008-12-23 20:25:15 +0000775*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000776static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000777 /* header */0x41, 0x06, 0x1C,
778 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
779 /* sel */0x62, 0x00,
780 /* rach*/0xD5, 0x00, 0x00,
Harald Welte53833f62009-07-05 13:41:40 +0200781 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
782 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000783};
784
785/*
786 SYSTEM INFORMATION TYPE 5
787 Neighbour Cells Description
788 EXT-IND: Carries the complete BA
789 BA-IND = 0
790 Format-ID bit map 0
791 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
792*/
793
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000794static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000795 /* header without l2 len*/0x06, 0x1D,
796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000798};
799
800// SYSTEM INFORMATION TYPE 6
801
802/*
803SACCH FILLING
804 System Info Type: SYSTEM INFORMATION 6
805 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
806
807SYSTEM INFORMATION TYPE 6
808 Cell identity = 00001 (1h)
809 Location area identification
810 Mobile Country Code (MCC): 001
811 Mobile Network Code (MNC): 01
812 Location Area Code (LAC): 00001 (1h)
813 Cell Options SACCH
814 Power control indicator: not set
815 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
816 Radio link timeout = 36
817 NCC permitted (NCC) = FF
818*/
819
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000820static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000821 /* header */0x06, 0x1E,
822 /* cell id*/ 0x00, 0x01,
823 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
824 /* options */ 0x28,
825 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000826};
827
828
829
830static const struct bcch_info bcch_infos[] = {
831 {
832 .type = RSL_SYSTEM_INFO_1,
833 .len = sizeof(si1),
834 .data = si1,
835 }, {
836 .type = RSL_SYSTEM_INFO_2,
837 .len = sizeof(si2),
838 .data = si2,
839 }, {
840 .type = RSL_SYSTEM_INFO_3,
841 .len = sizeof(si3),
842 .data = si3,
843 }, {
844 .type = RSL_SYSTEM_INFO_4,
845 .len = sizeof(si4),
846 .data = si4,
847 },
848};
849
Holger Freyther24287b62008-12-28 16:32:41 +0000850static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
851static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
852static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
853static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000854static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
855static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000856
Harald Welte52b1f982008-12-23 20:25:15 +0000857/* set all system information types */
Harald Weltee79769b2009-02-07 00:48:17 +0000858static int set_system_infos(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000859{
860 int i;
861
Harald Welted1586052009-08-06 17:41:19 +0200862 if (trx == trx->bts->c0) {
863 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
864 rsl_bcch_info(trx, bcch_infos[i].type,
865 bcch_infos[i].data,
866 bcch_infos[i].len);
867 }
Harald Welte52b1f982008-12-23 20:25:15 +0000868 }
Harald Weltee79769b2009-02-07 00:48:17 +0000869 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
870 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000871
872 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000873}
874
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000875/*
876 * Patch the various SYSTEM INFORMATION tables to update
877 * the LAI
878 */
879static void patch_tables(struct gsm_bts *bts)
880{
Harald Weltee441d9c2009-06-21 16:17:15 +0200881 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
882 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000883 /* covert the raw packet to the struct */
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200884 struct gsm48_system_information_type_1 *type_1 =
885 (struct gsm48_system_information_type_1*)&si1;
886 struct gsm48_system_information_type_2 *type_2 =
887 (struct gsm48_system_information_type_2*)&si2;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000888 struct gsm48_system_information_type_3 *type_3 =
889 (struct gsm48_system_information_type_3*)&si3;
890 struct gsm48_system_information_type_4 *type_4 =
891 (struct gsm48_system_information_type_4*)&si4;
892 struct gsm48_system_information_type_6 *type_6 =
893 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000894 struct gsm48_loc_area_id lai;
895
896 gsm0408_generate_lai(&lai, bts->network->country_code,
Harald Welte110c0ab2009-05-23 16:27:05 +0000897 bts->network->network_code,
898 bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000899
900 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000901 type_3->lai = lai;
902 type_4->lai = lai;
903 type_6->lai = lai;
Harald Welte98981882009-01-06 18:59:11 +0000904
Harald Welte94009322009-02-15 15:38:42 +0000905 /* patch ARFCN into BTS Attributes */
Harald Weltea865f1b2009-06-20 10:42:17 +0200906 bs11_attr_bts[69] &= 0xf0;
907 bs11_attr_bts[69] |= arfcn_high;
908 bs11_attr_bts[70] = arfcn_low;
Harald Welte94009322009-02-15 15:38:42 +0000909 nanobts_attr_bts[42] &= 0xf0;
910 nanobts_attr_bts[42] |= arfcn_high;
911 nanobts_attr_bts[43] = arfcn_low;
Harald Welte98981882009-01-06 18:59:11 +0000912
Harald Welte94009322009-02-15 15:38:42 +0000913 /* patch ARFCN into TRX Attributes */
Harald Weltea865f1b2009-06-20 10:42:17 +0200914 bs11_attr_radio[2] &= 0xf0;
915 bs11_attr_radio[2] |= arfcn_high;
916 bs11_attr_radio[3] = arfcn_low;
Harald Welte94009322009-02-15 15:38:42 +0000917 nanobts_attr_radio[5] &= 0xf0;
918 nanobts_attr_radio[5] |= arfcn_high;
919 nanobts_attr_radio[6] = arfcn_low;
Harald Welte98981882009-01-06 18:59:11 +0000920
921 type_4->data[2] &= 0xf0;
922 type_4->data[2] |= arfcn_high;
923 type_4->data[3] = arfcn_low;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000924
925 /* patch Control Channel Description 10.5.2.11 */
926 type_3->control_channel_desc = bts->chan_desc;
Harald Welte78f2f502009-05-23 16:56:52 +0000927
928 /* patch BSIC */
Harald Weltea865f1b2009-06-20 10:42:17 +0200929 bs11_attr_bts[1] = bts->bsic;
Harald Welte78f2f502009-05-23 16:56:52 +0000930 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
Harald Weltef8d536d2009-07-21 22:12:23 +0200931
932 /* patch TSC */
933 si4[15] &= ~0xe0;
934 si4[15] |= (bts->tsc & 7) << 5;
Harald Welte31f03a62009-08-09 14:38:49 +0200935
936 /* patch MS max power for CCH */
937 type_4->cell_sel_par.ms_txpwr_max_ccch =
Harald Welte66b6a8d2009-08-09 14:45:18 +0200938 ms_pwr_ctl_lvl(bts->band, 20 /* dBm == 100mW */);
Harald Welte (local)5dececf2009-08-12 13:28:23 +0200939
940 if (bts->cell_barred) {
941 type_1->rach_control.cell_bar = 1;
942 type_2->rach_control.cell_bar = 1;
943 type_3->rach_control.cell_bar = 1;
944 type_4->rach_control.cell_bar = 1;
945 } else {
946 type_1->rach_control.cell_bar = 0;
947 type_2->rach_control.cell_bar = 0;
948 type_3->rach_control.cell_bar = 0;
949 type_4->rach_control.cell_bar = 0;
950 }
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000951}
952
953
Harald Weltee79769b2009-02-07 00:48:17 +0000954static void bootstrap_rsl(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000955{
Harald Welteedb37782009-05-01 14:59:07 +0000956 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Weltef8d536d2009-07-21 22:12:23 +0200957 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
Harald Welte42581822009-08-08 16:12:58 +0200958 trx->bts->nr, trx->nr, gsmnet->country_code,
959 gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
Harald Weltee79769b2009-02-07 00:48:17 +0000960 set_system_infos(trx);
Harald Welte52b1f982008-12-23 20:25:15 +0000961}
962
Harald Welte1fa60c82009-02-09 18:13:26 +0000963void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
Harald Weltead384642008-12-26 10:20:07 +0000964{
965 switch (event) {
Harald Welte1fa60c82009-02-09 18:13:26 +0000966 case EVT_E1_TEI_UP:
967 switch (type) {
968 case E1INP_SIGN_OML:
969 bootstrap_om(trx->bts);
970 break;
971 case E1INP_SIGN_RSL:
972 bootstrap_rsl(trx);
973 break;
974 default:
975 break;
976 }
Harald Weltead384642008-12-26 10:20:07 +0000977 break;
Harald Welte1fa60c82009-02-09 18:13:26 +0000978 case EVT_E1_TEI_DN:
979 fprintf(stderr, "Lost some E1 TEI link\n");
980 /* FIXME: deal with TEI or L1 link loss */
Harald Weltead384642008-12-26 10:20:07 +0000981 break;
982 default:
Harald Weltead384642008-12-26 10:20:07 +0000983 break;
984 }
985}
986
Harald Welteedb37782009-05-01 14:59:07 +0000987static int bootstrap_bts(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000988{
Harald Welte42581822009-08-08 16:12:58 +0200989 switch (bts->type) {
990 case GSM_BTS_TYPE_NANOBTS_1800:
991 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
992 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
993 return -EINVAL;
994 }
995 break;
996 case GSM_BTS_TYPE_BS11:
997 case GSM_BTS_TYPE_NANOBTS_900:
998 /* Assume we have a P-GSM900 here */
999 if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
1000 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1001 return -EINVAL;
1002 }
1003 break;
1004 case GSM_BTS_TYPE_UNKNOWN:
1005 fprintf(stderr, "Unknown BTS. Please specify\n");
1006 return -EINVAL;
1007 }
Holger Freyther1adb4ff2009-02-04 00:04:52 +00001008
1009 /* Control Channel Description */
1010 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
Harald Welte41fbf442009-02-24 22:34:22 +00001011 bts->chan_desc.att = 1;
Holger Freyther1adb4ff2009-02-04 00:04:52 +00001012 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1013 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1014 bts->chan_desc.t3212 = 0;
1015
Harald Welte98981882009-01-06 18:59:11 +00001016 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +00001017
Holger Freyther1fd34142009-02-09 23:42:03 +00001018 paging_init(bts);
Harald Welte38c2f132009-01-06 23:10:57 +00001019
Harald Welteedb37782009-05-01 14:59:07 +00001020 return 0;
1021}
1022
1023static int bootstrap_network(void)
1024{
Harald Welte42581822009-08-08 16:12:58 +02001025 struct gsm_bts *bts;
Harald Welte51460062009-08-06 17:54:21 +02001026 int rc;
1027
Harald Welteedb37782009-05-01 14:59:07 +00001028 /* initialize our data structures */
Harald Weltee441d9c2009-06-21 16:17:15 +02001029 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welteedb37782009-05-01 14:59:07 +00001030 if (!gsmnet)
1031 return -ENOMEM;
1032
Harald Welte42581822009-08-08 16:12:58 +02001033 gsmnet->name_long = talloc_strdup(gsmnet, "OpenBSC");
1034 gsmnet->name_short = talloc_strdup(gsmnet, "OpenBSC");
Harald Welteedb37782009-05-01 14:59:07 +00001035
Holger Freytherc7b86f92009-06-06 13:54:20 +00001036 if (db_init(database_name)) {
Holger Freytheref7f7ce2009-04-19 06:35:12 +00001037 printf("DB: Failed to init database. Please check the option settings.\n");
1038 return -1;
1039 }
1040 printf("DB: Database initialized.\n");
1041
1042 if (db_prepare()) {
1043 printf("DB: Failed to prepare database.\n");
1044 return -1;
1045 }
1046 printf("DB: Database prepared.\n");
1047
Holger Freyther219518d2009-01-02 22:04:43 +00001048 telnet_init(gsmnet, 4242);
Holger Hans Peter Freytherd5d1cef2009-08-10 08:39:27 +02001049 rc = vty_read_config_file(config_file);
Holger Hans Peter Freyther100325a2009-08-10 10:35:24 +02001050 if (rc < 0) {
1051 fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
Harald Welte42581822009-08-08 16:12:58 +02001052 return rc;
Holger Hans Peter Freyther100325a2009-08-10 10:35:24 +02001053 }
Harald Weltead384642008-12-26 10:20:07 +00001054
Harald Welteb4630602009-05-01 15:43:22 +00001055 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1056
Harald Welte42581822009-08-08 16:12:58 +02001057 llist_for_each_entry(bts, &gsmnet->bts_list, list) {
Holger Hans Peter Freyther03582a82009-07-16 15:24:27 +02001058 bootstrap_bts(bts);
Holger Hans Peter Freyther557ca782009-08-10 14:16:08 +02001059 if (!is_ipaccess_bts(bts))
Harald Welte42581822009-08-08 16:12:58 +02001060 rc = e1_reconfig_bts(bts);
Holger Hans Peter Freyther03582a82009-07-16 15:24:27 +02001061
Harald Welte42581822009-08-08 16:12:58 +02001062 if (rc < 0)
1063 exit (1);
Harald Welteedb37782009-05-01 14:59:07 +00001064 }
Harald Welte42581822009-08-08 16:12:58 +02001065
Holger Hans Peter Freyther557ca782009-08-10 14:16:08 +02001066 /* initialize nanoBTS support omce */
1067 rc = ipaccess_setup(gsmnet);
1068
Harald Welte42581822009-08-08 16:12:58 +02001069 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +00001070}
Harald Weltef6b7a902008-12-26 00:05:11 +00001071
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001072static void create_pcap_file(char *file)
1073{
1074 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1075 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1076
1077 if (fd < 0) {
1078 perror("Failed to open file for pcap");
1079 return;
1080 }
1081
Holger Freyther0469cf62009-03-31 12:14:16 +00001082 e1_set_pcap_fd(fd);
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001083}
1084
Holger Freytherb332f612008-12-27 12:46:51 +00001085static void print_usage()
1086{
1087 printf("Usage: bsc_hack\n");
1088}
1089
1090static void print_help()
1091{
1092 printf(" Some useful help...\n");
Harald Welte42581822009-08-08 16:12:58 +02001093 printf(" -h --help this text\n");
Holger Freytherb332f612008-12-27 12:46:51 +00001094 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +00001095 printf(" -s --disable-color\n");
Holger Hans Peter Freytherd5d1cef2009-08-10 08:39:27 +02001096 printf(" -c --config-file filename The config file to use.\n");
Holger Freytherbde36102008-12-28 22:51:39 +00001097 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +00001098 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freythere97f7fb2008-12-31 18:52:11 +00001099 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001100 printf(" -p --pcap file The filename of the pcap file\n");
Holger Freytherdda22c12009-04-22 22:07:31 +00001101 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
Holger Freytherb5c00f52009-04-22 22:08:07 +00001102 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
Holger Freytherb332f612008-12-27 12:46:51 +00001103}
1104
1105static void handle_options(int argc, char** argv)
1106{
1107 while (1) {
Harald Welte2cf161b2009-06-20 22:36:41 +02001108 int option_index = 0, c;
Holger Freytherb332f612008-12-27 12:46:51 +00001109 static struct option long_options[] = {
1110 {"help", 0, 0, 'h'},
1111 {"debug", 1, 0, 'd'},
Holger Hans Peter Freytherd5d1cef2009-08-10 08:39:27 +02001112 {"config-file", 1, 0, 'c'},
Holger Freytherefde7fb2008-12-28 14:14:56 +00001113 {"disable-color", 0, 0, 's'},
Holger Freytherbde36102008-12-28 22:51:39 +00001114 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +00001115 {"authorize-everyone", 0, 0, 'a'},
Holger Freythere97f7fb2008-12-31 18:52:11 +00001116 {"reject-cause", 1, 0, 'r'},
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001117 {"pcap", 1, 0, 'p'},
Holger Freytherdda22c12009-04-22 22:07:31 +00001118 {"cardnr", 1, 0, 'C'},
Holger Freytherb5c00f52009-04-22 22:08:07 +00001119 {"release-l2", 0, 0, 'R'},
Harald Welted3ff51d2009-06-09 20:21:57 +00001120 {"timestamp", 0, 0, 'T'},
Harald Welte805f6442009-07-28 18:25:29 +02001121 {"rtp-proxy", 0, 0, 'P'},
Holger Freytherb332f612008-12-27 12:46:51 +00001122 {0, 0, 0, 0}
1123 };
1124
Holger Hans Peter Freytherd5d1cef2009-08-10 08:39:27 +02001125 c = getopt_long(argc, argv, "hd:sl:ar:p:C:RTPc:",
Holger Freytherb332f612008-12-27 12:46:51 +00001126 long_options, &option_index);
1127 if (c == -1)
1128 break;
1129
1130 switch (c) {
1131 case 'h':
1132 print_usage();
1133 print_help();
1134 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +00001135 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +00001136 debug_use_color(0);
1137 break;
1138 case 'd':
1139 debug_parse_category_mask(optarg);
1140 break;
Harald Welte8965da42009-01-06 18:09:02 +00001141 case 'l':
Holger Freytherbde36102008-12-28 22:51:39 +00001142 database_name = strdup(optarg);
1143 break;
Holger Hans Peter Freytherd5d1cef2009-08-10 08:39:27 +02001144 case 'c':
1145 config_file = strdup(optarg);
1146 break;
Holger Freyther89824fc2008-12-30 16:18:18 +00001147 case 'a':
1148 gsm0408_allow_everyone(1);
1149 break;
Holger Freythere97f7fb2008-12-31 18:52:11 +00001150 case 'r':
1151 gsm0408_set_reject_cause(atoi(optarg));
1152 break;
Holger Freyther9a3ee0f2009-01-02 00:40:15 +00001153 case 'p':
1154 create_pcap_file(optarg);
1155 break;
Harald Welte8c1d0e42009-02-15 03:38:12 +00001156 case 't':
1157 BTS_TYPE = parse_btstype(optarg);
1158 break;
Holger Freytherdda22c12009-04-22 22:07:31 +00001159 case 'C':
1160 cardnr = atoi(optarg);
1161 break;
Holger Freytherb5c00f52009-04-22 22:08:07 +00001162 case 'R':
1163 release_l2 = 1;
1164 break;
Harald Welted3ff51d2009-06-09 20:21:57 +00001165 case 'T':
1166 debug_timestamp(1);
1167 break;
Harald Welte805f6442009-07-28 18:25:29 +02001168 case 'P':
1169 ipacc_rtp_direct = 0;
1170 break;
Holger Freytherb332f612008-12-27 12:46:51 +00001171 default:
1172 /* ignore */
1173 break;
1174 }
1175 }
1176}
1177
Harald Welted1252502009-01-01 01:50:32 +00001178static void signal_handler(int signal)
1179{
1180 fprintf(stdout, "signal %u received\n", signal);
1181
1182 switch (signal) {
Harald Weltef294f452009-08-06 17:43:50 +02001183 case SIGINT:
Harald Welted1252502009-01-01 01:50:32 +00001184 shutdown_net(gsmnet);
Harald Weltef294f452009-08-06 17:43:50 +02001185 sleep(3);
1186 exit(0);
Harald Welted1252502009-01-01 01:50:32 +00001187 break;
Harald Welte31c3d342009-08-07 00:29:44 +02001188 case SIGABRT:
1189 /* in case of abort, we want to obtain a talloc report
1190 * and then return to the caller, who will abort the process */
Harald Welte2cf161b2009-06-20 22:36:41 +02001191 case SIGUSR1:
1192 talloc_report_full(tall_bsc_ctx, stderr);
1193 break;
Harald Welted1252502009-01-01 01:50:32 +00001194 default:
1195 break;
1196 }
1197}
1198
Harald Weltef6b7a902008-12-26 00:05:11 +00001199int main(int argc, char **argv)
1200{
Harald Welte1fa60c82009-02-09 18:13:26 +00001201 int rc;
1202
Harald Welte2cf161b2009-06-20 22:36:41 +02001203 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1204
Holger Freytherb332f612008-12-27 12:46:51 +00001205 /* parse options */
1206 handle_options(argc, argv);
1207
Harald Welte65ccf882009-02-24 22:36:20 +00001208 /* seed the PRNG */
1209 srand(time(NULL));
1210
Harald Welte1fa60c82009-02-09 18:13:26 +00001211 rc = bootstrap_network();
1212 if (rc < 0)
1213 exit(1);
Harald Weltef6b7a902008-12-26 00:05:11 +00001214
Harald Weltef294f452009-08-06 17:43:50 +02001215 signal(SIGINT, &signal_handler);
Harald Welted1252502009-01-01 01:50:32 +00001216 signal(SIGABRT, &signal_handler);
Harald Welte2cf161b2009-06-20 22:36:41 +02001217 signal(SIGUSR1, &signal_handler);
Harald Welted1252502009-01-01 01:50:32 +00001218
Harald Weltef6b7a902008-12-26 00:05:11 +00001219 while (1) {
Harald Welte4bfdfe72009-06-10 23:11:52 +08001220 bsc_upqueue(gsmnet);
Harald Welte04d3c922009-05-23 06:07:04 +00001221 bsc_select_main(0);
Harald Weltef6b7a902008-12-26 00:05:11 +00001222 }
1223}