Minor fix in display facility.
[lcr.git] / bootstrap.c
1 /* Bootstrapping GSM - taken from bsc_hack.c */
2
3 /* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
4  * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
5  * All Rights Reserved
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <time.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <sys/stat.h>
32
33 #ifndef _GNU_SOURCE
34 #define _GNU_SOURCE
35 #endif
36 #include <getopt.h>
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 #include <openbsc/gsm_data.h>
42 #include <openbsc/gsm_04_08.h>
43 #include <openbsc/db.h>
44 #include <openbsc/timer.h>
45 #include <openbsc/select.h>
46 #include <openbsc/abis_rsl.h>
47 #include <openbsc/abis_nm.h>
48 #include <openbsc/debug.h>
49 #include <openbsc/misdn.h>
50 #include <openbsc/telnet_interface.h>
51 #include <openbsc/paging.h>
52 #include <openbsc/e1_input.h>
53 #include <openbsc/signal.h>
54
55
56 static enum gsm_band BAND = GSM_BAND_900;
57
58 /* The following definitions are for OM and NM packets that we cannot yet
59  * generate by code but we just pass on */
60
61 // BTS Site Manager, SET ATTRIBUTES
62
63 /*
64   Object Class: BTS Site Manager
65   Instance 1: FF
66   Instance 2: FF
67   Instance 3: FF
68 SET ATTRIBUTES
69   sAbisExternalTime: 2007/09/08   14:36:11
70   omLAPDRelTimer: 30sec
71   shortLAPDIntTimer: 5sec
72   emergencyTimer1: 10 minutes
73   emergencyTimer2: 0 minutes
74 */
75
76 unsigned char msg_1[] = 
77 {
78         NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER, 0xFF, 0xFF, 0xFF, 
79                 NM_ATT_BS11_ABIS_EXT_TIME, 0x07, 
80                         0xD7, 0x09, 0x08, 0x0E, 0x24, 0x0B, 0xCE, 
81                 0x02, 
82                         0x00, 0x1E, 
83                 NM_ATT_BS11_SH_LAPD_INT_TIMER, 
84                         0x01, 0x05,
85                 0x42, 0x02, 0x00, 0x0A, 
86                 0x44, 0x02, 0x00, 0x00
87 };
88
89 // BTS, SET BTS ATTRIBUTES
90
91 /*
92   Object Class: BTS
93   BTS relat. Number: 0 
94   Instance 2: FF
95   Instance 3: FF
96 SET BTS ATTRIBUTES
97   bsIdentityCode / BSIC:
98     PLMN_colour_code: 7h
99     BS_colour_code:   7h
100   BTS Air Timer T3105: 4  ,unit 10 ms
101   btsIsHopping: FALSE
102   periodCCCHLoadIndication: 1sec
103   thresholdCCCHLoadIndication: 0%
104   cellAllocationNumber: 00h = GSM 900
105   enableInterferenceClass: 00h =  Disabled
106   fACCHQual: 6 (FACCH stealing flags minus 1)
107   intaveParameter: 31 SACCH multiframes
108   interferenceLevelBoundaries:
109     Interference Boundary 1: 0Ah 
110     Interference Boundary 2: 0Fh
111     Interference Boundary 3: 14h
112     Interference Boundary 4: 19h
113     Interference Boundary 5: 1Eh
114   mSTxPwrMax: 11
115       GSM range:     2=39dBm, 15=13dBm, stepsize 2 dBm 
116       DCS1800 range: 0=30dBm, 15=0dBm, stepsize 2 dBm 
117       PCS1900 range: 0=30dBm, 15=0dBm, stepsize 2 dBm 
118                     30=33dBm, 31=32dBm 
119   ny1:
120     Maximum number of repetitions for PHYSICAL INFORMATION message (GSM 04.08): 20
121   powerOutputThresholds:
122     Out Power Fault Threshold:     -10 dB
123     Red Out Power Threshold:       - 6 dB
124     Excessive Out Power Threshold:   5 dB
125   rACHBusyThreshold: -127 dBm 
126   rACHLoadAveragingSlots: 250 ,number of RACH burst periods
127   rfResourceIndicationPeriod: 125  SACCH multiframes 
128   T200:
129     SDCCH:                044 in  5 ms
130     FACCH/Full rate:      031 in  5 ms
131     FACCH/Half rate:      041 in  5 ms
132     SACCH with TCH SAPI0: 090 in 10 ms
133     SACCH with SDCCH:     090 in 10 ms
134     SDCCH with SAPI3:     090 in  5 ms
135     SACCH with TCH SAPI3: 135 in 10 ms
136   tSync: 9000 units of 10 msec
137   tTrau: 9000 units of 10 msec
138   enableUmLoopTest: 00h =  disabled
139   enableExcessiveDistance: 00h =  Disabled
140   excessiveDistance: 64km
141   hoppingMode: 00h = baseband hopping
142   cellType: 00h =  Standard Cell
143   BCCH ARFCN / bCCHFrequency: 1
144 */
145
146 static unsigned char bs11_attr_bts[] = 
147 {
148                 NM_ATT_BSIC, HARDCODED_BSIC,
149                 NM_ATT_BTS_AIR_TIMER, 0x04,
150                 NM_ATT_BS11_BTSLS_HOPPING, 0x00,
151                 NM_ATT_CCCH_L_I_P, 0x01,
152                 NM_ATT_CCCH_L_T, 0x00,
153                 NM_ATT_BS11_CELL_ALLOC_NR, NM_BS11_CANR_GSM,
154                 NM_ATT_BS11_ENA_INTERF_CLASS, 0x01,
155                 NM_ATT_BS11_FACCH_QUAL, 0x06,
156                 /* interference avg. period in numbers of SACCH multifr */
157                 NM_ATT_INTAVE_PARAM, 0x1F, 
158                 NM_ATT_INTERF_BOUND, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x7B,
159                 NM_ATT_CCCH_L_T, 0x23,
160                 NM_ATT_GSM_TIME, 0x28, 0x00,
161                 NM_ATT_ADM_STATE, 0x03,
162                 NM_ATT_RACH_B_THRESH, 0x7F,
163                 NM_ATT_LDAVG_SLOTS, 0x00, 0xFA,
164                 NM_ATT_BS11_RF_RES_IND_PER, 0x7D,
165                 NM_ATT_T200, 0x2C, 0x1F, 0x29, 0x5A, 0x5A, 0x5A, 0x87,
166                 NM_ATT_BS11_TSYNC, 0x23, 0x28,
167                 NM_ATT_BS11_TTRAU, 0x23, 0x28, 
168                 NM_ATT_TEST_DUR, 0x01, 0x00,
169                 NM_ATT_OUTST_ALARM, 0x01, 0x00,
170                 NM_ATT_BS11_EXCESSIVE_DISTANCE, 0x01, 0x40,
171                 NM_ATT_BS11_HOPPING_MODE, 0x01, 0x00,
172                 NM_ATT_BS11_PLL, 0x01, 0x00, 
173                 NM_ATT_BCCH_ARFCN, 0x00, HARDCODED_ARFCN/*0x01*/, 
174 };
175
176 // Handover Recognition, SET ATTRIBUTES
177
178 /*
179 Illegal Contents GSM Formatted O&M Msg 
180   Object Class: Handover Recognition
181   BTS relat. Number: 0 
182   Instance 2: FF
183   Instance 3: FF
184 SET ATTRIBUTES
185   enableDelayPowerBudgetHO: 00h = Disabled
186   enableDistanceHO: 00h =  Disabled
187   enableInternalInterCellHandover: 00h = Disabled
188   enableInternalIntraCellHandover: 00h =  Disabled
189   enablePowerBudgetHO: 00h = Disabled
190   enableRXLEVHO: 00h =  Disabled
191   enableRXQUALHO: 00h =  Disabled
192   hoAveragingDistance: 8  SACCH multiframes 
193   hoAveragingLev:
194     A_LEV_HO: 8  SACCH multiframes 
195     W_LEV_HO: 1  SACCH multiframes 
196   hoAveragingPowerBudget:  16  SACCH multiframes 
197   hoAveragingQual:
198     A_QUAL_HO: 8  SACCH multiframes 
199     W_QUAL_HO: 2  SACCH multiframes 
200   hoLowerThresholdLevDL: (10 - 110) dBm
201   hoLowerThresholdLevUL: (5 - 110) dBm
202   hoLowerThresholdQualDL: 06h =   6.4% < BER < 12.8%
203   hoLowerThresholdQualUL: 06h =   6.4% < BER < 12.8%
204   hoThresholdLevDLintra : (20 - 110) dBm
205   hoThresholdLevULintra: (20 - 110) dBm
206   hoThresholdMsRangeMax: 20 km 
207   nCell: 06h
208   timerHORequest: 3  ,unit 2 SACCH multiframes 
209 */
210
211 unsigned char msg_3[] = 
212 {
213         NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF, 
214                 0xD0, 0x00,
215                 0x64, 0x00,
216                 0x67, 0x00,
217                 0x68, 0x00,
218                 0x6A, 0x00,
219                 0x6C, 0x00,
220                 0x6D, 0x00,
221                 0x6F, 0x08,
222                 0x70, 0x08, 0x01,
223                 0x71, 0x10, 0x10, 0x10,
224                 0x72, 0x08, 0x02,
225                 0x73, 0x0A,
226                 0x74, 0x05,
227                 0x75, 0x06,
228                 0x76, 0x06,
229                 0x78, 0x14,
230                 0x79, 0x14,
231                 0x7A, 0x14,
232                 0x7D, 0x06,
233                 0x92, 0x03, 0x20, 0x01, 0x00,
234                 0x45, 0x01, 0x00,
235                 0x48, 0x01, 0x00,
236                 0x5A, 0x01, 0x00,
237                 0x5B, 0x01, 0x05,
238                 0x5E, 0x01, 0x1A,
239                 0x5F, 0x01, 0x20,
240                 0x9D, 0x01, 0x00,
241                 0x47, 0x01, 0x00,
242                 0x5C, 0x01, 0x64,
243                 0x5D, 0x01, 0x1E,
244                 0x97, 0x01, 0x20,
245                 0xF7, 0x01, 0x3C,
246 };
247
248 // Power Control, SET ATTRIBUTES
249
250 /*
251   Object Class: Power Control
252   BTS relat. Number: 0 
253   Instance 2: FF
254   Instance 3: FF
255 SET ATTRIBUTES
256   enableMsPowerControl: 00h =  Disabled
257   enablePowerControlRLFW: 00h =  Disabled
258   pcAveragingLev:
259     A_LEV_PC: 4  SACCH multiframes 
260     W_LEV_PC: 1  SACCH multiframes 
261   pcAveragingQual:
262     A_QUAL_PC: 4  SACCH multiframes 
263     W_QUAL_PC: 2  SACCH multiframes 
264   pcLowerThresholdLevDL: 0Fh
265   pcLowerThresholdLevUL: 0Ah
266   pcLowerThresholdQualDL: 05h =   3.2% < BER <  6.4%
267   pcLowerThresholdQualUL: 05h =   3.2% < BER <  6.4%
268   pcRLFThreshold: 0Ch
269   pcUpperThresholdLevDL: 14h
270   pcUpperThresholdLevUL: 0Fh
271   pcUpperThresholdQualDL: 04h =   1.6% < BER <  3.2%
272   pcUpperThresholdQualUL: 04h =   1.6% < BER <  3.2%
273   powerConfirm: 2  ,unit 2 SACCH multiframes 
274   powerControlInterval: 2  ,unit 2 SACCH multiframes 
275   powerIncrStepSize: 02h = 4 dB
276   powerRedStepSize: 01h = 2 dB
277   radioLinkTimeoutBs: 64  SACCH multiframes 
278   enableBSPowerControl: 00h =  disabled
279 */
280
281 unsigned char msg_4[] = 
282 {
283         NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF, 
284                 NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00,
285                 NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00,
286                 0x7E, 0x04, 0x01,
287                 0x7F, 0x04, 0x02,
288                 0x80, 0x0F,
289                 0x81, 0x0A,
290                 0x82, 0x05,
291                 0x83, 0x05,
292                 0x84, 0x0C, 
293                 0x85, 0x14, 
294                 0x86, 0x0F, 
295                 0x87, 0x04,
296                 0x88, 0x04,
297                 0x89, 0x02,
298                 0x8A, 0x02,
299                 0x8B, 0x02,
300                 0x8C, 0x01,
301                 0x8D, 0x40,
302                 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl
303 };
304
305
306 // Transceiver, SET TRX ATTRIBUTES (TRX 0)
307
308 /*
309   Object Class: Transceiver
310   BTS relat. Number: 0 
311   Tranceiver number: 0 
312   Instance 3: FF
313 SET TRX ATTRIBUTES
314   aRFCNList (HEX):  0001
315   txPwrMaxReduction: 00h =   30dB
316   radioMeasGran: 254  SACCH multiframes 
317   radioMeasRep: 01h =  enabled
318   memberOfEmergencyConfig: 01h =  TRUE
319   trxArea: 00h = TRX doesn't belong to a concentric cell
320 */
321
322 static unsigned char bs11_attr_radio[] = 
323 {
324                 NM_ATT_ARFCN_LIST, 0x01, 0x00, HARDCODED_ARFCN /*0x01*/,
325                 NM_ATT_RF_MAXPOWR_R, 0x00,
326                 NM_ATT_BS11_RADIO_MEAS_GRAN, 0x01, 0x05, 
327                 NM_ATT_BS11_RADIO_MEAS_REP, 0x01, 0x01,
328                 NM_ATT_BS11_EMRG_CFG_MEMBER, 0x01, 0x01,
329                 NM_ATT_BS11_TRX_AREA, 0x01, 0x00, 
330 };
331
332 static unsigned char nanobts_attr_bts[] = {
333         NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
334         /* interference avg. period in numbers of SACCH multifr */
335         NM_ATT_INTAVE_PARAM, 0x06,
336         /* conn fail based on SACCH error rate */
337         NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10, 
338         NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
339         NM_ATT_MAX_TA, 0x3f,
340         NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
341         NM_ATT_CCCH_L_T, 10, /* percent */
342         NM_ATT_CCCH_L_I_P, 1, /* seconds */
343         NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
344         NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
345         NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
346         NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
347         NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
348         NM_ATT_BSIC, HARDCODED_BSIC,
349 };
350
351 static unsigned char nanobts_attr_radio[] = {
352         NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
353         NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
354 };
355
356 static unsigned char nanobts_attr_e0[] = {
357         0x85, 0x00,
358         0x81, 0x0b, 0xbb,       /* TCP PORT for RSL */
359 };
360
361 /* Callback function to be called whenever we get a GSM 12.21 state change event */
362 int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
363                    struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
364 {
365         struct gsm_bts *bts;
366         struct gsm_bts_trx *trx;
367         struct gsm_bts_trx_ts *ts;
368
369         /* This is currently only required on nanoBTS */
370
371         switch (evt) {
372         case EVT_STATECHG_OPER:
373                 switch (obj_class) {
374                 case NM_OC_SITE_MANAGER:
375                         bts = container_of(obj, struct gsm_bts, site_mgr);
376                         if (old_state->operational != 2 && new_state->operational == 2) {
377                                 abis_nm_opstart(bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff);
378                         }
379                         break;
380                 case NM_OC_BTS:
381                         bts = (struct gsm_bts *)obj;
382                         if (new_state->availability == 5) {
383                                 abis_nm_set_bts_attr(bts, nanobts_attr_bts,
384                                                         sizeof(nanobts_attr_bts));
385                                 abis_nm_opstart(bts, NM_OC_BTS,
386                                                 bts->bts_nr, 0xff, 0xff);
387                                 abis_nm_chg_adm_state(bts, NM_OC_BTS,
388                                                       bts->bts_nr, 0xff, 0xff,
389                                                       NM_STATE_UNLOCKED);
390                         }
391                         break;
392                 case NM_OC_CHANNEL:
393                         ts = (struct gsm_bts_trx_ts *)obj;
394                         trx = ts->trx;
395                         if (new_state->availability == 5) {
396                                 if (ts->nr == 0 && trx == trx->bts->c0)
397                                         abis_nm_set_channel_attr(ts, NM_CHANC_BCCH_CBCH);
398                                 else
399                                         abis_nm_set_channel_attr(ts, NM_CHANC_TCHFull);
400                                 abis_nm_opstart(trx->bts, NM_OC_CHANNEL,
401                                                 trx->bts->bts_nr, trx->nr, ts->nr);
402                                 abis_nm_chg_adm_state(trx->bts, NM_OC_CHANNEL,
403                                                       trx->bts->bts_nr, trx->nr, ts->nr,
404                                                       NM_STATE_UNLOCKED);
405                         }
406                         break;
407                 default:
408                         break;
409                 }
410                 break;
411         default:
412                 //DEBUGP(DMM, "Unhandled state change in %s:%d\n", __func__, __LINE__);
413                 break;
414         }
415         return 0;
416 }
417
418 /* Callback function to be called every time we receive a 12.21 SW activated report */
419 static int sw_activ_rep(struct msgb *mb)
420 {
421         struct abis_om_fom_hdr *foh = (struct abis_om_fom_hdr *)msgb_l3(mb);
422         struct gsm_bts_trx *trx = mb->trx;
423
424         switch (foh->obj_class) {
425         case NM_OC_BASEB_TRANSC:
426                 /* TRX software is active, tell it to initiate RSL Link */
427                 abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC,
428                                      trx->bts->bts_nr, trx->nr, 0xff,
429                                      nanobts_attr_e0, sizeof(nanobts_attr_e0));
430                 abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC, 
431                                 trx->bts->bts_nr, trx->nr, 0xff);
432                 abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC, 
433                                         trx->bts->bts_nr, trx->nr, 0xff,
434                                         NM_STATE_UNLOCKED);
435                 break;
436         case NM_OC_RADIO_CARRIER:
437                 abis_nm_set_radio_attr(trx, nanobts_attr_radio,
438                                         sizeof(nanobts_attr_radio));
439                 abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER,
440                                 trx->bts->bts_nr, trx->nr, 0xff);
441                 abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
442                                       trx->bts->bts_nr, trx->nr, 0xff,
443                                       NM_STATE_UNLOCKED);
444                 break;
445         }
446         return 0;
447 }
448
449 /* Callback function for NACK on the OML NM */
450 static int oml_msg_nack(int mt)
451 {
452         if (mt == NM_MT_SET_BTS_ATTR_NACK) {
453                 fprintf(stderr, "Failed to set BTS attributes. That is fatal. "
454                                 "Was the bts type and frequency properly specified?\n");
455                 exit(-1);
456         }
457
458         return 0;
459 }
460
461 /* Callback function to be called every time we receive a signal from NM */
462 static int nm_sig_cb(unsigned int subsys, unsigned int signal,
463                      void *handler_data, void *signal_data)
464 {
465         switch (signal) {
466         case S_NM_SW_ACTIV_REP:
467                 return sw_activ_rep((struct msgb *)signal_data);
468         case S_NM_NACK:
469                 return oml_msg_nack((int)signal_data);
470         default:
471                 break;
472         }
473         return 0;
474 }
475
476 static void bootstrap_om_nanobts(struct gsm_bts *bts)
477 {
478         /* We don't do callback based bootstrapping, but event driven (see above) */
479 }
480
481 static void bootstrap_om_bs11(struct gsm_bts *bts)
482 {
483         struct gsm_bts_trx *trx = bts->c0;
484
485         /* stop sending event reports */
486         abis_nm_event_reports(bts, 0);
487
488         /* begin DB transmission */
489         abis_nm_bs11_db_transmission(bts, 1);
490
491         /* end DB transmission */
492         abis_nm_bs11_db_transmission(bts, 0);
493
494         /* Reset BTS Site manager resource */
495         abis_nm_bs11_reset_resource(bts);
496
497         /* begin DB transmission */
498         abis_nm_bs11_db_transmission(bts, 1);
499
500         abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
501         abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
502         abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
503         abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
504
505         /* Connect signalling of bts0/trx0 to e1_0/ts1/64kbps */
506         abis_nm_conn_terr_sign(trx, 0, 1, 0xff);
507         abis_nm_set_radio_attr(trx, bs11_attr_radio, sizeof(bs11_attr_radio));
508
509         /* Use TEI 1 for signalling */
510         abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x01);
511         abis_nm_set_channel_attr(&trx->ts[0], NM_CHANC_SDCCH_CBCH);
512
513 #ifdef HAVE_TRX1
514         /* TRX 1 */
515         abis_nm_conn_terr_sign(&bts->trx[1], 0, 1, 0xff);
516         /* FIXME: TRX ATTRIBUTE */
517         abis_nm_establish_tei(bts, 0, 0, 1, 0xff, 0x02);
518 #endif
519
520         /* SET CHANNEL ATTRIBUTE TS1 */
521         abis_nm_set_channel_attr(&trx->ts[1], NM_CHANC_TCHFull);
522         /* Connect traffic of bts0/trx0/ts1 to e1_0/ts2/b */
523         abis_nm_conn_terr_traf(&trx->ts[1], 0, 2, 1);
524         
525         /* SET CHANNEL ATTRIBUTE TS2 */
526         abis_nm_set_channel_attr(&trx->ts[2], NM_CHANC_TCHFull);
527         /* Connect traffic of bts0/trx0/ts2 to e1_0/ts2/c */
528         abis_nm_conn_terr_traf(&trx->ts[2], 0, 2, 2);
529
530         /* SET CHANNEL ATTRIBUTE TS3 */
531         abis_nm_set_channel_attr(&trx->ts[3], NM_CHANC_TCHFull);
532         /* Connect traffic of bts0/trx0/ts3 to e1_0/ts2/d */
533         abis_nm_conn_terr_traf(&trx->ts[3], 0, 2, 3);
534
535         /* SET CHANNEL ATTRIBUTE TS4 */
536         abis_nm_set_channel_attr(&trx->ts[4], NM_CHANC_TCHFull);
537         /* Connect traffic of bts0/trx0/ts4 to e1_0/ts3/a */
538         abis_nm_conn_terr_traf(&trx->ts[4], 0, 3, 0);
539
540         /* SET CHANNEL ATTRIBUTE TS5 */
541         abis_nm_set_channel_attr(&trx->ts[5], NM_CHANC_TCHFull);
542         /* Connect traffic of bts0/trx0/ts5 to e1_0/ts3/b */
543         abis_nm_conn_terr_traf(&trx->ts[5], 0, 3, 1);
544
545         /* SET CHANNEL ATTRIBUTE TS6 */
546         abis_nm_set_channel_attr(&trx->ts[6], NM_CHANC_TCHFull);
547         /* Connect traffic of bts0/trx0/ts6 to e1_0/ts3/c */
548         abis_nm_conn_terr_traf(&trx->ts[6], 0, 3, 2);
549
550         /* SET CHANNEL ATTRIBUTE TS7 */
551         abis_nm_set_channel_attr(&trx->ts[7], NM_CHANC_TCHFull);
552         /* Connect traffic of bts0/trx0/ts7 to e1_0/ts3/d */
553         abis_nm_conn_terr_traf(&trx->ts[7], 0, 3, 3);
554
555         /* end DB transmission */
556         abis_nm_bs11_db_transmission(bts, 0);
557
558         /* Reset BTS Site manager resource */
559         abis_nm_bs11_reset_resource(bts);
560
561         /* restart sending event reports */
562         abis_nm_event_reports(bts, 1);
563 }
564
565 static void bootstrap_om(struct gsm_bts *bts)
566 {
567         fprintf(stdout, "bootstrapping OML for BTS %u\n", bts->nr);
568
569         switch (bts->type) {
570         case GSM_BTS_TYPE_BS11:
571                 bootstrap_om_bs11(bts);
572                 break;
573         case GSM_BTS_TYPE_NANOBTS_900:
574         case GSM_BTS_TYPE_NANOBTS_1800:
575                 bootstrap_om_nanobts(bts);
576                 break;
577         default:
578                 fprintf(stderr, "Unable to bootstrap OML: Unknown BTS type %d\n", bts->type);
579         }
580 }
581
582 static int shutdown_om(struct gsm_bts *bts)
583 {
584         /* stop sending event reports */
585         abis_nm_event_reports(bts, 0);
586
587         /* begin DB transmission */
588         abis_nm_bs11_db_transmission(bts, 1);
589
590         /* end DB transmission */
591         abis_nm_bs11_db_transmission(bts, 0);
592
593         /* Reset BTS Site manager resource */
594         abis_nm_bs11_reset_resource(bts);
595
596         return 0;
597 }
598
599 int shutdown_net(struct gsm_network *net)
600 {
601         struct gsm_bts *bts;
602
603         llist_for_each_entry(bts, &net->bts_list, list) {
604                 int rc;
605                 rc = shutdown_om(bts);
606                 if (rc < 0)
607                         return rc;
608         }
609
610         return 0;
611 }
612
613 struct bcch_info {
614         u_int8_t type;
615         u_int8_t len;
616         const u_int8_t *data;
617 };
618
619 /*
620 SYSTEM INFORMATION TYPE 1
621   Cell channel description
622     Format-ID bit map 0
623     CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
624   RACH Control Parameters
625     maximum 7 retransmissions
626     8 slots used to spread transmission
627     cell not barred for access
628     call reestablishment not allowed
629     Access Control Class = 0000
630 */
631 static u_int8_t si1[] = {
632         /* header */0x55, 0x06, 0x19,
633         /* ccdesc */0x04 /*0x00*/, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*0x01*/,
635         /* rach */0xD5, 0x00, 0x00,
636         /* s1 reset*/0x2B
637 };
638
639 static u_int8_t *gsm48_si1(u_int8_t *arfcn_list, int arfcn_len, int max_trans, int tx_integer, int cell_barr, int re, int ec, u_int8_t *ac_list, int ac_len)
640 {
641         static u_int8_t si[23];
642         int i, bit, octet;
643
644         memset(&si, 0, sizeof(si));
645
646         /* header */
647         si[0] = 0x55;
648         si[1] = 0x06;
649         si[2] = 0x19;
650         /* ccdesc */
651         for (i = 0; i < arfcn_len; i++) {
652                 if (arfcn_list[i] <= 124 && arfcn_list[i] > 0) {
653                         bit = (arfcn_list[i] - 1) & 7;
654                         octet = (arfcn_list[i] -1) / 8;
655                         si[18 - octet] |= (1 << bit);
656                 }
657         }
658         /* rach */
659         si[19] = (max_trans << 6);
660         si[19] |= (tx_integer << 2);
661         si[19] |= (cell_barr << 1);
662         si[19] |= re;
663         si[20] = (ec << 2);
664         for (i = 0; i < ac_len; i++) {
665                 if (ac_list[i] <= 15 && ac_list[i] != 10) {
666                         bit = ac_list[i] & 7;
667                         octet = ac_list[i] / 8;
668                         si[21 - octet] |= (1 << bit);
669                 }
670         }
671         /* s1 rest */
672         si[22] = 0x2B;
673
674         /* testig */
675         if (memcmp(&si1, &si, sizeof(si)))
676                 printf("SI1 does not match default template.\n");
677
678         return si;
679 }
680
681 /*
682  SYSTEM INFORMATION TYPE 2
683   Neighbour Cells Description
684     EXT-IND: Carries the complete BA
685     BA-IND = 0
686     Format-ID bit map 0
687     CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
688   NCC permitted (NCC) = FF
689   RACH Control Parameters
690     maximum 7 retransmissions
691     8 slots used to spread transmission
692     cell not barred for access
693     call reestablishment not allowed
694     Access Control Class = 0000
695 */
696 static u_int8_t si2[] = {
697         /* header */0x59, 0x06, 0x1A,
698         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700         /* ncc */0xFF,
701         /* rach*/0xD5, 0x00, 0x00
702 };
703
704 static u_int8_t *gsm48_si2(int ba, u_int8_t *arfcn_list, int arfcn_len, u_int8_t ncc, int max_trans, int tx_integer, int cell_barr, int re, int ec, u_int8_t *ac_list, int ac_len)
705 {
706         static u_int8_t si[23];
707         int i, bit, octet;
708
709         memset(&si, 0, sizeof(si));
710
711         /* header */
712         si[0] = 0x59;
713         si[1] = 0x06;
714         si[2] = 0x1A;
715         /* ncdesc */
716         si[3] = (ba << 4);
717         for (i = 0; i < arfcn_len; i++) {
718                 if (arfcn_list[i] <= 124 && arfcn_list[i] > 0) {
719                         bit = (arfcn_list[i] - 1) & 7;
720                         octet = (arfcn_list[i] -1) / 8;
721                         si[18 - octet] |= (1 << bit);
722                 }
723         }
724         /* ncc */
725         si[19] = ncc;
726         /* rach */
727         si[20] = (max_trans << 6);
728         si[20] |= (tx_integer << 2);
729         si[20] |= (cell_barr << 1);
730         si[20] |= re;
731         si[21] = (ec << 2);
732         for (i = 0; i < ac_len; i++) {
733                 if (ac_list[i] <= 15 && ac_list[i] != 10) {
734                         bit = ac_list[i] & 7;
735                         octet = ac_list[i] / 8;
736                         si[22 - octet] |= (1 << bit);
737                 }
738         }
739
740         /* testig */
741         if (memcmp(&si2, &si, sizeof(si)))
742                 printf("SI2 does not match default template.\n");
743
744         return si;
745 }
746
747
748 /*
749 SYSTEM INFORMATION TYPE 3
750   Cell identity = 00001 (1h)
751   Location area identification
752     Mobile Country Code (MCC): 001
753     Mobile Network Code (MNC): 01
754     Location Area Code  (LAC): 00001 (1h)
755   Control Channel Description
756     Attach-detach: MSs in the cell are not allowed to apply IMSI attach /detach
757     0 blocks reserved for access grant
758     1 channel used for CCCH, with SDCCH
759     5 multiframes period for PAGING REQUEST
760     Time-out T3212 = 0
761   Cell Options BCCH
762     Power control indicator: not set
763     MSs shall not use uplink DTX
764     Radio link timeout = 36
765   Cell Selection Parameters
766     Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
767     max.TX power level MS may use for CCH = 2 <- according to GSM05.05 39dBm (max)
768     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
769     Half rate support (NECI): New establishment causes are not supported
770     min.RX signal level for MS = 0
771   RACH Control Parameters
772     maximum 7 retransmissions
773     8 slots used to spread transmission
774     cell not barred for access
775     call reestablishment not allowed
776     Access Control Class = 0000
777   SI 3 Rest Octets
778     Cell Bar Qualify (CBQ): 0
779     Cell Reselect Offset = 0 dB
780     Temporary Offset = 0 dB
781     Penalty Time = 20 s
782     System Information 2ter Indicator (2TI): 0 = not available
783     Early Classmark Sending Control (ECSC):  0 = forbidden
784     Scheduling Information is not sent in SYSTEM INFORMATION TYPE 9 on the BCCH
785 */
786 static u_int8_t si3[] = {
787         /* header */0x49, 0x06, 0x1B,
788         /* cell */0x00, 0x01,
789         /* lai  */0x00, 0xF1, 0x10, 0x00, 0x01,
790         /* desc */0x01, 0x03, 0x00,
791         /* option*/0x28,
792         /* selection*/0x62, 0x00,
793         /* rach */0xD5, 0x00, 0x00,
794         /* reset*/0x80, 0x00, 0x00, 0x2B
795 };
796
797 /*
798 SYSTEM INFORMATION TYPE 4
799   Location area identification
800     Mobile Country Code (MCC): 001
801     Mobile Network Code (MNC): 01
802     Location Area Code  (LAC): 00001 (1h)
803   Cell Selection Parameters
804     Cell reselect hysteresis = 6 dB RXLEV hysteresis for LA re-selection
805     max.TX power level MS may use for CCH = 2
806     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
807     Half rate support (NECI): New establishment causes are not supported
808     min.RX signal level for MS = 0
809   RACH Control Parameters
810     maximum 7 retransmissions
811     8 slots used to spread transmission
812     cell not barred for access
813     call reestablishment not allowed
814     Access Control Class = 0000
815   Channel Description
816     Type = SDCCH/4[2]
817     Timeslot Number: 0
818     Training Sequence Code: 7h
819     ARFCN: 1
820   SI Rest Octets
821     Cell Bar Qualify (CBQ): 0
822     Cell Reselect Offset = 0 dB
823     Temporary Offset = 0 dB
824     Penalty Time = 20 s
825 */
826 static u_int8_t si4[] = {
827         /* header */0x41, 0x06, 0x1C,
828         /* lai */0x00, 0xF1, 0x10, 0x00, 0x01,
829         /* sel */0x62, 0x00,
830         /* rach*/0xD5, 0x00, 0x00,
831         /* var */0x64, 0x30, 0xE0, HARDCODED_ARFCN/*0x01*/, 0x80, 0x00, 0x00,
832         0x2B, 0x2B, 0x2B
833 };
834
835 /*
836  SYSTEM INFORMATION TYPE 5
837   Neighbour Cells Description
838     EXT-IND: Carries the complete BA
839     BA-IND = 0
840     Format-ID bit map 0
841     CA-ARFCN Bit 124...001 (Hex): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
842 */
843
844 static u_int8_t si5[] = {
845         /* header without l2 len*/0x06, 0x1D,
846         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
847         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848 };
849
850 static u_int8_t *gsm48_si5(int ba, u_int8_t *arfcn_list, int arfcn_len)
851 {
852         static u_int8_t si[18];
853         int i, bit, octet;
854
855         memset(&si, 0, sizeof(si));
856
857         /* header */
858         si[0] = 0x06;
859         si[1] = 0x1D;
860         /* ncdesc */
861         si[2] = (ba << 4);
862         for (i = 0; i < arfcn_len; i++) {
863                 if (arfcn_list[i] <= 124 && arfcn_list[i] > 0) {
864                         bit = (arfcn_list[i] - 1) & 7;
865                         octet = (arfcn_list[i] -1) / 8;
866                         si[17 - octet] |= (1 << bit);
867                 }
868         }
869
870         /* testig */
871         if (memcmp(&si3, &si, sizeof(si)))
872                 printf("SI3 does not match default template.\n");
873
874         return si;
875 }
876
877
878 // SYSTEM INFORMATION TYPE 6
879
880 /*
881 SACCH FILLING
882   System Info Type: SYSTEM INFORMATION 6
883   L3 Information (Hex): 06 1E 00 01 xx xx 10 00 01 28 FF
884
885 SYSTEM INFORMATION TYPE 6
886   Cell identity = 00001 (1h)
887   Location area identification
888     Mobile Country Code (MCC): 001
889     Mobile Network Code (MNC): 01
890     Location Area Code  (LAC): 00001 (1h)
891   Cell Options SACCH
892     Power control indicator: not set
893     MSs shall not use uplink DTX on a TCH-F. MS shall not use uplink DTX on TCH-H.
894     Radio link timeout = 36
895   NCC permitted (NCC) = FF
896 */
897
898 static u_int8_t si6[] = {
899         /* header */0x06, 0x1E,
900         /* cell id*/ 0x00, 0x01,
901         /* lai */ 0x00, 0xF1, 0x10, 0x00, 0x01,
902         /* options */ 0x28,
903         /* ncc */ 0xFF,
904 };
905
906
907
908 static const struct bcch_info bcch_infos[] = {
909         {
910                 RSL_SYSTEM_INFO_1,
911                 sizeof(si1),
912                 si1,
913         }, {
914                 RSL_SYSTEM_INFO_2,
915                 sizeof(si2),
916                 si2,
917         }, {
918                 RSL_SYSTEM_INFO_3,
919                 sizeof(si3),
920                 si3,
921         }, {
922                 RSL_SYSTEM_INFO_4,
923                 sizeof(si4),
924                 si4,
925         },
926 };
927
928 static_assert(sizeof(si1) == sizeof(struct gsm48_system_information_type_1), type1)
929 static_assert(sizeof(si2) == sizeof(struct gsm48_system_information_type_2), type2)
930 static_assert(sizeof(si3) == sizeof(struct gsm48_system_information_type_3), type3)
931 static_assert(sizeof(si4) >= sizeof(struct gsm48_system_information_type_4), type4)
932 static_assert(sizeof(si5) == sizeof(struct gsm48_system_information_type_5), type5)
933 static_assert(sizeof(si6) >= sizeof(struct gsm48_system_information_type_6), type6)
934
935 /* set all system information types */
936 static int set_system_infos(struct gsm_bts_trx *trx)
937 {
938         unsigned int i;
939
940 #if 0
941         u_int8_t *_si1;
942         u_int8_t *_si2;
943         u_int8_t *_si5;
944         u_int8_t arfcn_list[8];
945
946         arfcn_list[0] = trx->arfcn;
947         _si1 = gsm48_si1(arfcn_list, 1, 3, 5, 0, 1, 0, NULL, 0);
948
949         memset(arfcn_list, 0, sizeof(arfcn_list));
950         arfcn_list[0] = trx->arfcn;
951         arfcn_list[1] = 112;
952         arfcn_list[2] = 62;
953         arfcn_list[3] = 99;
954         arfcn_list[4] = 77;
955         arfcn_list[5] = 64;
956         arfcn_list[6] = 54;
957         arfcn_list[7] = 51;
958         _si2 = gsm48_si2(0, arfcn_list, 8, 0xff, 3, 5, 0, 1, 0, NULL, 0);
959         _si5 = gsm48_si5(0, arfcn_list, 8);
960
961         rsl_bcch_info(trx, RSL_SYSTEM_INFO_1, _si1, 23);
962         rsl_bcch_info(trx, RSL_SYSTEM_INFO_2, _si2, 23);
963 //      rsl_bcch_info(trx, RSL_SYSTEM_INFO_3, _si3, );
964 //      rsl_bcch_info(trx, RSL_SYSTEM_INFO_4, _si4, );
965
966         for (i = 2; i < ARRAY_SIZE(bcch_infos); i++) {
967                 rsl_bcch_info(trx, bcch_infos[i].type,
968                               bcch_infos[i].data,
969                               bcch_infos[i].len);
970         }
971         rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, _si5, 18);
972         rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
973 #endif
974
975         for (i = 0; i < ARRAY_SIZE(bcch_infos); i++) {
976                 rsl_bcch_info(trx, bcch_infos[i].type,
977                               bcch_infos[i].data,
978                               bcch_infos[i].len);
979         }
980         rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si5, sizeof(si5));
981         rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si6, sizeof(si6));
982
983         return 0;
984 }
985
986 /*
987  * Patch the various SYSTEM INFORMATION tables to update
988  * the LAI
989  */
990 static void patch_tables(struct gsm_bts *bts)
991 {
992         u_int8_t arfcn_low = bts->c0->arfcn & 0xff;
993         u_int8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;
994         /* covert the raw packet to the struct */
995         struct gsm48_system_information_type_3 *type_3 =
996                 (struct gsm48_system_information_type_3*)&si3;
997         struct gsm48_system_information_type_4 *type_4 =
998                 (struct gsm48_system_information_type_4*)&si4;
999         struct gsm48_system_information_type_6 *type_6 =
1000                 (struct gsm48_system_information_type_6*)&si6;
1001         struct gsm48_loc_area_id lai;
1002
1003         gsm0408_generate_lai(&lai, bts->network->country_code,
1004                              bts->network->network_code,
1005                              bts->location_area_code);
1006
1007         /* assign the MCC and MNC */
1008         type_3->lai = lai;
1009         type_4->lai = lai;
1010         type_6->lai = lai;
1011
1012         /* patch ARFCN into BTS Attributes */
1013         bs11_attr_bts[69] &= 0xf0;
1014         bs11_attr_bts[69] |= arfcn_high;
1015         bs11_attr_bts[70] = arfcn_low;
1016         nanobts_attr_bts[42] &= 0xf0;
1017         nanobts_attr_bts[42] |= arfcn_high;
1018         nanobts_attr_bts[43] = arfcn_low;
1019
1020         /* patch ARFCN into TRX Attributes */
1021         bs11_attr_radio[2] &= 0xf0;
1022         bs11_attr_radio[2] |= arfcn_high;
1023         bs11_attr_radio[3] = arfcn_low;
1024         nanobts_attr_radio[5] &= 0xf0;
1025         nanobts_attr_radio[5] |= arfcn_high;
1026         nanobts_attr_radio[6] = arfcn_low;
1027
1028         type_4->data[2] &= 0xf0;
1029         type_4->data[2] |= arfcn_high;
1030         type_4->data[3] = arfcn_low;
1031
1032         /* patch Control Channel Description 10.5.2.11 */
1033         type_3->control_channel_desc = bts->chan_desc;
1034
1035         /* patch BSIC */
1036         bs11_attr_bts[1] = bts->bsic;
1037         nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
1038 }
1039
1040
1041 static void bootstrap_rsl(struct gsm_bts_trx *trx)
1042 {
1043         fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) "
1044                 "using MCC=%u MNC=%u\n", trx->nr, trx->bts->nr, trx->bts->network->country_code, trx->bts->network->network_code);
1045         set_system_infos(trx);
1046 }
1047
1048 void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
1049 {
1050         switch (event) {
1051         case EVT_E1_TEI_UP:
1052                 switch (type) {
1053                 case E1INP_SIGN_OML:
1054                         bootstrap_om(trx->bts);
1055                         break;
1056                 case E1INP_SIGN_RSL:
1057                         bootstrap_rsl(trx);
1058                         break;
1059                 default:
1060                         break;
1061                 }
1062                 break;
1063         case EVT_E1_TEI_DN:
1064                 fprintf(stderr, "Lost some E1 TEI link\n");
1065                 /* FIXME: deal with TEI or L1 link loss */
1066                 break;
1067         default:
1068                 break;
1069         }
1070 }
1071
1072 static int bootstrap_bts(struct gsm_bts *bts, int lac, int arfcn)
1073 {
1074         bts->band = BAND;
1075         bts->location_area_code = lac;
1076         bts->c0->arfcn = arfcn;
1077
1078         /* Control Channel Description */
1079         memset(&bts->chan_desc, 0, sizeof(struct gsm48_control_channel_descr));
1080         bts->chan_desc.att = 1;
1081         bts->chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
1082         bts->chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
1083         bts->chan_desc.t3212 = 0;
1084
1085         patch_tables(bts);
1086
1087         paging_init(bts);
1088
1089         if (bts->type == GSM_BTS_TYPE_BS11) {
1090                 struct gsm_bts_trx *trx = bts->c0;
1091                 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
1092                 set_ts_e1link(&trx->ts[1], 0, 2, 1);
1093                 set_ts_e1link(&trx->ts[2], 0, 2, 2);
1094                 set_ts_e1link(&trx->ts[3], 0, 2, 3);
1095                 set_ts_e1link(&trx->ts[4], 0, 3, 0);
1096                 set_ts_e1link(&trx->ts[5], 0, 3, 1);
1097                 set_ts_e1link(&trx->ts[6], 0, 3, 2);
1098                 set_ts_e1link(&trx->ts[7], 0, 3, 3);
1099 #ifdef HAVE_TRX1
1100                 /* TRX 1 */
1101                 trx = &bts->trx[1];
1102                 set_ts_e1link(&trx->ts[0], 0, 1, 0xff);
1103                 set_ts_e1link(&trx->ts[1], 0, 2, 1);
1104                 set_ts_e1link(&trx->ts[2], 0, 2, 2);
1105                 set_ts_e1link(&trx->ts[3], 0, 2, 3);
1106                 set_ts_e1link(&trx->ts[4], 0, 3, 0);
1107                 set_ts_e1link(&trx->ts[5], 0, 3, 1);
1108                 set_ts_e1link(&trx->ts[6], 0, 3, 2);
1109                 set_ts_e1link(&trx->ts[7], 0, 3, 3);
1110 #endif
1111         }
1112
1113         return 0;
1114 }
1115
1116 struct gsm_network *bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *), gsm_bts_type bts_type, int mcc, int mnc, int lac, int arfcn, int cardnr, int release_l2, char *name_short, char *name_long, char *database_name, int allow_all)
1117 {
1118         struct gsm_network *gsmnet;
1119         struct gsm_bts *bts;
1120
1121         switch(bts_type) {
1122         case GSM_BTS_TYPE_NANOBTS_1800:
1123                 if (arfcn < 512 || arfcn > 885) {
1124                         fprintf(stderr, "GSM1800 channel must be between 512-885.\n");
1125                         return NULL;
1126                 }
1127                 break;
1128         case GSM_BTS_TYPE_BS11:
1129         case GSM_BTS_TYPE_NANOBTS_900:
1130                 /* Assume we have a P-GSM900 here */
1131                 if (arfcn < 1 || arfcn > 124) {
1132                         fprintf(stderr, "GSM900 channel must be between 1-124.\n");
1133                         return NULL;
1134                 }
1135                 break;
1136         case GSM_BTS_TYPE_UNKNOWN:
1137                 fprintf(stderr, "Unknown BTS. Please use the --bts-type switch\n");
1138                 return NULL;
1139         }
1140
1141         /* initialize our data structures */
1142         gsmnet = gsm_network_init(mcc, mnc, mncc_recv);
1143         if (!gsmnet)
1144                 return NULL;
1145
1146         gsmnet->name_long = name_long;
1147         gsmnet->name_short = name_short;
1148
1149         bts = gsm_bts_alloc(gsmnet, bts_type, HARDCODED_TSC, HARDCODED_BSIC);
1150         bootstrap_bts(bts, lac, arfcn);
1151
1152         if (db_init(database_name)) {
1153                 printf("DB: Failed to init database. Please check the option settings.\n");
1154                 return NULL;
1155         }        
1156         printf("DB: Database initialized.\n");
1157
1158         if (db_prepare()) {
1159                 printf("DB: Failed to prepare database.\n");
1160                 return NULL;
1161         }
1162         printf("DB: Database prepared.\n");
1163
1164         telnet_init(gsmnet, 4242);
1165
1166         register_signal_handler(SS_NM, nm_sig_cb, NULL);
1167
1168         /* E1 mISDN input setup */
1169         if (bts_type == GSM_BTS_TYPE_BS11) {
1170                 gsmnet->num_bts = 1;
1171                 if (e1_config(bts, cardnr, release_l2))
1172                         return NULL;
1173         } else {
1174                 /* FIXME: do this dynamic */
1175                 bts->ip_access.site_id = 1801;
1176                 bts->ip_access.bts_id = 0;
1177
1178                 bts = gsm_bts_alloc(gsmnet, bts_type, HARDCODED_TSC, HARDCODED_BSIC);
1179                 bootstrap_bts(bts, lac, arfcn);
1180                 bts->ip_access.site_id = 1800;
1181                 bts->ip_access.bts_id = 0;
1182                 if (ipaccess_setup(gsmnet))
1183                         return NULL;
1184         }
1185
1186         if (allow_all)
1187                 gsm0408_allow_everyone(1);
1188
1189         return gsmnet;
1190 }
1191
1192 static void create_pcap_file(char *file)
1193 {
1194         mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1195         int fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, mode);
1196
1197         if (fd < 0) {
1198                 perror("Failed to open file for pcap");
1199                 return;
1200         }
1201
1202         e1_set_pcap_fd(fd);
1203 }
1204
1205 #ifdef __cplusplus
1206 }
1207 #endif