blob: 80b0f3b2caf57380951add53f8a93ef32bec0ba3 [file] [log] [blame]
Harald Welte52b1f982008-12-23 20:25:15 +00001/* A hackish minimal BSC (+MSC +HLR) implementation */
2
3/* (C) 2008 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 Welte255539c2008-12-28 02:26:27 +000040#include <openbsc/gsm_04_08.h>
Harald Weltead384642008-12-26 10:20:07 +000041#include <openbsc/select.h>
Harald Welte8470bf22008-12-25 23:28:35 +000042#include <openbsc/abis_rsl.h>
43#include <openbsc/abis_nm.h>
Harald Welte702d8702008-12-26 20:25:35 +000044#include <openbsc/debug.h>
Holger Freyther5677ae32008-12-27 09:41:03 +000045#include <openbsc/misdn.h>
Holger Freyther219518d2009-01-02 22:04:43 +000046#include <openbsc/telnet_interface.h>
Harald Welte38c2f132009-01-06 23:10:57 +000047#include <openbsc/paging.h>
Harald Welte1fa60c82009-02-09 18:13:26 +000048#include <openbsc/e1_input.h>
Harald Welte52b1f982008-12-23 20:25:15 +000049
50/* global pointer to the gsm network data structure */
51static struct gsm_network *gsmnet;
52
Holger Freytherefde7fb2008-12-28 14:14:56 +000053/* MCC and MNC for the Location Area Identifier */
54static int MCC = 1;
55static int MNC = 1;
Harald Welte98981882009-01-06 18:59:11 +000056static int ARFCN = HARDCODED_ARFCN;
Holger Freytherbde36102008-12-28 22:51:39 +000057static const char *database_name = "hlr.sqlite3";
Holger Freytherefde7fb2008-12-28 14:14:56 +000058
Harald Welte52b1f982008-12-23 20:25:15 +000059/* The following definitions are for OM and NM packets that we cannot yet
60 * generate by code but we just pass on */
61
62// BTS Site Manager, SET ATTRIBUTES
63
64/*
65 Object Class: BTS Site Manager
66 Instance 1: FF
67 Instance 2: FF
68 Instance 3: FF
69SET ATTRIBUTES
70 sAbisExternalTime: 2007/09/08 14:36:11
71 omLAPDRelTimer: 30sec
72 shortLAPDIntTimer: 5sec
73 emergencyTimer1: 10 minutes
74 emergencyTimer2: 0 minutes
75*/
76
77unsigned char msg_1[] =
78{
79 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
80 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
81 0x02, 0x00, 0x00
82};
83
84// BTS, SET BTS ATTRIBUTES
85
86/*
87 Object Class: BTS
88 BTS relat. Number: 0
89 Instance 2: FF
90 Instance 3: FF
91SET BTS ATTRIBUTES
92 bsIdentityCode / BSIC:
93 PLMN_colour_code: 7h
94 BS_colour_code: 7h
95 BTS Air Timer T3105: 4 ,unit 10 ms
96 btsIsHopping: FALSE
Harald Welte83282292009-02-01 16:22:19 +000097 periodCCCHLoadIndication: 1sec
Harald Welte0bbb8b22009-02-06 12:49:11 +000098 thresholdCCCHLoadIndication: 50%
Harald Welte52b1f982008-12-23 20:25:15 +000099 cellAllocationNumber: 00h = GSM 900
100 enableInterferenceClass: 00h = Disabled
101 fACCHQual: 6 (FACCH stealing flags minus 1)
102 intaveParameter: 31 SACCH multiframes
103 interferenceLevelBoundaries:
104 Interference Boundary 1: 0Ah
105 Interference Boundary 2: 0Fh
106 Interference Boundary 3: 14h
107 Interference Boundary 4: 19h
108 Interference Boundary 5: 1Eh
109 mSTxPwrMax: 11
110 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
111 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
112 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
113 30=33dBm, 31=32dBm
114 ny1:
115 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
116 powerOutputThresholds:
117 Out Power Fault Threshold: -10 dB
118 Red Out Power Threshold: - 6 dB
119 Excessive Out Power Threshold: 5 dB
120 rACHBusyThreshold: -127 dBm
121 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
122 rfResourceIndicationPeriod: 125 SACCH multiframes
123 T200:
124 SDCCH: 044 in 5 ms
125 FACCH/Full rate: 031 in 5 ms
126 FACCH/Half rate: 041 in 5 ms
127 SACCH with TCH SAPI0: 090 in 10 ms
128 SACCH with SDCCH: 090 in 10 ms
129 SDCCH with SAPI3: 090 in 5 ms
130 SACCH with TCH SAPI3: 135 in 10 ms
131 tSync: 9000 units of 10 msec
132 tTrau: 9000 units of 10 msec
133 enableUmLoopTest: 00h = disabled
134 enableExcessiveDistance: 00h = Disabled
135 excessiveDistance: 64km
136 hoppingMode: 00h = baseband hopping
137 cellType: 00h = Standard Cell
138 BCCH ARFCN / bCCHFrequency: 1
139*/
140
141unsigned char msg_2[] =
142{
143 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
Harald Welte0bbb8b22009-02-06 12:49:11 +0000144 0x01, 0x0C, 0x32, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
Harald Welte52b1f982008-12-23 20:25:15 +0000145 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
146 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
147 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
148 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
149 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
150};
151
152// Handover Recognition, SET ATTRIBUTES
153
154/*
155Illegal Contents GSM Formatted O&M Msg
156 Object Class: Handover Recognition
157 BTS relat. Number: 0
158 Instance 2: FF
159 Instance 3: FF
160SET ATTRIBUTES
161 enableDelayPowerBudgetHO: 00h = Disabled
162 enableDistanceHO: 00h = Disabled
163 enableInternalInterCellHandover: 00h = Disabled
164 enableInternalIntraCellHandover: 00h = Disabled
165 enablePowerBudgetHO: 00h = Disabled
166 enableRXLEVHO: 00h = Disabled
167 enableRXQUALHO: 00h = Disabled
168 hoAveragingDistance: 8 SACCH multiframes
169 hoAveragingLev:
170 A_LEV_HO: 8 SACCH multiframes
171 W_LEV_HO: 1 SACCH multiframes
172 hoAveragingPowerBudget: 16 SACCH multiframes
173 hoAveragingQual:
174 A_QUAL_HO: 8 SACCH multiframes
175 W_QUAL_HO: 2 SACCH multiframes
176 hoLowerThresholdLevDL: (10 - 110) dBm
177 hoLowerThresholdLevUL: (5 - 110) dBm
178 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
179 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
180 hoThresholdLevDLintra : (20 - 110) dBm
181 hoThresholdLevULintra: (20 - 110) dBm
182 hoThresholdMsRangeMax: 20 km
183 nCell: 06h
184 timerHORequest: 3 ,unit 2 SACCH multiframes
185*/
186
187unsigned char msg_3[] =
188{
189 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
190 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
191 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
192 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
193 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
194 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
195 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
196 0x20, 0xF7, 0x01, 0x3C,
197};
198
199// Power Control, SET ATTRIBUTES
200
201/*
202 Object Class: Power Control
203 BTS relat. Number: 0
204 Instance 2: FF
205 Instance 3: FF
206SET ATTRIBUTES
207 enableMsPowerControl: 00h = Disabled
208 enablePowerControlRLFW: 00h = Disabled
209 pcAveragingLev:
210 A_LEV_PC: 4 SACCH multiframes
211 W_LEV_PC: 1 SACCH multiframes
212 pcAveragingQual:
213 A_QUAL_PC: 4 SACCH multiframes
214 W_QUAL_PC: 2 SACCH multiframes
215 pcLowerThresholdLevDL: 0Fh
216 pcLowerThresholdLevUL: 0Ah
217 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
218 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
219 pcRLFThreshold: 0Ch
220 pcUpperThresholdLevDL: 14h
221 pcUpperThresholdLevUL: 0Fh
222 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
223 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
224 powerConfirm: 2 ,unit 2 SACCH multiframes
225 powerControlInterval: 2 ,unit 2 SACCH multiframes
226 powerIncrStepSize: 02h = 4 dB
227 powerRedStepSize: 01h = 2 dB
228 radioLinkTimeoutBs: 64 SACCH multiframes
229 enableBSPowerControl: 00h = disabled
230*/
231
232unsigned char msg_4[] =
233{
234 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
235 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
236 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
237 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
238};
239
240
241// Transceiver, SET TRX ATTRIBUTES (TRX 0)
242
243/*
244 Object Class: Transceiver
245 BTS relat. Number: 0
246 Tranceiver number: 0
247 Instance 3: FF
248SET TRX ATTRIBUTES
249 aRFCNList (HEX): 0001
250 txPwrMaxReduction: 00h = 0dB
251 radioMeasGran: 254 SACCH multiframes
252 radioMeasRep: 01h = enabled
253 memberOfEmergencyConfig: 01h = TRUE
254 trxArea: 00h = TRX doesn't belong to a concentric cell
255*/
256
257unsigned char msg_6[] =
258{
259 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
260 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
261};
262
263
264static void bootstrap_om(struct gsm_bts *bts)
265{
266 struct gsm_bts_trx *trx = &bts->trx[0];
267
Harald Weltead384642008-12-26 10:20:07 +0000268 fprintf(stdout, "bootstrapping OML\n");
269
Harald Welte52b1f982008-12-23 20:25:15 +0000270 /* stop sending event reports */
271 abis_nm_event_reports(bts, 0);
272
273 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000274 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte52b1f982008-12-23 20:25:15 +0000275
Harald Welte702d8702008-12-26 20:25:35 +0000276 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000277 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte702d8702008-12-26 20:25:35 +0000278
279 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000280 abis_nm_bs11_reset_resource(bts);
Harald Welte702d8702008-12-26 20:25:35 +0000281
282 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000283 abis_nm_bs11_db_transmission(bts, 1);
Harald Welte702d8702008-12-26 20:25:35 +0000284
Harald Welte52b1f982008-12-23 20:25:15 +0000285 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
286 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
287 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
288 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
289
290 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
291 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
292 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
293
294 /* Use TEI 1 for signalling */
295 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
296 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
297#if 0
298 /* TRX 1 */
299 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
300 /* FIXME: TRX ATTRIBUTE */
301 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
302#endif
303
304 /* SET CHANNEL ATTRIBUTE TS1 */
305 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
306 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
307 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
308
309 /* SET CHANNEL ATTRIBUTE TS2 */
310 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
311 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
312 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
313
314 /* SET CHANNEL ATTRIBUTE TS3 */
315 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
316 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
317 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
318
319 /* SET CHANNEL ATTRIBUTE TS4 */
320 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
321 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
322 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
323
324 /* SET CHANNEL ATTRIBUTE TS5 */
325 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
326 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
327 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
328
329 /* SET CHANNEL ATTRIBUTE TS6 */
330 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
331 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
332 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
333
334 /* SET CHANNEL ATTRIBUTE TS7 */
335 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
336 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
337 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
338
339 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000340 abis_nm_bs11_db_transmission(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000341
342 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000343 abis_nm_bs11_reset_resource(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000344
345 /* restart sending event reports */
346 abis_nm_event_reports(bts, 1);
347}
348
Harald Welted1252502009-01-01 01:50:32 +0000349static int shutdown_om(struct gsm_bts *bts)
350{
351 /* stop sending event reports */
352 abis_nm_event_reports(bts, 0);
Harald Welte52b1f982008-12-23 20:25:15 +0000353
Harald Welted1252502009-01-01 01:50:32 +0000354 /* begin DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000355 abis_nm_bs11_db_transmission(bts, 1);
Harald Welted1252502009-01-01 01:50:32 +0000356
357 /* end DB transmission */
Harald Welte05188ee2009-01-18 11:39:08 +0000358 abis_nm_bs11_db_transmission(bts, 0);
Harald Welted1252502009-01-01 01:50:32 +0000359
360 /* Reset BTS Site manager resource */
Harald Welte78374892009-01-18 19:09:22 +0000361 abis_nm_bs11_reset_resource(bts);
Harald Welted1252502009-01-01 01:50:32 +0000362
363 return 0;
364}
365
366static int shutdown_net(struct gsm_network *net)
367{
368 int i;
369 for (i = 0; i < net->num_bts; i++) {
370 int rc;
371 rc = shutdown_om(&net->bts[i]);
372 if (rc < 0)
373 return rc;
374 }
375
376 return 0;
377}
Harald Welte52b1f982008-12-23 20:25:15 +0000378
379struct bcch_info {
380 u_int8_t type;
381 u_int8_t len;
382 const u_int8_t *data;
383};
384
385/*
386SYSTEM INFORMATION TYPE 1
387 Cell channel description
388 Format-ID bit map 0
389 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
390 RACH Control Parameters
391 maximum 7 retransmissions
392 8 slots used to spread transmission
393 cell not barred for access
394 call reestablishment not allowed
395 Access Control Class = 0000
396*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000397static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000398 /* header */0x55, 0x06, 0x19,
399 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
401 /* rach */0xD5, 0x00, 0x00,
402 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000403};
404
405/*
406 SYSTEM INFORMATION TYPE 2
407 Neighbour Cells Description
408 EXT-IND: Carries the complete BA
409 BA-IND = 0
410 Format-ID bit map 0
411 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
412 NCC permitted (NCC) = FF
413 RACH Control Parameters
414 maximum 7 retransmissions
415 8 slots used to spread transmission
416 cell not barred for access
417 call reestablishment not allowed
418 Access Control Class = 0000
419*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000420static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000421 /* header */0x59, 0x06, 0x1A,
422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 /* ncc */0xFF,
425 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000426};
427
428/*
429SYSTEM INFORMATION TYPE 3
430 Cell identity = 00001 (1h)
431 Location area identification
432 Mobile Country Code (MCC): 001
433 Mobile Network Code (MNC): 01
434 Location Area Code (LAC): 00001 (1h)
435 Control Channel Description
436 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
437 0 blocks reserved for access grant
438 1 channel used for CCCH, with SDCCH
439 5 multiframes period for PAGING REQUEST
440 Time-out T3212 = 0
441 Cell Options BCCH
442 Power control indicator: not set
443 MSs shall not use uplink DTX
444 Radio link timeout = 36
445 Cell Selection Parameters
446 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000447 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000448 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
449 Half rate support (NECI): New establishment causes are not supported
450 min.RX signal level for MS = 0
451 RACH Control Parameters
452 maximum 7 retransmissions
453 8 slots used to spread transmission
454 cell not barred for access
455 call reestablishment not allowed
456 Access Control Class = 0000
457 SI 3 Rest Octets
458 Cell Bar Qualify (CBQ): 0
459 Cell Reselect Offset = 0 dB
460 Temporary Offset = 0 dB
461 Penalty Time = 20 s
462 System Information 2ter Indicator (2TI): 0 = not available
463 Early Classmark Sending Control (ECSC): 0 = forbidden
464 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
465*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000466static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000467 /* header */0x49, 0x06, 0x1B,
468 /* cell */0x00, 0x01,
469 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
470 /* desc */0x01, 0x03, 0x00,
471 /* option*/0x28,
472 /* selection*/0x62, 0x00,
473 /* rach */0xD5, 0x00, 0x00,
474 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000475};
476
477/*
478SYSTEM INFORMATION TYPE 4
479 Location area identification
480 Mobile Country Code (MCC): 001
481 Mobile Network Code (MNC): 01
482 Location Area Code (LAC): 00001 (1h)
483 Cell Selection Parameters
484 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
485 max.TX power level MS may use for CCH = 2
486 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
487 Half rate support (NECI): New establishment causes are not supported
488 min.RX signal level for MS = 0
489 RACH Control Parameters
490 maximum 7 retransmissions
491 8 slots used to spread transmission
492 cell not barred for access
493 call reestablishment not allowed
494 Access Control Class = 0000
495 Channel Description
496 Type = SDCCH/4[2]
497 Timeslot Number: 0
498 Training Sequence Code: 7h
499 ARFCN: 1
500 SI Rest Octets
501 Cell Bar Qualify (CBQ): 0
502 Cell Reselect Offset = 0 dB
503 Temporary Offset = 0 dB
504 Penalty Time = 20 s
505*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000506static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000507 /* header */0x41, 0x06, 0x1C,
508 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
509 /* sel */0x62, 0x00,
510 /* rach*/0xD5, 0x00, 0x00,
511 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000512 0x2B, 0x2B, 0x2B
513};
514
515/*
516 SYSTEM INFORMATION TYPE 5
517 Neighbour Cells Description
518 EXT-IND: Carries the complete BA
519 BA-IND = 0
520 Format-ID bit map 0
521 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
522*/
523
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000524static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000525 /* header without l2 len*/0x06, 0x1D,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000528};
529
530// SYSTEM INFORMATION TYPE 6
531
532/*
533SACCH FILLING
534 System Info Type: SYSTEM INFORMATION 6
535 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
536
537SYSTEM INFORMATION TYPE 6
538 Cell identity = 00001 (1h)
539 Location area identification
540 Mobile Country Code (MCC): 001
541 Mobile Network Code (MNC): 01
542 Location Area Code (LAC): 00001 (1h)
543 Cell Options SACCH
544 Power control indicator: not set
545 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
546 Radio link timeout = 36
547 NCC permitted (NCC) = FF
548*/
549
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000550static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000551 /* header */0x06, 0x1E,
552 /* cell id*/ 0x00, 0x01,
553 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
554 /* options */ 0x28,
555 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000556};
557
558
559
560static const struct bcch_info bcch_infos[] = {
561 {
562 .type = RSL_SYSTEM_INFO_1,
563 .len = sizeof(si1),
564 .data = si1,
565 }, {
566 .type = RSL_SYSTEM_INFO_2,
567 .len = sizeof(si2),
568 .data = si2,
569 }, {
570 .type = RSL_SYSTEM_INFO_3,
571 .len = sizeof(si3),
572 .data = si3,
573 }, {
574 .type = RSL_SYSTEM_INFO_4,
575 .len = sizeof(si4),
576 .data = si4,
577 },
578};
579
Holger Freyther24287b62008-12-28 16:32:41 +0000580static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
581static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
582static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
583static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000584static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
585static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000586
Harald Welte52b1f982008-12-23 20:25:15 +0000587/* set all system information types */
Harald Weltee79769b2009-02-07 00:48:17 +0000588static int set_system_infos(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000589{
590 int i;
591
592 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
Harald Weltee79769b2009-02-07 00:48:17 +0000593 rsl_bcch_info(trx, bcch_infos[i].type,
Harald Welte52b1f982008-12-23 20:25:15 +0000594 bcch_infos[i].data,
595 bcch_infos[i].len);
596 }
Harald Weltee79769b2009-02-07 00:48:17 +0000597 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
598 rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000599
600 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000601}
602
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000603/*
Harald Welte38c2f132009-01-06 23:10:57 +0000604 * Inform anyone...
605 */
606static void bsc_hack_channel_allocated(struct gsm_lchan *lchan) {
607}
608
609/*
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000610 * Patch the various SYSTEM INFORMATION tables to update
611 * the LAI
612 */
613static void patch_tables(struct gsm_bts *bts)
614{
Harald Welte98981882009-01-06 18:59:11 +0000615 u_int8_t arfcn_low = ARFCN & 0xff;
616 u_int8_t arfcn_high = (ARFCN >> 8) & 0x0f;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000617 /* covert the raw packet to the struct */
618 struct gsm48_system_information_type_3 *type_3 =
619 (struct gsm48_system_information_type_3*)&si3;
620 struct gsm48_system_information_type_4 *type_4 =
621 (struct gsm48_system_information_type_4*)&si4;
622 struct gsm48_system_information_type_6 *type_6 =
623 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000624 struct gsm48_loc_area_id lai;
625
626 gsm0408_generate_lai(&lai, bts->network->country_code,
627 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000628
629 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000630 type_3->lai = lai;
631 type_4->lai = lai;
632 type_6->lai = lai;
Harald Welte98981882009-01-06 18:59:11 +0000633
634 /* patch ARFCN */
635 msg_2[74] &= 0xf0;
636 msg_2[74] |= arfcn_high;
637 msg_2[75] = arfcn_low;
638
639 msg_6[7] &= 0xf0;
640 msg_6[7] |= arfcn_high;
641 msg_6[8] = arfcn_low;
642
643 type_4->data[2] &= 0xf0;
644 type_4->data[2] |= arfcn_high;
645 type_4->data[3] = arfcn_low;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000646
647 /* patch Control Channel Description 10.5.2.11 */
648 type_3->control_channel_desc = bts->chan_desc;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000649}
650
651
Harald Weltee79769b2009-02-07 00:48:17 +0000652static void bootstrap_rsl(struct gsm_bts_trx *trx)
Harald Welte52b1f982008-12-23 20:25:15 +0000653{
Harald Welteb84e2f42008-12-28 23:42:04 +0000654 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Harald Weltee79769b2009-02-07 00:48:17 +0000655 set_system_infos(trx);
Harald Welte52b1f982008-12-23 20:25:15 +0000656}
657
Harald Welte1fa60c82009-02-09 18:13:26 +0000658void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
Harald Weltead384642008-12-26 10:20:07 +0000659{
660 switch (event) {
Harald Welte1fa60c82009-02-09 18:13:26 +0000661 case EVT_E1_TEI_UP:
662 switch (type) {
663 case E1INP_SIGN_OML:
664 bootstrap_om(trx->bts);
665 break;
666 case E1INP_SIGN_RSL:
667 bootstrap_rsl(trx);
668 break;
669 default:
670 break;
671 }
Harald Weltead384642008-12-26 10:20:07 +0000672 break;
Harald Welte1fa60c82009-02-09 18:13:26 +0000673 case EVT_E1_TEI_DN:
674 fprintf(stderr, "Lost some E1 TEI link\n");
675 /* FIXME: deal with TEI or L1 link loss */
Harald Weltead384642008-12-26 10:20:07 +0000676 break;
677 default:
Harald Weltead384642008-12-26 10:20:07 +0000678 break;
679 }
680}
681
682static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000683{
684 struct gsm_bts *bts;
685
686 /* initialize our data structures */
Holger Freytherefde7fb2008-12-28 14:14:56 +0000687 gsmnet = gsm_network_init(1, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000688 if (!gsmnet)
689 return -ENOMEM;
Harald Weltef5cbab72008-12-30 18:00:15 +0000690
691 gsmnet->name_short = "25C3";
692 gsmnet->name_long = "25C3 GSM";
Harald Welte52b1f982008-12-23 20:25:15 +0000693 bts = &gsmnet->bts[0];
694 bts->location_area_code = 1;
Harald Welte98981882009-01-06 18:59:11 +0000695 bts->trx[0].arfcn = ARFCN;
Holger Freyther1adb4ff2009-02-04 00:04:52 +0000696
697 /* Control Channel Description */
698 memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
699 bts->chan_desc.att = 0;
700 bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
701 bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
702 bts->chan_desc.t3212 = 0;
703
Harald Welte98981882009-01-06 18:59:11 +0000704 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000705
Holger Freyther1fd34142009-02-09 23:42:03 +0000706 paging_init(bts);
Holger Freytherceb59b72009-02-06 18:54:00 +0000707 bts->paging.channel_allocated = bsc_hack_channel_allocated;
Harald Welte38c2f132009-01-06 23:10:57 +0000708
Holger Freyther219518d2009-01-02 22:04:43 +0000709 telnet_init(gsmnet, 4242);
Harald Weltead384642008-12-26 10:20:07 +0000710
Harald Welte1fa60c82009-02-09 18:13:26 +0000711 /* E1 mISDN input setup */
712 return e1_config(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000713}
Harald Weltef6b7a902008-12-26 00:05:11 +0000714
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000715static void create_pcap_file(char *file)
716{
Harald Welte1fa60c82009-02-09 18:13:26 +0000717#if 0
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000718 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
719 int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
720
721 if (fd < 0) {
722 perror("Failed to open file for pcap");
723 return;
724 }
725
726 mi_set_pcap_fd(fd);
Harald Welte1fa60c82009-02-09 18:13:26 +0000727#else
728 fprintf(stderr, "PCAP support currently disabled!!\n");
729#endif
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000730}
731
Holger Freytherb332f612008-12-27 12:46:51 +0000732static void print_usage()
733{
734 printf("Usage: bsc_hack\n");
735}
736
737static void print_help()
738{
739 printf(" Some useful help...\n");
740 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000741 printf(" -s --disable-color\n");
742 printf(" -n --network-code number(MNC) \n");
743 printf(" -c --country-code number (MCC) \n");
Harald Welte98981882009-01-06 18:59:11 +0000744 printf(" -f --arfcn number The frequency ARFCN\n");
Holger Freytherbde36102008-12-28 22:51:39 +0000745 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +0000746 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freythere97f7fb2008-12-31 18:52:11 +0000747 printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n");
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000748 printf(" -p --pcap file The filename of the pcap file\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000749 printf(" -h --help this text\n");
750}
751
752static void handle_options(int argc, char** argv)
753{
754 while (1) {
755 int option_index = 0, c;
756 static struct option long_options[] = {
757 {"help", 0, 0, 'h'},
758 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000759 {"disable-color", 0, 0, 's'},
760 {"network-code", 1, 0, 'n'},
761 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000762 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +0000763 {"authorize-everyone", 0, 0, 'a'},
Holger Freythere97f7fb2008-12-31 18:52:11 +0000764 {"reject-cause", 1, 0, 'r'},
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000765 {"pcap", 1, 0, 'p'},
Harald Welte98981882009-01-06 18:59:11 +0000766 {"arfcn", 1, 0, 'f'},
Holger Freytherb332f612008-12-27 12:46:51 +0000767 {0, 0, 0, 0}
768 };
769
Harald Welte98981882009-01-06 18:59:11 +0000770 c = getopt_long(argc, argv, "hc:n:d:sar:p:f:",
Holger Freytherb332f612008-12-27 12:46:51 +0000771 long_options, &option_index);
772 if (c == -1)
773 break;
774
775 switch (c) {
776 case 'h':
777 print_usage();
778 print_help();
779 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000780 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000781 debug_use_color(0);
782 break;
783 case 'd':
784 debug_parse_category_mask(optarg);
785 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000786 case 'n':
787 MNC = atoi(optarg);
788 break;
789 case 'c':
790 MCC = atoi(optarg);
791 break;
Harald Welte98981882009-01-06 18:59:11 +0000792 case 'f':
793 ARFCN = atoi(optarg);
794 break;
Harald Welte8965da42009-01-06 18:09:02 +0000795 case 'l':
Holger Freytherbde36102008-12-28 22:51:39 +0000796 database_name = strdup(optarg);
797 break;
Holger Freyther89824fc2008-12-30 16:18:18 +0000798 case 'a':
799 gsm0408_allow_everyone(1);
800 break;
Holger Freythere97f7fb2008-12-31 18:52:11 +0000801 case 'r':
802 gsm0408_set_reject_cause(atoi(optarg));
803 break;
Holger Freyther9a3ee0f2009-01-02 00:40:15 +0000804 case 'p':
805 create_pcap_file(optarg);
806 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000807 default:
808 /* ignore */
809 break;
810 }
811 }
812}
813
Harald Welted1252502009-01-01 01:50:32 +0000814static void signal_handler(int signal)
815{
816 fprintf(stdout, "signal %u received\n", signal);
817
818 switch (signal) {
819 case SIGHUP:
820 case SIGABRT:
821 shutdown_net(gsmnet);
822 break;
823 default:
824 break;
825 }
826}
827
Harald Weltef6b7a902008-12-26 00:05:11 +0000828int main(int argc, char **argv)
829{
Harald Welte1fa60c82009-02-09 18:13:26 +0000830 int rc;
831
Holger Freytherb332f612008-12-27 12:46:51 +0000832 /* parse options */
833 handle_options(argc, argv);
834
Holger Freytherbde36102008-12-28 22:51:39 +0000835 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +0000836 printf("DB: Failed to init database. Please check the option settings.\n");
837 return 1;
838 }
839 printf("DB: Database initialized.\n");
840
841 if (db_prepare()) {
842 printf("DB: Failed to prepare database.\n");
843 return 1;
844 }
845 printf("DB: Database prepared.\n");
846
Harald Welte1fa60c82009-02-09 18:13:26 +0000847 rc = bootstrap_network();
848 if (rc < 0)
849 exit(1);
Harald Weltef6b7a902008-12-26 00:05:11 +0000850
Harald Welted1252502009-01-01 01:50:32 +0000851 signal(SIGHUP, &signal_handler);
852 signal(SIGABRT, &signal_handler);
853
Harald Weltef6b7a902008-12-26 00:05:11 +0000854 while (1) {
855 bsc_select_main();
856 }
857}