blob: 0759f262636109571c01fe3ee87bbd463eb37c3e [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>
40#include <openbsc/gsm_04_08.h>
41#include <openbsc/select.h>
42#include <openbsc/abis_rsl.h>
43#include <openbsc/abis_nm.h>
44#include <openbsc/debug.h>
45#include <openbsc/misdn.h>
46#include <openbsc/telnet_interface.h>
47#include <openbsc/paging.h>
48#include <openbsc/e1_input.h>
49#include <openbsc/signal.h>
Harald Weltea8379772009-06-20 22:36:41 +020050#include <openbsc/talloc.h>
51
Harald Welte59b04682009-06-10 05:40:52 +080052/* global pointer to the gsm network data structure */
53static struct gsm_network *gsmnet;
54
55/* MCC and MNC for the Location Area Identifier */
56static int MCC = 1;
57static int MNC = 1;
Harald Welte59b04682009-06-10 05:40:52 +080058static int cardnr = 0;
59static int release_l2 = 0;
60static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11;
61static const char *database_name = "hlr.sqlite3";
Harald Welte3c062072009-07-28 18:25:29 +020062extern int ipacc_rtp_direct;
Harald Welte59b04682009-06-10 05:40:52 +080063
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +020064
Harald Welte59b04682009-06-10 05:40:52 +080065/* The following definitions are for OM and NM packets that we cannot yet
66 * generate by code but we just pass on */
67
68// BTS Site Manager, SET ATTRIBUTES
69
70/*
71 Object Class: BTS Site Manager
72 Instance 1: FF
73 Instance 2: FF
74 Instance 3: FF
75SET ATTRIBUTES
76 sAbisExternalTime: 2007/09/08 14:36:11
77 omLAPDRelTimer: 30sec
78 shortLAPDIntTimer: 5sec
79 emergencyTimer1: 10 minutes
80 emergencyTimer2: 0 minutes
81*/
82
83unsigned char msg_1[] =
84{
Harald Weltef739ae62009-06-20 10:42:17 +020085 NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +080086 NM_ATT_BS11_ABIS_EXT_TIME, 0x07,
87 0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE,
88 0x02,
89 0x00, 0x1E,
90 NM_ATT_BS11_SH_LAPD_INT_TIMER,
91 0x01, 0x05,
92 0x42, 0x02, 0x00, 0x0A,
93 0x44, 0x02, 0x00, 0x00
94};
95
96// BTS, SET BTS ATTRIBUTES
97
98/*
99 Object Class: BTS
100 BTS relat. Number: 0
101 Instance 2: FF
102 Instance 3: FF
103SET BTS ATTRIBUTES
104 bsIdentityCode / BSIC:
105 PLMN_colour_code: 7h
106 BS_colour_code: 7h
107 BTS Air Timer T3105: 4 ,unit 10 ms
108 btsIsHopping: FALSE
109 periodCCCHLoadIndication: 1sec
110 thresholdCCCHLoadIndication: 0%
111 cellAllocationNumber: 00h = GSM 900
112 enableInterferenceClass: 00h = Disabled
113 fACCHQual: 6 (FACCH stealing flags minus 1)
114 intaveParameter: 31 SACCH multiframes
115 interferenceLevelBoundaries:
116 Interference Boundary 1: 0Ah
117 Interference Boundary 2: 0Fh
118 Interference Boundary 3: 14h
119 Interference Boundary 4: 19h
120 Interference Boundary 5: 1Eh
121 mSTxPwrMax: 11
122 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
123 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
124 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
125 30=33dBm, 31=32dBm
126 ny1:
127 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
128 powerOutputThresholds:
129 Out Power Fault Threshold: -10 dB
130 Red Out Power Threshold: - 6 dB
131 Excessive Out Power Threshold: 5 dB
132 rACHBusyThreshold: -127 dBm
133 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
134 rfResourceIndicationPeriod: 125 SACCH multiframes
135 T200:
136 SDCCH: 044 in 5 ms
137 FACCH/Full rate: 031 in 5 ms
138 FACCH/Half rate: 041 in 5 ms
139 SACCH with TCH SAPI0: 090 in 10 ms
140 SACCH with SDCCH: 090 in 10 ms
141 SDCCH with SAPI3: 090 in 5 ms
142 SACCH with TCH SAPI3: 135 in 10 ms
143 tSync: 9000 units of 10 msec
144 tTrau: 9000 units of 10 msec
145 enableUmLoopTest: 00h = disabled
146 enableExcessiveDistance: 00h = Disabled
147 excessiveDistance: 64km
148 hoppingMode: 00h = baseband hopping
149 cellType: 00h = Standard Cell
150 BCCH ARFCN / bCCHFrequency: 1
151*/
152
Harald Weltef739ae62009-06-20 10:42:17 +0200153static unsigned char bs11_attr_bts[] =
Harald Welte59b04682009-06-10 05:40:52 +0800154{
Harald Welte59b04682009-06-10 05:40:52 +0800155 NM_ATT_BSIC, HARDCODED_BSIC,
156 NM_ATT_BTS_AIR_TIMER, 0x04,
157 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
158 NM_ATT_CCCH_L_I_P, 0x01,
159 NM_ATT_CCCH_L_T, 0x00,
160 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
161 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
162 NM_ATT_BS11_FACCH_QUAL, 0x06,
163 /* interference avg. period in numbers of SACCH multifr */
164 NM_ATT_INTAVE_PARAM, 0x1F,
165 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
166 NM_ATT_CCCH_L_T, 0x23,
167 NM_ATT_GSM_TIME, 0x28, 0x00,
168 NM_ATT_ADM_STATE, 0x03,
169 NM_ATT_RACH_B_THRESH, 0x7F,
170 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
171 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
172 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
173 NM_ATT_BS11_TSYNC, 0x23, 0x28,
174 NM_ATT_BS11_TTRAU, 0x23, 0x28,
175 NM_ATT_TEST_DUR, 0x01, 0x00,
176 NM_ATT_OUTST_ALARM, 0x01, 0x00,
177 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
178 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
179 NM_ATT_BS11_PLL, 0x01, 0x00,
180 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/,
181};
182
183// Handover Recognition, SET ATTRIBUTES
184
185/*
186Illegal Contents GSM Formatted O&M Msg
187 Object Class: Handover Recognition
188 BTS relat. Number: 0
189 Instance 2: FF
190 Instance 3: FF
191SET ATTRIBUTES
192 enableDelayPowerBudgetHO: 00h = Disabled
193 enableDistanceHO: 00h = Disabled
194 enableInternalInterCellHandover: 00h = Disabled
195 enableInternalIntraCellHandover: 00h = Disabled
196 enablePowerBudgetHO: 00h = Disabled
197 enableRXLEVHO: 00h = Disabled
198 enableRXQUALHO: 00h = Disabled
199 hoAveragingDistance: 8 SACCH multiframes
200 hoAveragingLev:
201 A_LEV_HO: 8 SACCH multiframes
202 W_LEV_HO: 1 SACCH multiframes
203 hoAveragingPowerBudget: 16 SACCH multiframes
204 hoAveragingQual:
205 A_QUAL_HO: 8 SACCH multiframes
206 W_QUAL_HO: 2 SACCH multiframes
207 hoLowerThresholdLevDL: (10 - 110) dBm
208 hoLowerThresholdLevUL: (5 - 110) dBm
209 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
210 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
211 hoThresholdLevDLintra : (20 - 110) dBm
212 hoThresholdLevULintra: (20 - 110) dBm
213 hoThresholdMsRangeMax: 20 km
214 nCell: 06h
215 timerHORequest: 3 ,unit 2 SACCH multiframes
216*/
217
218unsigned char msg_3[] =
219{
Harald Weltef739ae62009-06-20 10:42:17 +0200220 NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF,
Harald Weltec7d75062009-07-18 16:18:11 +0200221 0xD0, 0x00, /* enableDelayPowerBudgetHO */
222 0x64, 0x00, /* enableDistanceHO */
223 0x67, 0x00, /* enableInternalInterCellHandover */
224 0x68, 0x00, /* enableInternalInterCellHandover */
225 0x6A, 0x00, /* enablePowerBudgetHO */
226 0x6C, 0x00, /* enableRXLEVHO */
227 0x6D, 0x00, /* enableRXQUALHO */
228 0x6F, 0x08, /* hoAveragingDistance */
229 0x70, 0x08, 0x01, /* hoAveragingLev */
Harald Welte59b04682009-06-10 05:40:52 +0800230 0x71, 0x10, 0x10, 0x10,
Harald Weltec7d75062009-07-18 16:18:11 +0200231 0x72, 0x08, 0x02, /* hoAveragingQual */
232 0x73, 0x0A, /* hoLowerThresholdLevDL */
233 0x74, 0x05, /* hoLowerThresholdLevUL */
234 0x75, 0x06, /* hoLowerThresholdQualDL */
235 0x76, 0x06, /* hoLowerThresholdQualUL */
236 0x78, 0x14, /* hoThresholdLevDLintra */
237 0x79, 0x14, /* hoThresholdLevULintra */
238 0x7A, 0x14, /* hoThresholdMsRangeMax */
239 0x7D, 0x06, /* nCell */
240 NM_ATT_BS11_TIMER_HO_REQUEST, 0x03,
241 0x20, 0x01, 0x00,
Harald Welte59b04682009-06-10 05:40:52 +0800242 0x45, 0x01, 0x00,
243 0x48, 0x01, 0x00,
244 0x5A, 0x01, 0x00,
245 0x5B, 0x01, 0x05,
246 0x5E, 0x01, 0x1A,
247 0x5F, 0x01, 0x20,
248 0x9D, 0x01, 0x00,
249 0x47, 0x01, 0x00,
250 0x5C, 0x01, 0x64,
251 0x5D, 0x01, 0x1E,
252 0x97, 0x01, 0x20,
253 0xF7, 0x01, 0x3C,
254};
255
256// Power Control, SET ATTRIBUTES
257
258/*
259 Object Class: Power Control
260 BTS relat. Number: 0
261 Instance 2: FF
262 Instance 3: FF
263SET ATTRIBUTES
264 enableMsPowerControl: 00h = Disabled
265 enablePowerControlRLFW: 00h = Disabled
266 pcAveragingLev:
267 A_LEV_PC: 4 SACCH multiframes
268 W_LEV_PC: 1 SACCH multiframes
269 pcAveragingQual:
270 A_QUAL_PC: 4 SACCH multiframes
271 W_QUAL_PC: 2 SACCH multiframes
272 pcLowerThresholdLevDL: 0Fh
273 pcLowerThresholdLevUL: 0Ah
274 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
275 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
276 pcRLFThreshold: 0Ch
277 pcUpperThresholdLevDL: 14h
278 pcUpperThresholdLevUL: 0Fh
279 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
280 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
281 powerConfirm: 2 ,unit 2 SACCH multiframes
282 powerControlInterval: 2 ,unit 2 SACCH multiframes
283 powerIncrStepSize: 02h = 4 dB
284 powerRedStepSize: 01h = 2 dB
285 radioLinkTimeoutBs: 64 SACCH multiframes
286 enableBSPowerControl: 00h = disabled
287*/
288
289unsigned char msg_4[] =
290{
Harald Weltef739ae62009-06-20 10:42:17 +0200291 NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF,
Harald Welte59b04682009-06-10 05:40:52 +0800292 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
293 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
Harald Weltec7d75062009-07-18 16:18:11 +0200294 0x7E, 0x04, 0x01, /* pcAveragingLev */
295 0x7F, 0x04, 0x02, /* pcAveragingQual */
296 0x80, 0x0F, /* pcLowerThresholdLevDL */
297 0x81, 0x0A, /* pcLowerThresholdLevUL */
298 0x82, 0x05, /* pcLowerThresholdQualDL */
299 0x83, 0x05, /* pcLowerThresholdQualUL */
300 0x84, 0x0C, /* pcRLFThreshold */
301 0x85, 0x14, /* pcUpperThresholdLevDL */
302 0x86, 0x0F, /* pcUpperThresholdLevUL */
303 0x87, 0x04, /* pcUpperThresholdQualDL */
304 0x88, 0x04, /* pcUpperThresholdQualUL */
305 0x89, 0x02, /* powerConfirm */
306 0x8A, 0x02, /* powerConfirmInterval */
307 0x8B, 0x02, /* powerIncrStepSize */
308 0x8C, 0x01, /* powerRedStepSize */
309 0x8D, 0x40, /* radioLinkTimeoutBs */
Harald Welte59b04682009-06-10 05:40:52 +0800310 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
311};
312
313
314// Transceiver, SET TRX ATTRIBUTES (TRX 0)
315
316/*
317 Object Class: Transceiver
318 BTS relat. Number: 0
319 Tranceiver number: 0
320 Instance 3: FF
321SET TRX ATTRIBUTES
322 aRFCNList (HEX): 0001
323 txPwrMaxReduction: 00h = 30dB
324 radioMeasGran: 254 SACCH multiframes
325 radioMeasRep: 01h = enabled
326 memberOfEmergencyConfig: 01h = TRUE
327 trxArea: 00h = TRX doesn't belong to a concentric cell
328*/
329
Harald Weltef739ae62009-06-20 10:42:17 +0200330static unsigned char bs11_attr_radio[] =
Harald Welte59b04682009-06-10 05:40:52 +0800331{
Harald Welte59b04682009-06-10 05:40:52 +0800332 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
333 NM_ATT_RF_MAXPOWR_R, 0x00,
334 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0xFE,
335 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
336 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
337 NM_ATT_BS11_TRX_AREA, 0x01, 0x00,
338};
339
340static unsigned char nanobts_attr_bts[] = {
341 NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
342 /* interference avg. period in numbers of SACCH multifr */
343 NM_ATT_INTAVE_PARAM, 0x06,
344 /* conn fail based on SACCH error rate */
345 NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
346 NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
347 NM_ATT_MAX_TA, 0x3f,
348 NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
349 NM_ATT_CCCH_L_T, 10, /* percent */
350 NM_ATT_CCCH_L_I_P, 1, /* seconds */
351 NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
352 NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
353 NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
354 NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
355 NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
356 NM_ATT_BSIC, HARDCODED_BSIC,
357};
358
359static unsigned char nanobts_attr_radio[] = {
360 NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
361 NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
362};
363
364static unsigned char nanobts_attr_e0[] = {
Harald Welte4206d982009-07-12 09:33:54 +0200365 NM_ATT_IPACC_STREAM_ID, 0x00,
366 NM_ATT_IPACC_DST_IP_PORT, 0x0b, 0xbb, /* TCP PORT for RSL */
Harald Welte59b04682009-06-10 05:40:52 +0800367};
368
369/* Callback function to be called whenever we get a GSM 12.21 state change event */
370int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
371 struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
372{
373 struct gsm_bts *bts;
374 struct gsm_bts_trx *trx;
375 struct gsm_bts_trx_ts *ts;
376
377 /* This is currently only required on nanoBTS */
378
379 switch (evt) {
380 case EVT_STATECHG_OPER:
381 switch (obj_class) {
382 case NM_OC_SITE_MANAGER:
383 bts = container_of(obj, struct gsm_bts, site_mgr);
384 if (old_state->operational != 2 && new_state->operational == 2) {
385 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
386 }
387 break;
388 case NM_OC_BTS:
389 bts = obj;
390 if (new_state->availability == 5) {
391 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
392 sizeof(nanobts_attr_bts));
393 abis_nm_opstart(bts, NM_OC_BTS,
394 bts->bts_nr, 0xff, 0xff);
395 abis_nm_chg_adm_state(bts, NM_OC_BTS,
396 bts->bts_nr, 0xff, 0xff,
397 NM_STATE_UNLOCKED);
398 }
399 break;
400 case NM_OC_CHANNEL:
401 ts = obj;
402 trx = ts->trx;
403 if (new_state->availability == 5) {
404 if (ts->nr == 0 && trx == trx->bts->c0)
405 abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
406 else
407 abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
408 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
409 trx->bts->bts_nr, trx->nr, ts->nr);
410 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
411 trx->bts->bts_nr, trx->nr, ts->nr,
412 NM_STATE_UNLOCKED);
413 }
414 break;
415 default:
416 break;
417 }
418 break;
419 default:
420 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
421 break;
422 }
423 return 0;
424}
425
426/* Callback function to be called every time we receive a 12.21 SW activated report */
427static int sw_activ_rep(struct msgb *mb)
428{
429 struct abis_om_fom_hdr *foh = msgb_l3(mb);
430 struct gsm_bts_trx *trx = mb->trx;
431
432 switch (foh->obj_class) {
433 case NM_OC_BASEB_TRANSC:
434 /* TRX software is active, tell it to initiate RSL Link */
435 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
436 trx->bts->bts_nr, trx->nr, 0xff,
437 nanobts_attr_e0, sizeof(nanobts_attr_e0));
438 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC,
439 trx->bts->bts_nr, trx->nr, 0xff);
440 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC,
441 trx->bts->bts_nr, trx->nr, 0xff,
442 NM_STATE_UNLOCKED);
443 break;
444 case NM_OC_RADIO_CARRIER:
445 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
446 sizeof(nanobts_attr_radio));
447 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
448 trx->bts->bts_nr, trx->nr, 0xff);
449 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
450 trx->bts->bts_nr, trx->nr, 0xff,
451 NM_STATE_UNLOCKED);
452 break;
453 }
454 return 0;
455}
456
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200457/* Callback function for NACK on the OML NM */
458static int oml_msg_nack(int mt)
459{
460 if (mt == NM_MT_SET_BTS_ATTR_NACK) {
461 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
462 "Was the bts type and frequency properly specified?\n");
463 exit(-1);
464 }
465
466 return 0;
467}
468
Harald Welte59b04682009-06-10 05:40:52 +0800469/* Callback function to be called every time we receive a signal from NM */
470static int nm_sig_cb(unsigned int subsys, unsigned int signal,
471 void *handler_data, void *signal_data)
472{
473 switch (signal) {
474 case S_NM_SW_ACTIV_REP:
475 return sw_activ_rep(signal_data);
Holger Hans Peter Freytherefedf942009-06-10 10:48:14 +0200476 case S_NM_NACK:
477 return oml_msg_nack((int)signal_data);
Harald Welte59b04682009-06-10 05:40:52 +0800478 default:
479 break;
480 }
481 return 0;
482}
483
484static void bootstrap_om_nanobts(struct gsm_bts *bts)
485{
486 /* We don't do callback based bootstrapping, but event driven (see above) */
487}
488
489static void bootstrap_om_bs11(struct gsm_bts *bts)
490{
Harald Weltee712a5f2009-06-21 16:17:15 +0200491 struct gsm_bts_trx *trx = bts->c0;
Harald Weltecf833cd2009-08-06 17:40:24 +0200492 int base_ts;
493
494 switch (bts->nr) {
495 case 0:
496 /* First BTS uses E1 TS 01,02,03,04,05 */
497 base_ts = HARDCODED_BTS0_TS - 1;
498 break;
499 case 1:
500 /* Second BTS uses E1 TS 06,07,08,09,10 */
501 base_ts = HARDCODED_BTS1_TS - 1;
502 break;
503 case 2:
504 /* Third BTS uses E1 TS 11,12,13,14,15 */
505 base_ts = HARDCODED_BTS2_TS - 1;
506 default:
507 return;
508 }
Harald Welte59b04682009-06-10 05:40:52 +0800509
510 /* stop sending event reports */
511 abis_nm_event_reports(bts, 0);
512
513 /* begin DB transmission */
514 abis_nm_bs11_db_transmission(bts, 1);
515
516 /* end DB transmission */
517 abis_nm_bs11_db_transmission(bts, 0);
518
519 /* Reset BTS Site manager resource */
520 abis_nm_bs11_reset_resource(bts);
521
522 /* begin DB transmission */
523 abis_nm_bs11_db_transmission(bts, 1);
524
525 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
Harald Weltef739ae62009-06-20 10:42:17 +0200526 abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
Harald Welte59b04682009-06-10 05:40:52 +0800527 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
528 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
529
530 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200531 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Weltef739ae62009-06-20 10:42:17 +0200532 abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
Harald Welte59b04682009-06-10 05:40:52 +0800533
534 /* Use TEI 1 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200535 abis_nm_establish_tei(bts, 0, 0, base_ts+1, 0xff, 0x01);
Harald Welte59b04682009-06-10 05:40:52 +0800536 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
537
Harald Welte59b04682009-06-10 05:40:52 +0800538 /* SET CHANNEL ATTRIBUTE TS1 */
539 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
540 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200541 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+2, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800542
543 /* SET CHANNEL ATTRIBUTE TS2 */
544 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
545 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200546 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+2, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800547
548 /* SET CHANNEL ATTRIBUTE TS3 */
549 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
550 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200551 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+2, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800552
553 /* SET CHANNEL ATTRIBUTE TS4 */
554 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
555 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200556 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+3, 0);
Harald Welte59b04682009-06-10 05:40:52 +0800557
558 /* SET CHANNEL ATTRIBUTE TS5 */
559 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
560 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200561 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+3, 1);
Harald Welte59b04682009-06-10 05:40:52 +0800562
563 /* SET CHANNEL ATTRIBUTE TS6 */
564 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
565 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200566 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+3, 2);
Harald Welte59b04682009-06-10 05:40:52 +0800567
568 /* SET CHANNEL ATTRIBUTE TS7 */
569 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
570 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200571 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+3, 3);
Harald Welte59b04682009-06-10 05:40:52 +0800572
Harald Welte25b70c52009-07-29 16:42:16 +0200573 trx = gsm_bts_trx_num(bts, 1);
574 if (trx) {
575 u_int8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
576 u_int8_t arfcn_low = trx->arfcn & 0xff;
577 u_int8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
578 memcpy(trx1_attr_radio, bs11_attr_radio,
579 sizeof(trx1_attr_radio));
580
581 /* patch ARFCN into TRX Attributes */
582 trx1_attr_radio[2] &= 0xf0;
583 trx1_attr_radio[2] |= arfcn_high;
584 trx1_attr_radio[3] = arfcn_low;
585
586 /* Connect signalling of TRX1 to e1_0/ts1/64kbps */
Harald Weltecf833cd2009-08-06 17:40:24 +0200587 abis_nm_conn_terr_sign(trx, 0, base_ts+1, 0xff);
Harald Welte25b70c52009-07-29 16:42:16 +0200588 /* FIXME: TRX ATTRIBUTE */
589 abis_nm_set_radio_attr(trx, trx1_attr_radio,
590 sizeof(trx1_attr_radio));
591
592 /* Use TEI 2 for signalling */
Harald Weltecf833cd2009-08-06 17:40:24 +0200593 abis_nm_establish_tei(bts, 1, 0, base_ts+1, 0xff, 0x02);
Harald Welte25b70c52009-07-29 16:42:16 +0200594
Harald Welte1a503162009-08-04 01:31:53 +0200595 /* SET CHANNEL ATTRIBUTE TS0 */
596 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_TCHFull);
597 /* Connect traffic of bts0/trx0/ts0 to e1_0/ts4/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200598 abis_nm_conn_terr_traf(&trx->ts[0], 0, base_ts+4, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200599
600 /* SET CHANNEL ATTRIBUTE TS1 */
601 abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
602 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts4/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200603 abis_nm_conn_terr_traf(&trx->ts[1], 0, base_ts+4, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200604
605 /* SET CHANNEL ATTRIBUTE TS2 */
606 abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
607 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts4/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200608 abis_nm_conn_terr_traf(&trx->ts[2], 0, base_ts+4, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200609
610 /* SET CHANNEL ATTRIBUTE TS3 */
611 abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
612 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts4/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200613 abis_nm_conn_terr_traf(&trx->ts[3], 0, base_ts+4, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200614
615 /* SET CHANNEL ATTRIBUTE TS4 */
616 abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
617 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts5/a */
Harald Weltecf833cd2009-08-06 17:40:24 +0200618 abis_nm_conn_terr_traf(&trx->ts[4], 0, base_ts+5, 0);
Harald Welte25b70c52009-07-29 16:42:16 +0200619
620 /* SET CHANNEL ATTRIBUTE TS5 */
621 abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
622 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts5/b */
Harald Weltecf833cd2009-08-06 17:40:24 +0200623 abis_nm_conn_terr_traf(&trx->ts[5], 0, base_ts+5, 1);
Harald Welte25b70c52009-07-29 16:42:16 +0200624
625 /* SET CHANNEL ATTRIBUTE TS6 */
626 abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
627 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts5/c */
Harald Weltecf833cd2009-08-06 17:40:24 +0200628 abis_nm_conn_terr_traf(&trx->ts[6], 0, base_ts+5, 2);
Harald Welte25b70c52009-07-29 16:42:16 +0200629
630 /* SET CHANNEL ATTRIBUTE TS7 */
631 abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
632 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts5/d */
Harald Weltecf833cd2009-08-06 17:40:24 +0200633 abis_nm_conn_terr_traf(&trx->ts[7], 0, base_ts+5, 3);
Harald Welte25b70c52009-07-29 16:42:16 +0200634 }
635
Harald Welte59b04682009-06-10 05:40:52 +0800636 /* end DB transmission */
637 abis_nm_bs11_db_transmission(bts, 0);
638
639 /* Reset BTS Site manager resource */
640 abis_nm_bs11_reset_resource(bts);
641
642 /* restart sending event reports */
643 abis_nm_event_reports(bts, 1);
644}
645
646static void bootstrap_om(struct gsm_bts *bts)
647{
648 fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
649
650 switch (bts->type) {
651 case GSM_BTS_TYPE_BS11:
652 bootstrap_om_bs11(bts);
653 break;
654 case GSM_BTS_TYPE_NANOBTS_900:
655 case GSM_BTS_TYPE_NANOBTS_1800:
656 bootstrap_om_nanobts(bts);
657 break;
658 default:
659 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
660 }
661}
662
663static int shutdown_om(struct gsm_bts *bts)
664{
Harald Welte3b714502009-08-06 17:43:50 +0200665 fprintf(stdout, "shutting down OML for BTS %u\n", bts->nr);
666
Harald Welte59b04682009-06-10 05:40:52 +0800667 /* stop sending event reports */
668 abis_nm_event_reports(bts, 0);
669
670 /* begin DB transmission */
671 abis_nm_bs11_db_transmission(bts, 1);
672
673 /* end DB transmission */
674 abis_nm_bs11_db_transmission(bts, 0);
675
676 /* Reset BTS Site manager resource */
677 abis_nm_bs11_reset_resource(bts);
678
679 return 0;
680}
681
682static int shutdown_net(struct gsm_network *net)
683{
Harald Weltee712a5f2009-06-21 16:17:15 +0200684 struct gsm_bts *bts;
685
686 llist_for_each_entry(bts, &net->bts_list, list) {
Harald Welte59b04682009-06-10 05:40:52 +0800687 int rc;
Harald Weltee712a5f2009-06-21 16:17:15 +0200688 rc = shutdown_om(bts);
Harald Welte59b04682009-06-10 05:40:52 +0800689 if (rc < 0)
690 return rc;
691 }
692
693 return 0;
694}
695
696struct bcch_info {
697 u_int8_t type;
698 u_int8_t len;
699 const u_int8_t *data;
700};
701
702/*
703SYSTEM INFORMATION TYPE 1
704 Cell channel description
705 Format-ID bit map 0
706 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
707 RACH Control Parameters
708 maximum 7 retransmissions
709 8 slots used to spread transmission
710 cell not barred for access
711 call reestablishment not allowed
712 Access Control Class = 0000
713*/
714static u_int8_t si1[] = {
715 /* header */0x55, 0x06, 0x19,
716 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
718 /* rach */0xD5, 0x00, 0x00,
719 /* s1 reset*/0x2B
720};
721
722/*
723 SYSTEM INFORMATION TYPE 2
724 Neighbour Cells Description
725 EXT-IND: Carries the complete BA
726 BA-IND = 0
727 Format-ID bit map 0
728 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
729 NCC permitted (NCC) = FF
730 RACH Control Parameters
731 maximum 7 retransmissions
732 8 slots used to spread transmission
733 cell not barred for access
734 call reestablishment not allowed
735 Access Control Class = 0000
736*/
737static u_int8_t si2[] = {
738 /* header */0x59, 0x06, 0x1A,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 /* ncc */0xFF,
742 /* rach*/0xD5, 0x00, 0x00
743};
744
745/*
746SYSTEM INFORMATION TYPE 3
747 Cell identity = 00001 (1h)
748 Location area identification
749 Mobile Country Code (MCC): 001
750 Mobile Network Code (MNC): 01
751 Location Area Code (LAC): 00001 (1h)
752 Control Channel Description
753 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
754 0 blocks reserved for access grant
755 1 channel used for CCCH, with SDCCH
756 5 multiframes period for PAGING REQUEST
757 Time-out T3212 = 0
758 Cell Options BCCH
759 Power control indicator: not set
760 MSs shall not use uplink DTX
761 Radio link timeout = 36
762 Cell Selection Parameters
763 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
764 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
765 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
766 Half rate support (NECI): New establishment causes are not supported
767 min.RX signal level for MS = 0
768 RACH Control Parameters
769 maximum 7 retransmissions
770 8 slots used to spread transmission
771 cell not barred for access
772 call reestablishment not allowed
773 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200774 SI 3 Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800775*/
776static u_int8_t si3[] = {
777 /* header */0x49, 0x06, 0x1B,
778 /* cell */0x00, 0x01,
779 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
780 /* desc */0x01, 0x03, 0x00,
781 /* option*/0x28,
782 /* selection*/0x62, 0x00,
783 /* rach */0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200784 /* rest */ 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800785};
786
787/*
788SYSTEM INFORMATION TYPE 4
789 Location area identification
790 Mobile Country Code (MCC): 001
791 Mobile Network Code (MNC): 01
792 Location Area Code (LAC): 00001 (1h)
793 Cell Selection Parameters
794 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
795 max.TX power level MS may use for CCH = 2
796 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
797 Half rate support (NECI): New establishment causes are not supported
798 min.RX signal level for MS = 0
799 RACH Control Parameters
800 maximum 7 retransmissions
801 8 slots used to spread transmission
802 cell not barred for access
803 call reestablishment not allowed
804 Access Control Class = 0000
Harald Weltec1c4a952009-07-05 13:41:40 +0200805 CBCH Channel Description
Harald Welte59b04682009-06-10 05:40:52 +0800806 Type = SDCCH/4[2]
807 Timeslot Number: 0
808 Training Sequence Code: 7h
809 ARFCN: 1
Harald Weltec1c4a952009-07-05 13:41:40 +0200810 SI Rest Octets (not present)
Harald Welte59b04682009-06-10 05:40:52 +0800811*/
812static u_int8_t si4[] = {
813 /* header */0x41, 0x06, 0x1C,
814 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
815 /* sel */0x62, 0x00,
816 /* rach*/0xD5, 0x00, 0x00,
Harald Weltec1c4a952009-07-05 13:41:40 +0200817 /* cbch chan desc */ 0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/,
818 /* rest octets */ 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B
Harald Welte59b04682009-06-10 05:40:52 +0800819};
820
821/*
822 SYSTEM INFORMATION TYPE 5
823 Neighbour Cells Description
824 EXT-IND: Carries the complete BA
825 BA-IND = 0
826 Format-ID bit map 0
827 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
828*/
829
830static u_int8_t si5[] = {
831 /* header without l2 len*/0x06, 0x1D,
832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
834};
835
836// SYSTEM INFORMATION TYPE 6
837
838/*
839SACCH FILLING
840 System Info Type: SYSTEM INFORMATION 6
841 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
842
843SYSTEM INFORMATION TYPE 6
844 Cell identity = 00001 (1h)
845 Location area identification
846 Mobile Country Code (MCC): 001
847 Mobile Network Code (MNC): 01
848 Location Area Code (LAC): 00001 (1h)
849 Cell Options SACCH
850 Power control indicator: not set
851 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
852 Radio link timeout = 36
853 NCC permitted (NCC) = FF
854*/
855
856static u_int8_t si6[] = {
857 /* header */0x06, 0x1E,
858 /* cell id*/ 0x00, 0x01,
859 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
860 /* options */ 0x28,
861 /* ncc */ 0xFF,
862};
863
864
865
866static const struct bcch_info bcch_infos[] = {
867 {
868 .type = RSL_SYSTEM_INFO_1,
869 .len = sizeof(si1),
870 .data = si1,
871 }, {
872 .type = RSL_SYSTEM_INFO_2,
873 .len = sizeof(si2),
874 .data = si2,
875 }, {
876 .type = RSL_SYSTEM_INFO_3,
877 .len = sizeof(si3),
878 .data = si3,
879 }, {
880 .type = RSL_SYSTEM_INFO_4,
881 .len = sizeof(si4),
882 .data = si4,
883 },
884};
885
886static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
887static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
888static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
889static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
890static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
891static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
892
893/* set all system information types */
894static int set_system_infos(struct gsm_bts_trx *trx)
895{
896 int i;
897
Harald Welte6ab22d22009-08-06 17:41:19 +0200898 if (trx == trx->bts->c0) {
899 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
900 rsl_bcch_info(trx, bcch_infos[i].type,
901 bcch_infos[i].data,
902 bcch_infos[i].len);
903 }
Harald Welte59b04682009-06-10 05:40:52 +0800904 }
905 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
906 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
907
908 return 0;
909}
910
911/*
912 * Patch the various SYSTEM INFORMATION tables to update
913 * the LAI
914 */
915static void patch_tables(struct gsm_bts *bts)
916{
Harald Weltee712a5f2009-06-21 16:17:15 +0200917 u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
918 u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
Harald Welte59b04682009-06-10 05:40:52 +0800919 /* covert the raw packet to the struct */
920 struct gsm48_system_information_type_3 *type_3 =
921 (struct gsm48_system_information_type_3*)&si3;
922 struct gsm48_system_information_type_4 *type_4 =
923 (struct gsm48_system_information_type_4*)&si4;
924 struct gsm48_system_information_type_6 *type_6 =
925 (struct gsm48_system_information_type_6*)&si6;
926 struct gsm48_loc_area_id lai;
927
928 gsm0408_generate_lai(&lai, bts->network->country_code,
929 bts->network->network_code,
930 bts->location_area_code);
931
932 /* assign the MCC and MNC */
933 type_3->lai = lai;
934 type_4->lai = lai;
935 type_6->lai = lai;
936
937 /* patch ARFCN into BTS Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200938 bs11_attr_bts[69] &= 0xf0;
939 bs11_attr_bts[69] |= arfcn_high;
940 bs11_attr_bts[70] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800941 nanobts_attr_bts[42] &= 0xf0;
942 nanobts_attr_bts[42] |= arfcn_high;
943 nanobts_attr_bts[43] = arfcn_low;
944
945 /* patch ARFCN into TRX Attributes */
Harald Weltef739ae62009-06-20 10:42:17 +0200946 bs11_attr_radio[2] &= 0xf0;
947 bs11_attr_radio[2] |= arfcn_high;
948 bs11_attr_radio[3] = arfcn_low;
Harald Welte59b04682009-06-10 05:40:52 +0800949 nanobts_attr_radio[5] &= 0xf0;
950 nanobts_attr_radio[5] |= arfcn_high;
951 nanobts_attr_radio[6] = arfcn_low;
952
953 type_4->data[2] &= 0xf0;
954 type_4->data[2] |= arfcn_high;
955 type_4->data[3] = arfcn_low;
956
957 /* patch Control Channel Description 10.5.2.11 */
958 type_3->control_channel_desc = bts->chan_desc;
959
960 /* patch BSIC */
Harald Weltef739ae62009-06-20 10:42:17 +0200961 bs11_attr_bts[1] = bts->bsic;
Harald Welte59b04682009-06-10 05:40:52 +0800962 nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
Harald Welte52281c12009-07-21 22:12:23 +0200963
964 /* patch TSC */
965 si4[15] &= ~0xe0;
966 si4[15] |= (bts->tsc & 7) << 5;
Harald Welte59b04682009-06-10 05:40:52 +0800967}
968
969
970static void bootstrap_rsl(struct gsm_bts_trx *trx)
971{
972 fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
Harald Welte52281c12009-07-21 22:12:23 +0200973 "using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
Harald Welte62868882009-08-08 16:12:58 +0200974 trx->bts->nr, trx->nr, gsmnet->country_code,
975 gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
Harald Welte59b04682009-06-10 05:40:52 +0800976 set_system_infos(trx);
977}
978
979void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
980{
981 switch (event) {
982 case EVT_E1_TEI_UP:
983 switch (type) {
984 case E1INP_SIGN_OML:
985 bootstrap_om(trx->bts);
986 break;
987 case E1INP_SIGN_RSL:
988 bootstrap_rsl(trx);
989 break;
990 default:
991 break;
992 }
993 break;
994 case EVT_E1_TEI_DN:
995 fprintf(stderr, "Lost some E1 TEI link\n");
996 /* FIXME: deal with TEI or L1 link loss */
997 break;
998 default:
999 break;
1000 }
1001}
1002
1003static int bootstrap_bts(struct gsm_bts *bts)
1004{
Harald Welte62868882009-08-08 16:12:58 +02001005 switch (bts->type) {
1006 case GSM_BTS_TYPE_NANOBTS_1800:
1007 if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
1008 fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
1009 return -EINVAL;
1010 }
1011 break;
1012 case GSM_BTS_TYPE_BS11:
1013 case GSM_BTS_TYPE_NANOBTS_900:
1014 /* Assume we have a P-GSM900 here */
1015 if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
1016 fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1017 return -EINVAL;
1018 }
1019 break;
1020 case GSM_BTS_TYPE_UNKNOWN:
1021 fprintf(stderr, "Unknown BTS. Please specify\n");
1022 return -EINVAL;
1023 }
Harald Welte59b04682009-06-10 05:40:52 +08001024
1025 /* Control Channel Description */
1026 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
1027 bts->chan_desc.att = 1;
1028 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1029 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1030 bts->chan_desc.t3212 = 0;
1031
1032 patch_tables(bts);
1033
1034 paging_init(bts);
1035
Harald Welte59b04682009-06-10 05:40:52 +08001036 return 0;
1037}
1038
1039static int bootstrap_network(void)
1040{
Harald Welte62868882009-08-08 16:12:58 +02001041 struct gsm_bts *bts;
Harald Welteca9af2b2009-08-06 17:54:21 +02001042 int rc;
1043
Harald Welte59b04682009-06-10 05:40:52 +08001044 /* initialize our data structures */
Harald Weltee712a5f2009-06-21 16:17:15 +02001045 gsmnet = gsm_network_init(MCC, MNC, mncc_recv);
Harald Welte59b04682009-06-10 05:40:52 +08001046 if (!gsmnet)
1047 return -ENOMEM;
1048
Harald Welte62868882009-08-08 16:12:58 +02001049 gsmnet->name_long = talloc_strdup(gsmnet, "OpenBSC");
1050 gsmnet->name_short = talloc_strdup(gsmnet, "OpenBSC");
Harald Welte59b04682009-06-10 05:40:52 +08001051
Harald Welte59b04682009-06-10 05:40:52 +08001052 if (db_init(database_name)) {
1053 printf("DB: Failed to init database. Please check the option settings.\n");
1054 return -1;
1055 }
1056 printf("DB: Database initialized.\n");
1057
1058 if (db_prepare()) {
1059 printf("DB: Failed to prepare database.\n");
1060 return -1;
1061 }
1062 printf("DB: Database prepared.\n");
1063
1064 telnet_init(gsmnet, 4242);
Harald Welte62868882009-08-08 16:12:58 +02001065 rc = vty_read_config_file("openbsc.cfg");
1066 if (rc < 0)
1067 return rc;
Harald Welte59b04682009-06-10 05:40:52 +08001068
1069 register_signal_handler(SS_NM, nm_sig_cb, NULL);
1070
Harald Welte62868882009-08-08 16:12:58 +02001071 llist_for_each_entry(bts, &gsmnet->bts_list, list) {
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001072 bootstrap_bts(bts);
Harald Welte62868882009-08-08 16:12:58 +02001073 if (is_ipaccess_bts(bts))
1074 rc = ipaccess_setup(bts);
1075 else
1076 rc = e1_reconfig_bts(bts);
Holger Hans Peter Freythera6429e32009-07-16 15:24:27 +02001077
Harald Welte62868882009-08-08 16:12:58 +02001078 if (rc < 0)
1079 exit (1);
Harald Welte59b04682009-06-10 05:40:52 +08001080 }
Harald Welte62868882009-08-08 16:12:58 +02001081
1082 return 0;
Harald Welte59b04682009-06-10 05:40:52 +08001083}
1084
1085static void create_pcap_file(char *file)
1086{
1087 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1088 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1089
1090 if (fd < 0) {
1091 perror("Failed to open file for pcap");
1092 return;
1093 }
1094
1095 e1_set_pcap_fd(fd);
1096}
1097
1098static void print_usage()
1099{
1100 printf("Usage: bsc_hack\n");
1101}
1102
1103static void print_help()
1104{
1105 printf(" Some useful help...\n");
Harald Welte62868882009-08-08 16:12:58 +02001106 printf(" -h --help this text\n");
Harald Welte59b04682009-06-10 05:40:52 +08001107 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
1108 printf(" -s --disable-color\n");
Harald Welte59b04682009-06-10 05:40:52 +08001109 printf(" -l --database db-name The database to use\n");
1110 printf(" -a --authorize-everyone Allow everyone into the network.\n");
1111 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
1112 printf(" -p --pcap file The filename of the pcap file\n");
Harald Welte59b04682009-06-10 05:40:52 +08001113 printf(" -C --cardnr number For bs11 select E1 card number other than 0\n");
1114 printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n");
Harald Welte59b04682009-06-10 05:40:52 +08001115}
1116
1117static void handle_options(int argc, char** argv)
1118{
1119 while (1) {
Harald Weltea8379772009-06-20 22:36:41 +02001120 int option_index = 0, c;
Harald Welte59b04682009-06-10 05:40:52 +08001121 static struct option long_options[] = {
1122 {"help", 0, 0, 'h'},
1123 {"debug", 1, 0, 'd'},
1124 {"disable-color", 0, 0, 's'},
Harald Welte59b04682009-06-10 05:40:52 +08001125 {"database", 1, 0, 'l'},
1126 {"authorize-everyone", 0, 0, 'a'},
1127 {"reject-cause", 1, 0, 'r'},
1128 {"pcap", 1, 0, 'p'},
Harald Welte59b04682009-06-10 05:40:52 +08001129 {"cardnr", 1, 0, 'C'},
1130 {"release-l2", 0, 0, 'R'},
1131 {"timestamp", 0, 0, 'T'},
Harald Welte3c062072009-07-28 18:25:29 +02001132 {"rtp-proxy", 0, 0, 'P'},
Harald Welte59b04682009-06-10 05:40:52 +08001133 {0, 0, 0, 0}
1134 };
1135
Harald Welte62868882009-08-08 16:12:58 +02001136 c = getopt_long(argc, argv, "hd:sl:ar:p:C:RTP",
Harald Welte59b04682009-06-10 05:40:52 +08001137 long_options, &option_index);
1138 if (c == -1)
1139 break;
1140
1141 switch (c) {
1142 case 'h':
1143 print_usage();
1144 print_help();
1145 exit(0);
1146 case 's':
1147 debug_use_color(0);
1148 break;
1149 case 'd':
1150 debug_parse_category_mask(optarg);
1151 break;
Harald Welte59b04682009-06-10 05:40:52 +08001152 case 'l':
1153 database_name = strdup(optarg);
1154 break;
1155 case 'a':
1156 gsm0408_allow_everyone(1);
1157 break;
1158 case 'r':
1159 gsm0408_set_reject_cause(atoi(optarg));
1160 break;
1161 case 'p':
1162 create_pcap_file(optarg);
1163 break;
1164 case 't':
1165 BTS_TYPE = parse_btstype(optarg);
1166 break;
1167 case 'C':
1168 cardnr = atoi(optarg);
1169 break;
1170 case 'R':
1171 release_l2 = 1;
1172 break;
1173 case 'T':
1174 debug_timestamp(1);
1175 break;
Harald Welte3c062072009-07-28 18:25:29 +02001176 case 'P':
1177 ipacc_rtp_direct = 0;
1178 break;
Harald Welte59b04682009-06-10 05:40:52 +08001179 default:
1180 /* ignore */
1181 break;
1182 }
1183 }
1184}
1185
1186static void signal_handler(int signal)
1187{
1188 fprintf(stdout, "signal %u received\n", signal);
1189
1190 switch (signal) {
Harald Welte3b714502009-08-06 17:43:50 +02001191 case SIGINT:
Harald Welte59b04682009-06-10 05:40:52 +08001192 shutdown_net(gsmnet);
Harald Welte3b714502009-08-06 17:43:50 +02001193 sleep(3);
1194 exit(0);
Harald Welte59b04682009-06-10 05:40:52 +08001195 break;
Harald Welte4d5e6d52009-08-07 00:29:44 +02001196 case SIGABRT:
1197 /* in case of abort, we want to obtain a talloc report
1198 * and then return to the caller, who will abort the process */
Harald Weltea8379772009-06-20 22:36:41 +02001199 case SIGUSR1:
1200 talloc_report_full(tall_bsc_ctx, stderr);
1201 break;
Harald Welte59b04682009-06-10 05:40:52 +08001202 default:
1203 break;
1204 }
1205}
1206
1207int main(int argc, char **argv)
1208{
1209 int rc;
1210
Harald Weltea8379772009-06-20 22:36:41 +02001211 tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
1212
Harald Welte59b04682009-06-10 05:40:52 +08001213 /* parse options */
1214 handle_options(argc, argv);
1215
1216 /* seed the PRNG */
1217 srand(time(NULL));
1218
1219 rc = bootstrap_network();
1220 if (rc < 0)
1221 exit(1);
1222
Harald Welte3b714502009-08-06 17:43:50 +02001223 signal(SIGINT, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001224 signal(SIGABRT, &signal_handler);
Harald Weltea8379772009-06-20 22:36:41 +02001225 signal(SIGUSR1, &signal_handler);
Harald Welte59b04682009-06-10 05:40:52 +08001226
1227 while (1) {
Harald Welte03740842009-06-10 23:11:52 +08001228 bsc_upqueue(gsmnet);
Harald Welte59b04682009-06-10 05:40:52 +08001229 bsc_select_main(0);
1230 }
1231}