blob: fe3431ef24d6612169d0dcb2921f4d9804f1c74e [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 */
Holger Freytherb7193e42008-12-29 17:44:08 +000052static void bsc_hack_update_request(struct gsm_bts *bts,
53 u_int32_t assigned_tmi, int accepted);
Holger Freyther3186bf22008-12-29 06:23:49 +000054static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
55 enum gsm_chreq_reason_t reason);
Holger Freyther88ea8322008-12-29 06:23:52 +000056static void bsc_hack_channel_response(struct gsm_lchan *chan, int acked);
Holger Freytherb7193e42008-12-29 17:44:08 +000057static void bsc_hack_call_state_changed(struct gsm_lchan *chan,
58 enum gsm_call_state new_state);
Holger Freyther07cc8d82008-12-29 06:23:46 +000059
Holger Freytherefde7fb2008-12-28 14:14:56 +000060
Harald Welte52b1f982008-12-23 20:25:15 +000061/* The following definitions are for OM and NM packets that we cannot yet
62 * generate by code but we just pass on */
63
64// BTS Site Manager, SET ATTRIBUTES
65
66/*
67 Object Class: BTS Site Manager
68 Instance 1: FF
69 Instance 2: FF
70 Instance 3: FF
71SET ATTRIBUTES
72 sAbisExternalTime: 2007/09/08 14:36:11
73 omLAPDRelTimer: 30sec
74 shortLAPDIntTimer: 5sec
75 emergencyTimer1: 10 minutes
76 emergencyTimer2: 0 minutes
77*/
78
79unsigned char msg_1[] =
80{
81 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0x91, 0x07, 0xD7, 0x09, 0x08, 0x0E, 0x24,
82 0x0B, 0xCE, 0x02, 0x00, 0x1E, 0xE8, 0x01, 0x05, 0x42, 0x02, 0x00, 0x0A, 0x44,
83 0x02, 0x00, 0x00
84};
85
86// BTS, SET BTS ATTRIBUTES
87
88/*
89 Object Class: BTS
90 BTS relat. Number: 0
91 Instance 2: FF
92 Instance 3: FF
93SET BTS ATTRIBUTES
94 bsIdentityCode / BSIC:
95 PLMN_colour_code: 7h
96 BS_colour_code: 7h
97 BTS Air Timer T3105: 4 ,unit 10 ms
98 btsIsHopping: FALSE
99 periodCCCHLoadIndication: 255sec
100 thresholdCCCHLoadIndication: 100%
101 cellAllocationNumber: 00h = GSM 900
102 enableInterferenceClass: 00h = Disabled
103 fACCHQual: 6 (FACCH stealing flags minus 1)
104 intaveParameter: 31 SACCH multiframes
105 interferenceLevelBoundaries:
106 Interference Boundary 1: 0Ah
107 Interference Boundary 2: 0Fh
108 Interference Boundary 3: 14h
109 Interference Boundary 4: 19h
110 Interference Boundary 5: 1Eh
111 mSTxPwrMax: 11
112 GSM range: 2=39dBm, 15=13dBm, stepsize 2 dBm
113 DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
114 PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm
115 30=33dBm, 31=32dBm
116 ny1:
117 Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
118 powerOutputThresholds:
119 Out Power Fault Threshold: -10 dB
120 Red Out Power Threshold: - 6 dB
121 Excessive Out Power Threshold: 5 dB
122 rACHBusyThreshold: -127 dBm
123 rACHLoadAveragingSlots: 250 ,number of RACH burst periods
124 rfResourceIndicationPeriod: 125 SACCH multiframes
125 T200:
126 SDCCH: 044 in 5 ms
127 FACCH/Full rate: 031 in 5 ms
128 FACCH/Half rate: 041 in 5 ms
129 SACCH with TCH SAPI0: 090 in 10 ms
130 SACCH with SDCCH: 090 in 10 ms
131 SDCCH with SAPI3: 090 in 5 ms
132 SACCH with TCH SAPI3: 135 in 10 ms
133 tSync: 9000 units of 10 msec
134 tTrau: 9000 units of 10 msec
135 enableUmLoopTest: 00h = disabled
136 enableExcessiveDistance: 00h = Disabled
137 excessiveDistance: 64km
138 hoppingMode: 00h = baseband hopping
139 cellType: 00h = Standard Cell
140 BCCH ARFCN / bCCHFrequency: 1
141*/
142
143unsigned char msg_2[] =
144{
145 0x41, 0x01, 0x00, 0xFF, 0xFF, 0x09, 0x3F, 0x0A, 0x04, 0x61, 0x00, 0x0B,
146 0xFF, 0x0C, 0x64, 0x62, 0x00, 0x66, 0x00, 0x6E, 0x06, 0x18, 0x1F, 0x19,
147 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B, 0x0B, 0x23, 0x14, 0x28, 0x00, 0x04,
148 0x03, 0x2A, 0x7F, 0x2B, 0x00, 0xFA, 0x8F, 0x7D, 0x33, 0x2C, 0x1F, 0x29,
149 0x5A, 0x5A, 0x5A, 0x87, 0x94, 0x23, 0x28, 0x95, 0x23, 0x28, 0x35, 0x01,
150 0x00, 0x46, 0x01, 0x00, 0x58, 0x01, 0x40, 0xC5, 0x01, 0x00, 0xF2, 0x01,
151 0x00, 0x08, 0x00, HARDCODED_ARFCN/*0x01*/,
152};
153
154// Handover Recognition, SET ATTRIBUTES
155
156/*
157Illegal Contents GSM Formatted O&M Msg
158 Object Class: Handover Recognition
159 BTS relat. Number: 0
160 Instance 2: FF
161 Instance 3: FF
162SET ATTRIBUTES
163 enableDelayPowerBudgetHO: 00h = Disabled
164 enableDistanceHO: 00h = Disabled
165 enableInternalInterCellHandover: 00h = Disabled
166 enableInternalIntraCellHandover: 00h = Disabled
167 enablePowerBudgetHO: 00h = Disabled
168 enableRXLEVHO: 00h = Disabled
169 enableRXQUALHO: 00h = Disabled
170 hoAveragingDistance: 8 SACCH multiframes
171 hoAveragingLev:
172 A_LEV_HO: 8 SACCH multiframes
173 W_LEV_HO: 1 SACCH multiframes
174 hoAveragingPowerBudget: 16 SACCH multiframes
175 hoAveragingQual:
176 A_QUAL_HO: 8 SACCH multiframes
177 W_QUAL_HO: 2 SACCH multiframes
178 hoLowerThresholdLevDL: (10 - 110) dBm
179 hoLowerThresholdLevUL: (5 - 110) dBm
180 hoLowerThresholdQualDL: 06h = 6.4% < BER < 12.8%
181 hoLowerThresholdQualUL: 06h = 6.4% < BER < 12.8%
182 hoThresholdLevDLintra : (20 - 110) dBm
183 hoThresholdLevULintra: (20 - 110) dBm
184 hoThresholdMsRangeMax: 20 km
185 nCell: 06h
186 timerHORequest: 3 ,unit 2 SACCH multiframes
187*/
188
189unsigned char msg_3[] =
190{
191 0xD0, 0xA1, 0x00, 0xFF, 0xFF, 0xD0, 0x00, 0x64, 0x00, 0x67, 0x00, 0x68,
192 0x00, 0x6A, 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6F, 0x08, 0x70, 0x08, 0x01,
193 0x71, 0x10, 0x10, 0x10, 0x72, 0x08, 0x02, 0x73, 0x0A, 0x74, 0x05, 0x75,
194 0x06, 0x76, 0x06, 0x78, 0x14, 0x79, 0x14, 0x7A, 0x14, 0x7D, 0x06, 0x92,
195 0x03, 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01,
196 0x00, 0x5B, 0x01, 0x05, 0x5E, 0x01, 0x1A, 0x5F, 0x01, 0x20, 0x9D, 0x01,
197 0x00, 0x47, 0x01, 0x00, 0x5C, 0x01, 0x64, 0x5D, 0x01, 0x1E, 0x97, 0x01,
198 0x20, 0xF7, 0x01, 0x3C,
199};
200
201// Power Control, SET ATTRIBUTES
202
203/*
204 Object Class: Power Control
205 BTS relat. Number: 0
206 Instance 2: FF
207 Instance 3: FF
208SET ATTRIBUTES
209 enableMsPowerControl: 00h = Disabled
210 enablePowerControlRLFW: 00h = Disabled
211 pcAveragingLev:
212 A_LEV_PC: 4 SACCH multiframes
213 W_LEV_PC: 1 SACCH multiframes
214 pcAveragingQual:
215 A_QUAL_PC: 4 SACCH multiframes
216 W_QUAL_PC: 2 SACCH multiframes
217 pcLowerThresholdLevDL: 0Fh
218 pcLowerThresholdLevUL: 0Ah
219 pcLowerThresholdQualDL: 05h = 3.2% < BER < 6.4%
220 pcLowerThresholdQualUL: 05h = 3.2% < BER < 6.4%
221 pcRLFThreshold: 0Ch
222 pcUpperThresholdLevDL: 14h
223 pcUpperThresholdLevUL: 0Fh
224 pcUpperThresholdQualDL: 04h = 1.6% < BER < 3.2%
225 pcUpperThresholdQualUL: 04h = 1.6% < BER < 3.2%
226 powerConfirm: 2 ,unit 2 SACCH multiframes
227 powerControlInterval: 2 ,unit 2 SACCH multiframes
228 powerIncrStepSize: 02h = 4 dB
229 powerRedStepSize: 01h = 2 dB
230 radioLinkTimeoutBs: 64 SACCH multiframes
231 enableBSPowerControl: 00h = disabled
232*/
233
234unsigned char msg_4[] =
235{
236 0xD0, 0xA2, 0x00, 0xFF, 0xFF, 0x69, 0x00, 0x6B, 0x00, 0x7E, 0x04, 0x01,
237 0x7F, 0x04, 0x02, 0x80, 0x0F, 0x81, 0x0A, 0x82, 0x05, 0x83, 0x05, 0x84,
238 0x0C, 0x85, 0x14, 0x86, 0x0F, 0x87, 0x04, 0x88, 0x04, 0x89, 0x02, 0x8A,
239 0x02, 0x8B, 0x02, 0x8C, 0x01, 0x8D, 0x40, 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
240};
241
242
243// Transceiver, SET TRX ATTRIBUTES (TRX 0)
244
245/*
246 Object Class: Transceiver
247 BTS relat. Number: 0
248 Tranceiver number: 0
249 Instance 3: FF
250SET TRX ATTRIBUTES
251 aRFCNList (HEX): 0001
252 txPwrMaxReduction: 00h = 0dB
253 radioMeasGran: 254 SACCH multiframes
254 radioMeasRep: 01h = enabled
255 memberOfEmergencyConfig: 01h = TRUE
256 trxArea: 00h = TRX doesn't belong to a concentric cell
257*/
258
259unsigned char msg_6[] =
260{
261 0x44, 0x02, 0x00, 0x00, 0xFF, 0x05, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/, 0x2D,
262 0x00, 0xDC, 0x01, 0xFE, 0xDD, 0x01, 0x01, 0x9B, 0x01, 0x01, 0x9F, 0x01, 0x00,
263};
264
265
266static void bootstrap_om(struct gsm_bts *bts)
267{
268 struct gsm_bts_trx *trx = &bts->trx[0];
269
Harald Weltead384642008-12-26 10:20:07 +0000270 fprintf(stdout, "bootstrapping OML\n");
271
Harald Welte52b1f982008-12-23 20:25:15 +0000272 /* stop sending event reports */
273 abis_nm_event_reports(bts, 0);
274
275 /* begin DB transmission */
276 abis_nm_db_transmission(bts, 1);
277
Harald Welte702d8702008-12-26 20:25:35 +0000278 /* end DB transmission */
279 abis_nm_db_transmission(bts, 0);
280
281 /* Reset BTS Site manager resource */
282 abis_nm_reset_resource(bts);
283
284 /* begin DB transmission */
285 abis_nm_db_transmission(bts, 1);
286
Harald Welte52b1f982008-12-23 20:25:15 +0000287 abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
288 abis_nm_raw_msg(bts, sizeof(msg_2), msg_2); /* set BTS attr */
289 abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
290 abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
291
292 /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
293 abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
294 abis_nm_raw_msg(bts, sizeof(msg_6), msg_6); /* SET TRX ATTRIBUTES */
295
296 /* Use TEI 1 for signalling */
297 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
298 abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
299#if 0
300 /* TRX 1 */
301 abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
302 /* FIXME: TRX ATTRIBUTE */
303 abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
304#endif
305
306 /* SET CHANNEL ATTRIBUTE TS1 */
307 abis_nm_set_channel_attr(&trx->ts[1], 0x09);
308 /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
309 abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
310
311 /* SET CHANNEL ATTRIBUTE TS2 */
312 abis_nm_set_channel_attr(&trx->ts[2], 0x09);
313 /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
314 abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
315
316 /* SET CHANNEL ATTRIBUTE TS3 */
317 abis_nm_set_channel_attr(&trx->ts[3], 0x09);
318 /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
319 abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
320
321 /* SET CHANNEL ATTRIBUTE TS4 */
322 abis_nm_set_channel_attr(&trx->ts[4], 0x09);
323 /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
324 abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
325
326 /* SET CHANNEL ATTRIBUTE TS5 */
327 abis_nm_set_channel_attr(&trx->ts[5], 0x09);
328 /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
329 abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
330
331 /* SET CHANNEL ATTRIBUTE TS6 */
332 abis_nm_set_channel_attr(&trx->ts[6], 0x09);
333 /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
334 abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
335
336 /* SET CHANNEL ATTRIBUTE TS7 */
337 abis_nm_set_channel_attr(&trx->ts[7], 0x09);
338 /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
339 abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
340
341 /* end DB transmission */
342 abis_nm_db_transmission(bts, 0);
343
344 /* Reset BTS Site manager resource */
345 abis_nm_reset_resource(bts);
346
347 /* restart sending event reports */
348 abis_nm_event_reports(bts, 1);
349}
350
351
352
353struct bcch_info {
354 u_int8_t type;
355 u_int8_t len;
356 const u_int8_t *data;
357};
358
359/*
360SYSTEM INFORMATION TYPE 1
361 Cell channel description
362 Format-ID bit map 0
363 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
364 RACH Control Parameters
365 maximum 7 retransmissions
366 8 slots used to spread transmission
367 cell not barred for access
368 call reestablishment not allowed
369 Access Control Class = 0000
370*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000371static u_int8_t si1[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000372 /* header */0x55, 0x06, 0x19,
373 /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
375 /* rach */0xD5, 0x00, 0x00,
376 /* s1 reset*/0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000377};
378
379/*
380 SYSTEM INFORMATION TYPE 2
381 Neighbour Cells Description
382 EXT-IND: Carries the complete BA
383 BA-IND = 0
384 Format-ID bit map 0
385 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
386 NCC permitted (NCC) = FF
387 RACH Control Parameters
388 maximum 7 retransmissions
389 8 slots used to spread transmission
390 cell not barred for access
391 call reestablishment not allowed
392 Access Control Class = 0000
393*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000394static u_int8_t si2[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000395 /* header */0x59, 0x06, 0x1A,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 /* ncc */0xFF,
399 /* rach*/0xD5, 0x00, 0x00
Harald Welte52b1f982008-12-23 20:25:15 +0000400};
401
402/*
403SYSTEM INFORMATION TYPE 3
404 Cell identity = 00001 (1h)
405 Location area identification
406 Mobile Country Code (MCC): 001
407 Mobile Network Code (MNC): 01
408 Location Area Code (LAC): 00001 (1h)
409 Control Channel Description
410 Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
411 0 blocks reserved for access grant
412 1 channel used for CCCH, with SDCCH
413 5 multiframes period for PAGING REQUEST
414 Time-out T3212 = 0
415 Cell Options BCCH
416 Power control indicator: not set
417 MSs shall not use uplink DTX
418 Radio link timeout = 36
419 Cell Selection Parameters
420 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
Harald Welte3b2ec422008-12-29 04:11:14 +0000421 max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
Harald Welte52b1f982008-12-23 20:25:15 +0000422 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
423 Half rate support (NECI): New establishment causes are not supported
424 min.RX signal level for MS = 0
425 RACH Control Parameters
426 maximum 7 retransmissions
427 8 slots used to spread transmission
428 cell not barred for access
429 call reestablishment not allowed
430 Access Control Class = 0000
431 SI 3 Rest Octets
432 Cell Bar Qualify (CBQ): 0
433 Cell Reselect Offset = 0 dB
434 Temporary Offset = 0 dB
435 Penalty Time = 20 s
436 System Information 2ter Indicator (2TI): 0 = not available
437 Early Classmark Sending Control (ECSC): 0 = forbidden
438 Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
439*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000440static u_int8_t si3[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000441 /* header */0x49, 0x06, 0x1B,
442 /* cell */0x00, 0x01,
443 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
444 /* desc */0x01, 0x03, 0x00,
445 /* option*/0x28,
446 /* selection*/0x62, 0x00,
447 /* rach */0xD5, 0x00, 0x00,
448 /* reset*/0x80, 0x00, 0x00, 0x2B
Harald Welte52b1f982008-12-23 20:25:15 +0000449};
450
451/*
452SYSTEM INFORMATION TYPE 4
453 Location area identification
454 Mobile Country Code (MCC): 001
455 Mobile Network Code (MNC): 01
456 Location Area Code (LAC): 00001 (1h)
457 Cell Selection Parameters
458 Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
459 max.TX power level MS may use for CCH = 2
460 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
461 Half rate support (NECI): New establishment causes are not supported
462 min.RX signal level for MS = 0
463 RACH Control Parameters
464 maximum 7 retransmissions
465 8 slots used to spread transmission
466 cell not barred for access
467 call reestablishment not allowed
468 Access Control Class = 0000
469 Channel Description
470 Type = SDCCH/4[2]
471 Timeslot Number: 0
472 Training Sequence Code: 7h
473 ARFCN: 1
474 SI Rest Octets
475 Cell Bar Qualify (CBQ): 0
476 Cell Reselect Offset = 0 dB
477 Temporary Offset = 0 dB
478 Penalty Time = 20 s
479*/
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000480static u_int8_t si4[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000481 /* header */0x41, 0x06, 0x1C,
482 /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
483 /* sel */0x62, 0x00,
484 /* rach*/0xD5, 0x00, 0x00,
485 /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000486 0x2B, 0x2B, 0x2B
487};
488
489/*
490 SYSTEM INFORMATION TYPE 5
491 Neighbour Cells Description
492 EXT-IND: Carries the complete BA
493 BA-IND = 0
494 Format-ID bit map 0
495 CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
496*/
497
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000498static u_int8_t si5[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000499 /* header without l2 len*/0x06, 0x1D,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Harald Welte52b1f982008-12-23 20:25:15 +0000502};
503
504// SYSTEM INFORMATION TYPE 6
505
506/*
507SACCH FILLING
508 System Info Type: SYSTEM INFORMATION 6
509 L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
510
511SYSTEM INFORMATION TYPE 6
512 Cell identity = 00001 (1h)
513 Location area identification
514 Mobile Country Code (MCC): 001
515 Mobile Network Code (MNC): 01
516 Location Area Code (LAC): 00001 (1h)
517 Cell Options SACCH
518 Power control indicator: not set
519 MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
520 Radio link timeout = 36
521 NCC permitted (NCC) = FF
522*/
523
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000524static u_int8_t si6[] = {
Holger Freyther4d505472008-12-28 16:32:42 +0000525 /* header */0x06, 0x1E,
526 /* cell id*/ 0x00, 0x01,
527 /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
528 /* options */ 0x28,
529 /* ncc */ 0xFF,
Harald Welte52b1f982008-12-23 20:25:15 +0000530};
531
532
533
534static const struct bcch_info bcch_infos[] = {
535 {
536 .type = RSL_SYSTEM_INFO_1,
537 .len = sizeof(si1),
538 .data = si1,
539 }, {
540 .type = RSL_SYSTEM_INFO_2,
541 .len = sizeof(si2),
542 .data = si2,
543 }, {
544 .type = RSL_SYSTEM_INFO_3,
545 .len = sizeof(si3),
546 .data = si3,
547 }, {
548 .type = RSL_SYSTEM_INFO_4,
549 .len = sizeof(si4),
550 .data = si4,
551 },
552};
553
Holger Freyther24287b62008-12-28 16:32:41 +0000554static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
555static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
556static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
557static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
Harald Welte104604e2008-12-28 16:36:11 +0000558static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
559static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
Holger Freyther24287b62008-12-28 16:32:41 +0000560
Harald Welte52b1f982008-12-23 20:25:15 +0000561/* set all system information types */
562static int set_system_infos(struct gsm_bts *bts)
563{
564 int i;
565
566 for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
567 rsl_bcch_info(bts, bcch_infos[i].type,
568 bcch_infos[i].data,
569 bcch_infos[i].len);
570 }
571 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
572 rsl_sacch_filling(bts, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
Harald Weltead384642008-12-26 10:20:07 +0000573
574 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000575}
576
577static void activate_traffic_channels(struct gsm_bts_trx *trx)
578{
579 int i;
580
581 /* channel 0 is CCCH */
582 for (i = 1; i < 8; i++)
583 rsl_chan_activate_tch_f(&trx->ts[i]);
584}
585
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000586/*
587 * Patch the various SYSTEM INFORMATION tables to update
588 * the LAI
589 */
590static void patch_tables(struct gsm_bts *bts)
591{
592 /* covert the raw packet to the struct */
593 struct gsm48_system_information_type_3 *type_3 =
594 (struct gsm48_system_information_type_3*)&si3;
595 struct gsm48_system_information_type_4 *type_4 =
596 (struct gsm48_system_information_type_4*)&si4;
597 struct gsm48_system_information_type_6 *type_6 =
598 (struct gsm48_system_information_type_6*)&si6;
Harald Welteb84e2f42008-12-28 23:42:04 +0000599 struct gsm48_loc_area_id lai;
600
601 gsm0408_generate_lai(&lai, bts->network->country_code,
602 bts->network->network_code, bts->location_area_code);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000603
604 /* assign the MCC and MNC */
Harald Welteb84e2f42008-12-28 23:42:04 +0000605 type_3->lai = lai;
606 type_4->lai = lai;
607 type_6->lai = lai;
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000608}
609
610
Harald Weltead384642008-12-26 10:20:07 +0000611static void bootstrap_rsl(struct gsm_bts *bts)
Harald Welte52b1f982008-12-23 20:25:15 +0000612{
Harald Welteb84e2f42008-12-28 23:42:04 +0000613 fprintf(stdout, "bootstrapping RSL MCC=%u MNC=%u\n", MCC, MNC);
Holger Freytherb9ddfd02008-12-28 16:32:45 +0000614 patch_tables(bts);
Harald Welte52b1f982008-12-23 20:25:15 +0000615 set_system_infos(bts);
616
617 /* FIXME: defer this until the channels are used */
Harald Welte702d8702008-12-26 20:25:35 +0000618 //activate_traffic_channels(&bts->trx[0]);
Harald Welte52b1f982008-12-23 20:25:15 +0000619}
620
Harald Weltead384642008-12-26 10:20:07 +0000621static void mi_cb(int event, struct gsm_bts *bts)
622{
623 switch (event) {
624 case EVT_E1_OML_UP:
625 bootstrap_om(bts);
626 break;
627 case EVT_E1_RSL_UP:
628 bootstrap_rsl(bts);
629 break;
630 default:
631 /* FIXME: deal with TEI or L1 link loss */
632 break;
633 }
634}
635
636static int bootstrap_network(void)
Harald Welte52b1f982008-12-23 20:25:15 +0000637{
638 struct gsm_bts *bts;
639
640 /* initialize our data structures */
Holger Freytherefde7fb2008-12-28 14:14:56 +0000641 gsmnet = gsm_network_init(1, MCC, MNC);
Harald Weltead384642008-12-26 10:20:07 +0000642 if (!gsmnet)
643 return -ENOMEM;
Harald Weltef5cbab72008-12-30 18:00:15 +0000644
645 gsmnet->name_short = "25C3";
646 gsmnet->name_long = "25C3 GSM";
Harald Welte52b1f982008-12-23 20:25:15 +0000647 bts = &gsmnet->bts[0];
648 bts->location_area_code = 1;
649 bts->trx[0].arfcn = HARDCODED_ARFCN;
Harald Weltef5cbab72008-12-30 18:00:15 +0000650#if 0
Holger Freytherb7193e42008-12-29 17:44:08 +0000651 gsmnet->update_request = bsc_hack_update_request;
Holger Freyther3186bf22008-12-29 06:23:49 +0000652 gsmnet->channel_allocated = bsc_hack_channel_allocated;
Holger Freyther88ea8322008-12-29 06:23:52 +0000653 gsmnet->channel_response = bsc_hack_channel_response;
Holger Freytherb7193e42008-12-29 17:44:08 +0000654 gsmnet->call_state_changed = bsc_hack_call_state_changed;
Harald Weltef5cbab72008-12-30 18:00:15 +0000655#endif
Harald Welte52b1f982008-12-23 20:25:15 +0000656
Harald Weltead384642008-12-26 10:20:07 +0000657 if (mi_setup(bts, 0, mi_cb) < 0)
658 return -EIO;
659
660 return 0;
Harald Welte52b1f982008-12-23 20:25:15 +0000661}
Harald Weltef6b7a902008-12-26 00:05:11 +0000662
Holger Freytherb332f612008-12-27 12:46:51 +0000663static void print_usage()
664{
665 printf("Usage: bsc_hack\n");
666}
667
668static void print_help()
669{
670 printf(" Some useful help...\n");
671 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
Holger Freytherefde7fb2008-12-28 14:14:56 +0000672 printf(" -s --disable-color\n");
673 printf(" -n --network-code number(MNC) \n");
674 printf(" -c --country-code number (MCC) \n");
Holger Freytherbde36102008-12-28 22:51:39 +0000675 printf(" -l --database db-name The database to use\n");
Holger Freyther89824fc2008-12-30 16:18:18 +0000676 printf(" -a --authorize-everyone Allow everyone into the network.\n");
Holger Freytherb332f612008-12-27 12:46:51 +0000677 printf(" -h --help this text\n");
678}
679
680static void handle_options(int argc, char** argv)
681{
682 while (1) {
683 int option_index = 0, c;
684 static struct option long_options[] = {
685 {"help", 0, 0, 'h'},
686 {"debug", 1, 0, 'd'},
Holger Freytherefde7fb2008-12-28 14:14:56 +0000687 {"disable-color", 0, 0, 's'},
688 {"network-code", 1, 0, 'n'},
689 {"country-code", 1, 0, 'c'},
Holger Freytherbde36102008-12-28 22:51:39 +0000690 {"database", 1, 0, 'l'},
Holger Freyther89824fc2008-12-30 16:18:18 +0000691 {"authorize-everyone", 0, 0, 'a'},
Holger Freytherb332f612008-12-27 12:46:51 +0000692 {0, 0, 0, 0}
693 };
694
Holger Freyther89824fc2008-12-30 16:18:18 +0000695 c = getopt_long(argc, argv, "hc:n:d:sa",
Holger Freytherb332f612008-12-27 12:46:51 +0000696 long_options, &option_index);
697 if (c == -1)
698 break;
699
700 switch (c) {
701 case 'h':
702 print_usage();
703 print_help();
704 exit(0);
Holger Freytherefde7fb2008-12-28 14:14:56 +0000705 case 's':
Holger Freytherb332f612008-12-27 12:46:51 +0000706 debug_use_color(0);
707 break;
708 case 'd':
709 debug_parse_category_mask(optarg);
710 break;
Holger Freytherefde7fb2008-12-28 14:14:56 +0000711 case 'n':
712 MNC = atoi(optarg);
713 break;
714 case 'c':
715 MCC = atoi(optarg);
716 break;
Holger Freytherbde36102008-12-28 22:51:39 +0000717 case 'l':
718 database_name = strdup(optarg);
719 break;
Holger Freyther89824fc2008-12-30 16:18:18 +0000720 case 'a':
721 gsm0408_allow_everyone(1);
722 break;
Holger Freytherb332f612008-12-27 12:46:51 +0000723 default:
724 /* ignore */
725 break;
726 }
727 }
728}
729
Harald Welte255539c2008-12-28 02:26:27 +0000730static struct timer_list pag_timer;
731
732/* handles uppercase decimal and hexadecimal */
733static u_int8_t char2bcd(char c)
734{
735 if (c <= '9')
736 return c - '0';
737 else
738 return c - 'A';
739}
740
741static int string_to_mi(u_int8_t *mi, const char *string,
742 u_int8_t type)
743{
744 u_int8_t *cur = mi+3;
745
746 mi[0] = GSM48_IE_MOBILE_ID;
747 //mi[1] = TMSI_LEN;
748 mi[2] = type & GSM_MI_TYPE_MASK;
749
750 if (strlen(string) & 0x01)
751 mi[2] |= char2bcd(*string++) << 4;
752 else
753 mi[2] |= 0xf0;
754
755 while (*string && *(string+1))
756 *cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4);
757
758 mi[1] = cur - mi;
759
760 return cur - mi;
761}
762
Holger Freyther07cc8d82008-12-29 06:23:46 +0000763/*
764 * Stations that registered and that we need to page
765 */
766struct pending_registered_station {
767 struct llist_head entry;
Harald Welte255539c2008-12-28 02:26:27 +0000768
Holger Freyther07cc8d82008-12-29 06:23:46 +0000769 /* the tmsi of the subscriber */
770 u_int32_t tmsi;
771 int last_page_group;
772};
773
774static LLIST_HEAD(pending_stations);
775
776static void pag_timer_cb(void *data);
777static struct timer_list pag_timer = {
778 .cb = pag_timer_cb,
779};
780
781/* page the tmsi and wait for the channel request */
782static void pag_timer_cb(void *data)
Harald Welte255539c2008-12-28 02:26:27 +0000783{
784 struct gsm_bts *bts = &gsmnet->bts[0];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000785 struct pending_registered_station *pending_station;
Harald Welte255539c2008-12-28 02:26:27 +0000786 u_int8_t mi[128];
Holger Freyther07cc8d82008-12-29 06:23:46 +0000787 unsigned int mi_len;
Harald Welte255539c2008-12-28 02:26:27 +0000788
Harald Weltef5cbab72008-12-30 18:00:15 +0000789return 0;
790
Holger Freyther07cc8d82008-12-29 06:23:46 +0000791 if (llist_empty(&pending_stations)) {
792 DEBUGP(DPAG, "pag_timer_cb but no pending mobile stations\n");
Harald Welte255539c2008-12-28 02:26:27 +0000793 return;
Holger Freyther07cc8d82008-12-29 06:23:46 +0000794 }
Harald Welte255539c2008-12-28 02:26:27 +0000795
Holger Freyther07cc8d82008-12-29 06:23:46 +0000796 /* get the station to page */
797 pending_station = (struct pending_registered_station*) pending_stations.next;
798 mi_len = generate_mid_from_tmsi(mi, pending_station->tmsi);
799 rsl_paging_cmd(bts, pending_station->last_page_group, mi_len, mi, RSL_CHANNEED_TCH_F);
Harald Welte255539c2008-12-28 02:26:27 +0000800
Holger Freyther07cc8d82008-12-29 06:23:46 +0000801 /* which group to page next */
802 pending_station->last_page_group = (pending_station->last_page_group+1) % 12;
803 schedule_timer(&pag_timer, 1, 0);
804}
Harald Welte255539c2008-12-28 02:26:27 +0000805
Holger Freyther07cc8d82008-12-29 06:23:46 +0000806/*
807 * initiate the a page command for the given
808 * station and retry until we get a channel request
809 */
810static void station_timer_cb(void *data)
811{
812 DEBUGP(DPAG, "Initiating paging of a channel\n");
813 pag_timer_cb(0);
814}
Harald Welte255539c2008-12-28 02:26:27 +0000815
Holger Freyther07cc8d82008-12-29 06:23:46 +0000816static struct timer_list station_timer = {
817 .cb = station_timer_cb,
818};
819
820/*
821 * schedule work
822 */
Holger Freytherb7193e42008-12-29 17:44:08 +0000823static void bsc_hack_update_request(struct gsm_bts *bts, u_int32_t tmsi, int accepted)
Holger Freyther07cc8d82008-12-29 06:23:46 +0000824{
825 struct pending_registered_station *station =
826 (struct pending_registered_station*)malloc(sizeof(*station));
Holger Freytherb7193e42008-12-29 17:44:08 +0000827
828 /*
829 * Only deal with LOCATION UPDATE REQUEST we have
830 * accepted.
831 */
832 if (!accepted)
833 return;
834
835
Holger Freyther07cc8d82008-12-29 06:23:46 +0000836 station->tmsi = tmsi;
837 station->last_page_group = 0;
838 llist_add_tail(&station->entry, &pending_stations);
839
840 if (!timer_pending(&station_timer))
841 schedule_timer(&station_timer, 1, 0);
Harald Welte255539c2008-12-28 02:26:27 +0000842}
843
Holger Freyther3186bf22008-12-29 06:23:49 +0000844static void bsc_hack_channel_allocated(struct gsm_lchan *chan,
845 enum gsm_chreq_reason_t chreq_reason)
846{
847 struct pending_registered_station *station;
848 if (chreq_reason != GSM_CHREQ_REASON_PAG)
849 return;
850
851 if (llist_empty(&pending_stations)) {
852 DEBUGP(DPAG, "Channel allocated for pag but not waitin for it\n");
853 return;
854 }
855
856 station = (struct pending_registered_station*) pending_stations.next;
857
858 DEBUGP(DPAG, "CHAN RQD due PAG %d on %d for %u\n", chan->type, chan->nr, station->tmsi);
859
860 /* allocate some token in the chan for us */
861 chan->user_data = (void*)station->tmsi;
862 del_timer(&pag_timer);
863}
864
Holger Freyther88ea8322008-12-29 06:23:52 +0000865static void bsc_hack_channel_response(struct gsm_lchan *lchan, int ack)
Holger Freyther24893de2008-12-29 06:23:51 +0000866{
867 struct pending_registered_station *station;
868 if (llist_empty(&pending_stations)) {
Holger Freyther24893de2008-12-29 06:23:51 +0000869 return;
870 }
871
872 station = (struct pending_registered_station*) pending_stations.next;
873 if (station->tmsi != (u_int32_t)lchan->user_data) {
874 DEBUGP(DPAG, "Hmmm the channel is not allocated by the"
875 "station we wanted channel: %u us:%u\n",
876 (u_int32_t)(lchan->user_data), station->tmsi);
877 return;
878 }
879
Holger Freyther88ea8322008-12-29 06:23:52 +0000880 if (ack) {
881 DEBUGP(DPAG, "We have probably paged a channel for tmsi: %u on %d\n",
882 station->tmsi, lchan->nr);
Holger Freyther24893de2008-12-29 06:23:51 +0000883
Holger Freyther88ea8322008-12-29 06:23:52 +0000884 llist_del(&station->entry);
885 free(station);
Holger Freytherabade7a2008-12-29 06:42:15 +0000886
887 /*
888 * start a call
889 */
890 gsm48_cc_tx_setup(lchan);
Holger Freyther88ea8322008-12-29 06:23:52 +0000891 } else {
892 /*
893 * give up and go to the next channel
894 */
895 llist_del(&station->entry);
896 free(station);
897 pag_timer_cb(0);
Holger Freyther24893de2008-12-29 06:23:51 +0000898 }
Holger Freyther24893de2008-12-29 06:23:51 +0000899}
900
Holger Freytherb7193e42008-12-29 17:44:08 +0000901static void bsc_hack_call_state_changed(struct gsm_lchan *lchan,
902 enum gsm_call_state new_state)
Holger Freyther2eafef52008-12-29 06:42:17 +0000903{
904 DEBUGP(DPAG, "Call released jumping to the next...\n");
Holger Freytherb7193e42008-12-29 17:44:08 +0000905
906 /* only handle the transition back to the NULL state */
907 if (new_state != GSM_CSTATE_NULL)
908 return;
909
Holger Freyther2eafef52008-12-29 06:42:17 +0000910 rsl_chan_release(lchan);
911
912 /* next!!! */
913 pag_timer_cb(0);
914}
915
Harald Weltef6b7a902008-12-26 00:05:11 +0000916int main(int argc, char **argv)
917{
Holger Freytherb332f612008-12-27 12:46:51 +0000918 /* parse options */
919 handle_options(argc, argv);
920
Holger Freytherbde36102008-12-28 22:51:39 +0000921 if (db_init(database_name)) {
Harald Welte75a983f2008-12-27 21:34:06 +0000922 printf("DB: Failed to init database. Please check the option settings.\n");
923 return 1;
924 }
925 printf("DB: Database initialized.\n");
926
927 if (db_prepare()) {
928 printf("DB: Failed to prepare database.\n");
929 return 1;
930 }
931 printf("DB: Database prepared.\n");
932
Harald Weltef6b7a902008-12-26 00:05:11 +0000933 bootstrap_network();
934
935 while (1) {
936 bsc_select_main();
937 }
938}