blob: 1cf0731f45d28a6ce3a064f78bae394be44bb0a0 [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>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
Harald Weltef6b7a902008-12-26 00:05:11 +000022#include <unistd.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <stdarg.h>
26#include <time.h>
27#include <string.h>
Harald Weltead384642008-12-26 10:20:07 +000028#include <errno.h>
Harald Welte52b1f982008-12-23 20:25:15 +000029
Holger Freytherb332f612008-12-27 12:46:51 +000030#define _GNU_SOURCE
31#include <getopt.h>
32
Harald Welte255539c2008-12-28 02:26:27 +000033#include <openbsc/db.h>
34#include <openbsc/timer.h>
Harald Welte8470bf22008-12-25 23:28:35 +000035#include <openbsc/gsm_data.h>
Harald Welte255539c2008-12-28 02:26:27 +000036#include <openbsc/gsm_04_08.h>
Harald Weltead384642008-12-26 10:20:07 +000037#include <openbsc/select.h>
Harald Welte8470bf22008-12-25 23:28:35 +000038#include <openbsc/abis_rsl.h>
39#include <openbsc/abis_nm.h>
Harald Welte702d8702008-12-26 20:25:35 +000040#include <openbsc/debug.h>
Holger Freyther5677ae32008-12-27 09:41:03 +000041#include <openbsc/misdn.h>
Harald Welte52b1f982008-12-23 20:25:15 +000042
43/* global pointer to the gsm network data structure */
44static struct gsm_network *gsmnet;
45
Holger Freytherefde7fb2008-12-28 14:14:56 +000046/* MCC and MNC for the Location Area Identifier */
47static int MCC = 1;
48static int MNC = 1;
Holger Freytherbde36102008-12-28 22:51:39 +000049static const char *database_name = "hlr.sqlite3";
Holger Freytherefde7fb2008-12-28 14:14:56 +000050
Holger Freyther07cc8d82008-12-29 06:23:46 +000051/* forward declarations */
52static void bsc_hack_update_request_accepted(struct gsm_bts *bts, u_int32_t assigned_tmi);
Holger Freyther3186bf22008-12-29 06:23:49 +000053static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
54 enum gsm_chreq_reason_t reason);
Holger Freyther07cc8d82008-12-29 06:23:46 +000055
Holger Freytherefde7fb2008-12-28 14:14:56 +000056
Harald Welte52b1f982008-12-23 20:25:15 +000057/* The following definitions are for OM and NM packets that we cannot yet
58 * generate by code but we just pass on */
59
60// BTS Site Manager, SET ATTRIBUTES
61
62/*
63 Object Class: BTS Site Manager
64 Instance 1: FF
65 Instance 2: FF
66 Instance 3: FF
67SET ATTRIBUTES
68 sAbisExternalTime: 2007/09/08 14:36:11
69 omLAPDRelTimer: 30sec
70 shortLAPDIntTimer: 5sec
71 emergencyTimer1: 10 minutes
72 emergencyTimer2: 0 minutes
73*/
74
75unsigned char msg_1[] =
76{
77 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
78 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
79 0x02, 0x00, 0x00
80};
81
82// BTS, SET BTS ATTRIBUTES
83
84/*
85 Object Class: BTS
86 BTS relat. Number: 0
87 Instance 2: FF
88 Instance 3: FF
89SET BTS ATTRIBUTES
90 bsIdentityCode / BSIC:
91 PLMN_colour_code: 7h
92 BS_colour_code: 7h
93 BTS Air Timer T3105: 4 ,unit 10 ms
94 btsIsHopping: FALSE
95 periodCCCHLoadIndication: 255sec
96 thresholdCCCHLoadIndication: 100%
97 cellAllocationNumber: 00h = GSM 900
98 enableInterferenceClass: 00h = Disabled
99 fACCHQual: 6 (FACCH stealing flags minus 1)
100 intaveParameter: 31 SACCH multiframes
101 interferenceLevelBoundaries:
102 Interference Boundary 1: 0Ah
103 Interference Boundary 2: 0Fh
104 Interference Boundary 3: 14h
105 Interference Boundary 4: 19h
106 Interference Boundary 5: 1Eh
107 mSTxPwrMax: 11
108 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
109 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
110 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
111 30=33dBm, 31=32dBm
112 ny1:
113 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
114 powerOutputThresholds:
115 Out Power Fault Threshold: -10 dB
116 Red Out Power Threshold: - 6 dB
117 Excessive Out Power Threshold: 5 dB
118 rACHBusyThreshold: -127 dBm
119 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
120 rfResourceIndicationPeriod: 125 SACCH multiframes
121 T200:
122 SDCCH: 044 in 5 ms
123 FACCH/Full rate: 031 in 5 ms
124 FACCH/Half rate: 041 in 5 ms
125 SACCH with TCH SAPI0: 090 in 10 ms
126 SACCH with SDCCH: 090 in 10 ms
127 SDCCH with SAPI3: 090 in 5 ms
128 SACCH with TCH SAPI3: 135 in 10 ms
129 tSync: 9000 units of 10 msec
130 tTrau: 9000 units of 10 msec
131 enableUmLoopTest: 00h = disabled
132 enableExcessiveDistance: 00h = Disabled
133 excessiveDistance: 64km
134 hoppingMode: 00h = baseband hopping
135 cellType: 00h = Standard Cell
136 BCCH ARFCN / bCCHFrequency: 1
137*/
138
139unsigned char msg_2[] =
140{
141 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
142 0xFF, 0x0C, 0x64, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
143 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
144 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
145 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
146 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
147 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
148};
149
150// Handover Recognition, SET ATTRIBUTES
151
152/*
153Illegal Contents GSM Formatted O&M Msg
154 Object Class: Handover Recognition
155 BTS relat. Number: 0
156 Instance 2: FF
157 Instance 3: FF
158SET ATTRIBUTES
159 enableDelayPowerBudgetHO: 00h = Disabled
160 enableDistanceHO: 00h = Disabled
161 enableInternalInterCellHandover: 00h = Disabled
162 enableInternalIntraCellHandover: 00h = Disabled
163 enablePowerBudgetHO: 00h = Disabled
164 enableRXLEVHO: 00h = Disabled
165 enableRXQUALHO: 00h = Disabled
166 hoAveragingDistance: 8 SACCH multiframes
167 hoAveragingLev:
168 A_LEV_HO: 8 SACCH multiframes
169 W_LEV_HO: 1 SACCH multiframes
170 hoAveragingPowerBudget: 16 SACCH multiframes
171 hoAveragingQual:
172 A_QUAL_HO: 8 SACCH multiframes
173 W_QUAL_HO: 2 SACCH multiframes
174 hoLowerThresholdLevDL: (10 - 110) dBm
175 hoLowerThresholdLevUL: (5 - 110) dBm
176 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
177 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
178 hoThresholdLevDLintra : (20 - 110) dBm
179 hoThresholdLevULintra: (20 - 110) dBm
180 hoThresholdMsRangeMax: 20 km
181 nCell: 06h
182 timerHORequest: 3 ,unit 2 SACCH multiframes
183*/
184
185unsigned char msg_3[] =
186{
187 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
188 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
189 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
190 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
191 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
192 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
193 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
194 0x20, 0xF7, 0x01, 0x3C,
195};
196
197// Power Control, SET ATTRIBUTES
198
199/*
200 Object Class: Power Control
201 BTS relat. Number: 0
202 Instance 2: FF
203 Instance 3: FF
204SET ATTRIBUTES
205 enableMsPowerControl: 00h = Disabled
206 enablePowerControlRLFW: 00h = Disabled
207 pcAveragingLev:
208 A_LEV_PC: 4 SACCH multiframes
209 W_LEV_PC: 1 SACCH multiframes
210 pcAveragingQual:
211 A_QUAL_PC: 4 SACCH multiframes
212 W_QUAL_PC: 2 SACCH multiframes
213 pcLowerThresholdLevDL: 0Fh
214 pcLowerThresholdLevUL: 0Ah
215 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
216 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
217 pcRLFThreshold: 0Ch
218 pcUpperThresholdLevDL: 14h
219 pcUpperThresholdLevUL: 0Fh
220 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
221 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
222 powerConfirm: 2 ,unit 2 SACCH multiframes
223 powerControlInterval: 2 ,unit 2 SACCH multiframes
224 powerIncrStepSize: 02h = 4 dB
225 powerRedStepSize: 01h = 2 dB
226 radioLinkTimeoutBs: 64 SACCH multiframes
227 enableBSPowerControl: 00h = disabled
228*/
229
230unsigned char msg_4[] =
231{
232 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
233 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
234 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
235 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
236};
237
238
239// Transceiver, SET TRX ATTRIBUTES (TRX 0)
240
241/*
242 Object Class: Transceiver
243 BTS relat. Number: 0
244 Tranceiver number: 0
245 Instance 3: FF
246SET TRX ATTRIBUTES
247 aRFCNList (HEX): 0001
248 txPwrMaxReduction: 00h = 0dB
249 radioMeasGran: 254 SACCH multiframes
250 radioMeasRep: 01h = enabled
251 memberOfEmergencyConfig: 01h = TRUE
252 trxArea: 00h = TRX doesn't belong to a concentric cell
253*/
254
255unsigned char msg_6[] =
256{
257 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
258 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
259};
260
261
262static void bootstrap_om(struct gsm_bts *bts)
263{
264 struct gsm_bts_trx *trx = &bts->trx[0];
265
Harald Weltead384642008-12-26 10:20:07 +0000266 fprintf(stdout, "bootstrapping OML\n");
267
Harald Welte52b1f982008-12-23 20:25:15 +0000268 /* stop sending event reports */
269 abis_nm_event_reports(bts, 0);
270
271 /* begin DB transmission */
272 abis_nm_db_transmission(bts, 1);
273
Harald Welte702d8702008-12-26 20:25:35 +0000274 /* end DB transmission */
275 abis_nm_db_transmission(bts, 0);
276
277 /* Reset BTS Site manager resource */
278 abis_nm_reset_resource(bts);
279
280 /* begin DB transmission */
281 abis_nm_db_transmission(bts, 1);
282
Harald Welte52b1f982008-12-23 20:25:15 +0000283 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
284 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
285 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
286 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
287
288 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
289 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
290 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
291
292 /* Use TEI 1 for signalling */
293 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
294 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
295#if 0
296 /* TRX 1 */
297 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
298 /* FIXME: TRX ATTRIBUTE */
299 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
300#endif
301
302 /* SET CHANNEL ATTRIBUTE TS1 */
303 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
304 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
305 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
306
307 /* SET CHANNEL ATTRIBUTE TS2 */
308 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
309 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
310 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
311
312 /* SET CHANNEL ATTRIBUTE TS3 */
313 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
314 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
315 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
316
317 /* SET CHANNEL ATTRIBUTE TS4 */
318 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
319 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
320 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
321
322 /* SET CHANNEL ATTRIBUTE TS5 */
323 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
324 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
325 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
326
327 /* SET CHANNEL ATTRIBUTE TS6 */
328 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
329 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
330 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
331
332 /* SET CHANNEL ATTRIBUTE TS7 */
333 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
334 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
335 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
336
337 /* end DB transmission */
338 abis_nm_db_transmission(bts, 0);
339
340 /* Reset BTS Site manager resource */
341 abis_nm_reset_resource(bts);
342
343 /* restart sending event reports */
344 abis_nm_event_reports(bts, 1);
345}
346
347
348
349struct bcch_info {
350 u_int8_t type;
351 u_int8_t len;
352 const u_int8_t *data;
353};
354
355/*
356SYSTEM INFORMATION TYPE 1
357 Cell channel description
358 Format-ID bit map 0
359 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
360 RACH Control Parameters
361 maximum 7 retransmissions
362 8 slots used to spread transmission
363 cell not barred for access
364 call reestablishment not allowed
365 Access Control Class = 0000
366*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000367static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000368 /* header */0x55, 0x06, 0x19,
369 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
371 /* rach */0xD5, 0x00, 0x00,
372 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000373};
374
375/*
376 SYSTEM INFORMATION TYPE 2
377 Neighbour Cells Description
378 EXT-IND: Carries the complete BA
379 BA-IND = 0
380 Format-ID bit map 0
381 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
382 NCC permitted (NCC) = FF
383 RACH Control Parameters
384 maximum 7 retransmissions
385 8 slots used to spread transmission
386 cell not barred for access
387 call reestablishment not allowed
388 Access Control Class = 0000
389*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000390static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000391 /* header */0x59, 0x06, 0x1A,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 /* ncc */0xFF,
395 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000396};
397
398/*
399SYSTEM INFORMATION TYPE 3
400 Cell identity = 00001 (1h)
401 Location area identification
402 Mobile Country Code (MCC): 001
403 Mobile Network Code (MNC): 01
404 Location Area Code (LAC): 00001 (1h)
405 Control Channel Description
406 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
407 0 blocks reserved for access grant
408 1 channel used for CCCH, with SDCCH
409 5 multiframes period for PAGING REQUEST
410 Time-out T3212 = 0
411 Cell Options BCCH
412 Power control indicator: not set
413 MSs shall not use uplink DTX
414 Radio link timeout = 36
415 Cell Selection Parameters
416 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000417 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000418 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
419 Half rate support (NECI): New establishment causes are not supported
420 min.RX signal level for MS = 0
421 RACH Control Parameters
422 maximum 7 retransmissions
423 8 slots used to spread transmission
424 cell not barred for access
425 call reestablishment not allowed
426 Access Control Class = 0000
427 SI 3 Rest Octets
428 Cell Bar Qualify (CBQ): 0
429 Cell Reselect Offset = 0 dB
430 Temporary Offset = 0 dB
431 Penalty Time = 20 s
432 System Information 2ter Indicator (2TI): 0 = not available
433 Early Classmark Sending Control (ECSC): 0 = forbidden
434 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
435*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000436static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000437 /* header */0x49, 0x06, 0x1B,
438 /* cell */0x00, 0x01,
439 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
440 /* desc */0x01, 0x03, 0x00,
441 /* option*/0x28,
442 /* selection*/0x62, 0x00,
443 /* rach */0xD5, 0x00, 0x00,
444 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000445};
446
447/*
448SYSTEM INFORMATION TYPE 4
449 Location area identification
450 Mobile Country Code (MCC): 001
451 Mobile Network Code (MNC): 01
452 Location Area Code (LAC): 00001 (1h)
453 Cell Selection Parameters
454 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
455 max.TX power level MS may use for CCH = 2
456 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
457 Half rate support (NECI): New establishment causes are not supported
458 min.RX signal level for MS = 0
459 RACH Control Parameters
460 maximum 7 retransmissions
461 8 slots used to spread transmission
462 cell not barred for access
463 call reestablishment not allowed
464 Access Control Class = 0000
465 Channel Description
466 Type = SDCCH/4[2]
467 Timeslot Number: 0
468 Training Sequence Code: 7h
469 ARFCN: 1
470 SI Rest Octets
471 Cell Bar Qualify (CBQ): 0
472 Cell Reselect Offset = 0 dB
473 Temporary Offset = 0 dB
474 Penalty Time = 20 s
475*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000476static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000477 /* header */0x41, 0x06, 0x1C,
478 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
479 /* sel */0x62, 0x00,
480 /* rach*/0xD5, 0x00, 0x00,
481 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000482 0x2B, 0x2B, 0x2B
483};
484
485/*
486 SYSTEM INFORMATION TYPE 5
487 Neighbour Cells Description
488 EXT-IND: Carries the complete BA
489 BA-IND = 0
490 Format-ID bit map 0
491 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
492*/
493
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000494static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000495 /* header without l2 len*/0x06, 0x1D,
496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000498};
499
500// SYSTEM INFORMATION TYPE 6
501
502/*
503SACCH FILLING
504 System Info Type: SYSTEM INFORMATION 6
505 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
506
507SYSTEM INFORMATION TYPE 6
508 Cell identity = 00001 (1h)
509 Location area identification
510 Mobile Country Code (MCC): 001
511 Mobile Network Code (MNC): 01
512 Location Area Code (LAC): 00001 (1h)
513 Cell Options SACCH
514 Power control indicator: not set
515 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
516 Radio link timeout = 36
517 NCC permitted (NCC) = FF
518*/
519
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000520static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000521 /* header */0x06, 0x1E,
522 /* cell id*/ 0x00, 0x01,
523 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
524 /* options */ 0x28,
525 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000526};
527
528
529
530static const struct bcch_info bcch_infos[] = {
531 {
532 .type = RSL_SYSTEM_INFO_1,
533 .len = sizeof(si1),
534 .data = si1,
535 }, {
536 .type = RSL_SYSTEM_INFO_2,
537 .len = sizeof(si2),
538 .data = si2,
539 }, {
540 .type = RSL_SYSTEM_INFO_3,
541 .len = sizeof(si3),
542 .data = si3,
543 }, {
544 .type = RSL_SYSTEM_INFO_4,
545 .len = sizeof(si4),
546 .data = si4,
547 },
548};
549
Holger Freyther24287b62008-12-28 16:32:41 +0000550static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
551static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
552static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
553static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000554static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
555static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000556
Harald Welte52b1f982008-12-23 20:25:15 +0000557/* set all system information types */
558static int set_system_infos(struct gsm_bts *bts)
559{
560 int i;
561
562 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
563 rsl_bcch_info(bts, bcch_infos[i].type,
564 bcch_infos[i].data,
565 bcch_infos[i].len);
566 }
567 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
568 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000569
570 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000571}
572
573static void activate_traffic_channels(struct gsm_bts_trx *trx)
574{
575 int i;
576
577 /* channel 0 is CCCH */
578 for (i = 1; i < 8; i++)
579 rsl_chan_activate_tch_f(&trx->ts[i]);
580}
581
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000582/*
583 * Patch the various SYSTEM INFORMATION tables to update
584 * the LAI
585 */
586static void patch_tables(struct gsm_bts *bts)
587{
588 /* covert the raw packet to the struct */
589 struct gsm48_system_information_type_3 *type_3 =
590 (struct gsm48_system_information_type_3*)&si3;
591 struct gsm48_system_information_type_4 *type_4 =
592 (struct gsm48_system_information_type_4*)&si4;
593 struct gsm48_system_information_type_6 *type_6 =
594 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000595 struct gsm48_loc_area_id lai;
596
597 gsm0408_generate_lai(&lai, bts->network->country_code,
598 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000599
600 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000601 type_3->lai = lai;
602 type_4->lai = lai;
603 type_6->lai = lai;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000604}
605
606
Harald Weltead384642008-12-26 10:20:07 +0000607static void bootstrap_rsl(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000608{
Harald Welteb84e2f42008-12-28 23:42:04 +0000609 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000610 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000611 set_system_infos(bts);
612
613 /* FIXME: defer this until the channels are used */
Harald Welte702d8702008-12-26 20:25:35 +0000614 //activate_traffic_channels(&bts->trx[0]);
Harald Welte52b1f982008-12-23 20:25:15 +0000615}
616
Harald Weltead384642008-12-26 10:20:07 +0000617static void mi_cb(int event, struct gsm_bts *bts)
618{
619 switch (event) {
620 case EVT_E1_OML_UP:
621 bootstrap_om(bts);
622 break;
623 case EVT_E1_RSL_UP:
624 bootstrap_rsl(bts);
625 break;
626 default:
627 /* FIXME: deal with TEI or L1 link loss */
628 break;
629 }
630}
631
632static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000633{
634 struct gsm_bts *bts;
635
636 /* initialize our data structures */
Holger Freytherefde7fb2008-12-28 14:14:56 +0000637 gsmnet = gsm_network_init(1, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000638 if (!gsmnet)
639 return -ENOMEM;
640
Harald Welte52b1f982008-12-23 20:25:15 +0000641 bts = &gsmnet->bts[0];
642 bts->location_area_code = 1;
643 bts->trx[0].arfcn = HARDCODED_ARFCN;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000644 gsmnet->update_request_accepted = bsc_hack_update_request_accepted;
Holger Freyther3186bf22008-12-29 06:23:49 +0000645 gsmnet->channel_allocated = bsc_hack_channel_allocated;
Harald Welte52b1f982008-12-23 20:25:15 +0000646
Harald Weltead384642008-12-26 10:20:07 +0000647 if (mi_setup(bts, 0, mi_cb) < 0)
648 return -EIO;
649
650 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000651}
Harald Weltef6b7a902008-12-26 00:05:11 +0000652
Holger Freytherb332f612008-12-27 12:46:51 +0000653static void print_usage()
654{
655 printf("Usage: bsc_hack\n");
656}
657
658static void print_help()
659{
660 printf(" Some useful help...\n");
661 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000662 printf(" -s --disable-color\n");
663 printf(" -n --network-code number(MNC) \n");
664 printf(" -c --country-code number (MCC) \n");
Holger Freytherbde36102008-12-28 22:51:39 +0000665 printf(" -l --database db-name The database to use\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000666 printf(" -h --help this text\n");
667}
668
669static void handle_options(int argc, char** argv)
670{
671 while (1) {
672 int option_index = 0, c;
673 static struct option long_options[] = {
674 {"help", 0, 0, 'h'},
675 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000676 {"disable-color", 0, 0, 's'},
677 {"network-code", 1, 0, 'n'},
678 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000679 {"database", 1, 0, 'l'},
Holger Freytherb332f612008-12-27 12:46:51 +0000680 {0, 0, 0, 0}
681 };
682
Holger Freyther33a61842008-12-28 16:57:19 +0000683 c = getopt_long(argc, argv, "hc:n:d:s",
Holger Freytherb332f612008-12-27 12:46:51 +0000684 long_options, &option_index);
685 if (c == -1)
686 break;
687
688 switch (c) {
689 case 'h':
690 print_usage();
691 print_help();
692 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000693 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000694 debug_use_color(0);
695 break;
696 case 'd':
697 debug_parse_category_mask(optarg);
698 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000699 case 'n':
700 MNC = atoi(optarg);
701 break;
702 case 'c':
703 MCC = atoi(optarg);
704 break;
Holger Freytherbde36102008-12-28 22:51:39 +0000705 case 'l':
706 database_name = strdup(optarg);
707 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000708 default:
709 /* ignore */
710 break;
711 }
712 }
713}
714
Harald Welte255539c2008-12-28 02:26:27 +0000715static struct timer_list pag_timer;
716
717/* handles uppercase decimal and hexadecimal */
718static u_int8_t char2bcd(char c)
719{
720 if (c <= '9')
721 return c - '0';
722 else
723 return c - 'A';
724}
725
726static int string_to_mi(u_int8_t *mi, const char *string,
727 u_int8_t type)
728{
729 u_int8_t *cur = mi+3;
730
731 mi[0] = GSM48_IE_MOBILE_ID;
732 //mi[1] = TMSI_LEN;
733 mi[2] = type & GSM_MI_TYPE_MASK;
734
735 if (strlen(string) & 0x01)
736 mi[2] |= char2bcd(*string++) << 4;
737 else
738 mi[2] |= 0xf0;
739
740 while (*string && *(string+1))
741 *cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4);
742
743 mi[1] = cur - mi;
744
745 return cur - mi;
746}
747
Holger Freyther07cc8d82008-12-29 06:23:46 +0000748/*
749 * Stations that registered and that we need to page
750 */
751struct pending_registered_station {
752 struct llist_head entry;
Harald Welte255539c2008-12-28 02:26:27 +0000753
Holger Freyther07cc8d82008-12-29 06:23:46 +0000754 /* the tmsi of the subscriber */
755 u_int32_t tmsi;
756 int last_page_group;
757};
758
759static LLIST_HEAD(pending_stations);
760
761static void pag_timer_cb(void *data);
762static struct timer_list pag_timer = {
763 .cb = pag_timer_cb,
764};
765
766/* page the tmsi and wait for the channel request */
767static void pag_timer_cb(void *data)
Harald Welte255539c2008-12-28 02:26:27 +0000768{
769 struct gsm_bts *bts = &gsmnet->bts[0];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000770 struct pending_registered_station *pending_station;
Harald Welte255539c2008-12-28 02:26:27 +0000771 u_int8_t mi[128];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000772 unsigned int mi_len;
Harald Welte255539c2008-12-28 02:26:27 +0000773
Holger Freyther07cc8d82008-12-29 06:23:46 +0000774 if (llist_empty(&pending_stations)) {
775 DEBUGP(DPAG, "pag_timer_cb but no pending mobile stations\n");
Harald Welte255539c2008-12-28 02:26:27 +0000776 return;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000777 }
Harald Welte255539c2008-12-28 02:26:27 +0000778
Holger Freyther07cc8d82008-12-29 06:23:46 +0000779 /* get the station to page */
780 pending_station = (struct pending_registered_station*) pending_stations.next;
781 mi_len = generate_mid_from_tmsi(mi, pending_station->tmsi);
782 rsl_paging_cmd(bts, pending_station->last_page_group, mi_len, mi, RSL_CHANNEED_TCH_F);
Harald Welte255539c2008-12-28 02:26:27 +0000783
Holger Freyther07cc8d82008-12-29 06:23:46 +0000784 /* which group to page next */
785 pending_station->last_page_group = (pending_station->last_page_group+1) % 12;
786 schedule_timer(&pag_timer, 1, 0);
787}
Harald Welte255539c2008-12-28 02:26:27 +0000788
Holger Freyther07cc8d82008-12-29 06:23:46 +0000789/*
790 * initiate the a page command for the given
791 * station and retry until we get a channel request
792 */
793static void station_timer_cb(void *data)
794{
795 DEBUGP(DPAG, "Initiating paging of a channel\n");
796 pag_timer_cb(0);
797}
Harald Welte255539c2008-12-28 02:26:27 +0000798
Holger Freyther07cc8d82008-12-29 06:23:46 +0000799static struct timer_list station_timer = {
800 .cb = station_timer_cb,
801};
802
803/*
804 * schedule work
805 */
806static void bsc_hack_update_request_accepted(struct gsm_bts *bts, u_int32_t tmsi)
807{
808 struct pending_registered_station *station =
809 (struct pending_registered_station*)malloc(sizeof(*station));
810 station->tmsi = tmsi;
811 station->last_page_group = 0;
812 llist_add_tail(&station->entry, &pending_stations);
813
814 if (!timer_pending(&station_timer))
815 schedule_timer(&station_timer, 1, 0);
Harald Welte255539c2008-12-28 02:26:27 +0000816}
817
Holger Freyther3186bf22008-12-29 06:23:49 +0000818static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
819 enum gsm_chreq_reason_t chreq_reason)
820{
821 struct pending_registered_station *station;
822 if (chreq_reason != GSM_CHREQ_REASON_PAG)
823 return;
824
825 if (llist_empty(&pending_stations)) {
826 DEBUGP(DPAG, "Channel allocated for pag but not waitin for it\n");
827 return;
828 }
829
830 station = (struct pending_registered_station*) pending_stations.next;
831
832 DEBUGP(DPAG, "CHAN RQD due PAG %d on %d for %u\n", chan->type, chan->nr, station->tmsi);
833
834 /* allocate some token in the chan for us */
835 chan->user_data = (void*)station->tmsi;
836 del_timer(&pag_timer);
837}
838
Harald Weltef6b7a902008-12-26 00:05:11 +0000839int main(int argc, char **argv)
840{
Holger Freytherb332f612008-12-27 12:46:51 +0000841 /* parse options */
842 handle_options(argc, argv);
843
Holger Freytherbde36102008-12-28 22:51:39 +0000844 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +0000845 printf("DB: Failed to init database. Please check the option settings.\n");
846 return 1;
847 }
848 printf("DB: Database initialized.\n");
849
850 if (db_prepare()) {
851 printf("DB: Failed to prepare database.\n");
852 return 1;
853 }
854 printf("DB: Database prepared.\n");
855
Harald Weltef6b7a902008-12-26 00:05:11 +0000856 bootstrap_network();
857
858 while (1) {
859 bsc_select_main();
860 }
861}