blob: 89375cf42b7a53133edff31d6b9b74b6f347bec0 [file] [log] [blame]
Harald Welte6be350c2011-05-25 13:10:08 +02001#ifndef _GSM_DATA_SHAREDH
2#define _GSM_DATA_SHAREDH
3
4#include <stdbool.h>
5#include <stdint.h>
6
7#include <osmocom/core/timer.h>
8#include <osmocom/core/bitvec.h>
9#include <osmocom/core/statistics.h>
10#include <osmocom/core/utils.h>
11#include <osmocom/gsm/gsm_utils.h>
12#include <osmocom/gsm/tlv.h>
13#include <osmocom/gsm/rxlev_stat.h>
14#include <osmocom/gsm/sysinfo.h>
15
16#include <osmocom/gsm/protocol/gsm_08_58.h>
Harald Welte3300c012011-06-05 13:31:33 +020017#include <osmocom/gsm/protocol/gsm_12_21.h>
Harald Welte6be350c2011-05-25 13:10:08 +020018
19struct osmo_msc_data;
20struct osmo_bsc_sccp_con;
21struct gsm_sms_queue;
22
23/* RRLP mode of operation */
24enum rrlp_mode {
25 RRLP_MODE_NONE,
26 RRLP_MODE_MS_BASED,
27 RRLP_MODE_MS_PREF,
28 RRLP_MODE_ASS_PREF,
29};
30
31/* Channel Request reason */
32enum gsm_chreq_reason_t {
33 GSM_CHREQ_REASON_EMERG,
34 GSM_CHREQ_REASON_PAG,
35 GSM_CHREQ_REASON_CALL,
36 GSM_CHREQ_REASON_LOCATION_UPD,
37 GSM_CHREQ_REASON_OTHER,
38};
39
40#define TRX_NR_TS 8
41#define TS_MAX_LCHAN 8
42
43#define HARDCODED_ARFCN 123
44#define HARDCODED_TSC 7
45#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */
46
47/* for multi-drop config */
48#define HARDCODED_BTS0_TS 1
49#define HARDCODED_BTS1_TS 6
50#define HARDCODED_BTS2_TS 11
51
52/* reserved according to GSM 03.03 ยง 2.4 */
53#define GSM_RESERVED_TMSI 0xFFFFFFFF
54
55enum gsm_hooks {
56 GSM_HOOK_NM_SWLOAD,
57 GSM_HOOK_RR_PAGING,
58 GSM_HOOK_RR_SECURITY,
59};
60
61enum gsm_paging_event {
62 GSM_PAGING_SUCCEEDED,
63 GSM_PAGING_EXPIRED,
64 GSM_PAGING_OOM,
65 GSM_PAGING_BUSY,
66};
67
68enum bts_gprs_mode {
69 BTS_GPRS_NONE = 0,
70 BTS_GPRS_GPRS = 1,
71 BTS_GPRS_EGPRS = 2,
72};
73
74struct gsm_lchan;
75struct gsm_subscriber;
76struct gsm_mncc;
77struct rtp_socket;
78struct bsc_api;
79
80/* Network Management State */
81struct gsm_nm_state {
82 uint8_t operational;
83 uint8_t administrative;
84 uint8_t availability;
85};
86
Harald Welted64c0bc2011-05-30 12:07:53 +020087struct gsm_abis_mo {
Harald Welte3300c012011-06-05 13:31:33 +020088 uint8_t obj_class;
89 struct abis_om_obj_inst obj_inst;
Harald Welted64c0bc2011-05-30 12:07:53 +020090 const char *name;
91 struct gsm_nm_state nm_state;
92 struct tlv_parsed *nm_attr;
Harald Welte32bc1162011-06-06 18:58:48 +020093 struct gsm_bts *bts;
Harald Welted64c0bc2011-05-30 12:07:53 +020094};
95
Harald Welte6be350c2011-05-25 13:10:08 +020096#define MAX_A5_KEY_LEN (128/8)
97#define A38_XOR_MIN_KEY_LEN 12
98#define A38_XOR_MAX_KEY_LEN 16
99#define A38_COMP128_KEY_LEN 16
100#define RSL_ENC_ALG_A5(x) (x+1)
101
102/* is the data link established? who established it? */
103#define LCHAN_SAPI_UNUSED 0
104#define LCHAN_SAPI_MS 1
105#define LCHAN_SAPI_NET 2
106
107/* state of a logical channel */
108enum gsm_lchan_state {
109 LCHAN_S_NONE, /* channel is not active */
110 LCHAN_S_ACT_REQ, /* channel activatin requested */
111 LCHAN_S_ACTIVE, /* channel is active and operational */
112 LCHAN_S_REL_REQ, /* channel release has been requested */
113 LCHAN_S_REL_ERR, /* channel is in an error state */
114 LCHAN_S_INACTIVE, /* channel is set inactive */
115};
116
Harald Weltec7921c92011-06-29 10:38:34 +0200117/* BTS ONLY */
118#define MAX_NUM_UL_MEAS 104
119#define LC_UL_M_F_L1_VALID (1 << 0)
120#define LC_UL_M_F_RES_VALID (1 << 1)
121
122struct bts_ul_meas {
123 /* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */
124 uint16_t ber10k;
125 /* timing advance offset (in quarter bits) */
126 int16_t ta_offs_qbits;
127 /* C/I ratio in dB */
128 float c_i;
129 /* flags */
130 uint8_t is_sub:1;
131 /* RSSI in dBm * -1 */
132 uint8_t inv_rssi;
133};
134/* /BTS ONLY */
135
Harald Welte6be350c2011-05-25 13:10:08 +0200136struct gsm_lchan {
137 /* The TS that we're part of */
138 struct gsm_bts_trx_ts *ts;
139 /* The logical subslot number in the TS */
140 uint8_t nr;
141 /* The logical channel type */
142 enum gsm_chan_t type;
143 /* RSL channel mode */
144 enum rsl_cmod_spd rsl_cmode;
145 /* If TCH, traffic channel mode */
146 enum gsm48_chan_mode tch_mode;
147 /* State */
148 enum gsm_lchan_state state;
149 /* Power levels for MS and BTS */
150 uint8_t bs_power;
151 uint8_t ms_power;
152 /* Encryption information */
153 struct {
154 uint8_t alg_id;
155 uint8_t key_len;
156 uint8_t key[MAX_A5_KEY_LEN];
157 } encr;
158
159 /* AMR bits */
160 struct gsm48_multi_rate_conf mr_conf;
161
162 /* Established data link layer services */
163 uint8_t sapis[8];
164 int sach_deact;
165 int release_reason;
166
167 struct {
168 uint32_t bound_ip;
169 uint32_t connect_ip;
170 uint16_t bound_port;
171 uint16_t connect_port;
172 uint16_t conn_id;
173 uint8_t rtp_payload;
174 uint8_t rtp_payload2;
175 uint8_t speech_mode;
176 struct rtp_socket *rtp_socket;
177 } abis_ip;
178
Harald Welte2c1ae472011-06-26 14:13:37 +0200179 uint8_t rqd_ta;
180
Harald Welte6be350c2011-05-25 13:10:08 +0200181#ifdef ROLE_BSC
182 struct osmo_timer_list T3101;
183 struct osmo_timer_list T3111;
184 struct osmo_timer_list error_timer;
Harald Weltee8bd9e82011-08-10 23:26:33 +0200185 struct osmo_timer_list act_timer;
Harald Welte6be350c2011-05-25 13:10:08 +0200186
187 /* table of neighbor cell measurements */
188 struct neigh_meas_proc neigh_meas[MAX_NEIGH_MEAS];
189
190 /* cache of last measurement reports on this lchan */
191 struct gsm_meas_rep meas_rep[6];
192 int meas_rep_idx;
193
194 /* GSM Random Access data */
195 struct gsm48_req_ref *rqd_ref;
Harald Welte6be350c2011-05-25 13:10:08 +0200196
197 struct gsm_subscriber_connection *conn;
Harald Weltef6093a42011-06-25 10:02:33 +0200198#else
199 struct lapdm_channel lapdm_ch;
Harald Welte2c1ae472011-06-26 14:13:37 +0200200 struct {
201 /* bitmask of all SI that are present/valid in si_buf */
202 uint32_t valid;
203 uint32_t last;
204 /* buffers where we put the pre-computed SI */
205 sysinfo_buf_t buf[_MAX_SYSINFO_TYPE];
206 } si;
Harald Weltec7921c92011-06-29 10:38:34 +0200207 struct {
208 uint8_t flags;
209 /* RSL measurment result number, 0 at lchan_act */
210 uint8_t res_nr;
211 /* current Tx power level of the BTS */
212 uint8_t bts_tx_pwr;
213 /* number of measurements stored in array below */
214 uint8_t num_ul_meas;
215 struct bts_ul_meas uplink[MAX_NUM_UL_MEAS];
216 /* last L1 header from the MS */
217 uint8_t l1_info[2];
218 struct {
219 uint8_t rxlev_full;
220 uint8_t rxlev_sub;
221 uint8_t rxqual_full;
222 uint8_t rxqual_sub;
223 } res;
224 } meas;
Harald Welte6be350c2011-05-25 13:10:08 +0200225#endif
226};
227
Harald Weltec7921c92011-06-29 10:38:34 +0200228
Harald Welte6be350c2011-05-25 13:10:08 +0200229struct gsm_e1_subslot {
230 /* Number of E1 link */
231 uint8_t e1_nr;
232 /* Number of E1 TS inside E1 link */
233 uint8_t e1_ts;
234 /* Sub-slot within the E1 TS, 0xff if full TS */
235 uint8_t e1_ts_ss;
236};
237
238#define TS_F_PDCH_MODE 0x1000
239/* One Timeslot in a TRX */
240struct gsm_bts_trx_ts {
241 struct gsm_bts_trx *trx;
242 /* number of this timeslot at the TRX */
243 uint8_t nr;
244
245 enum gsm_phys_chan_config pchan;
246
247 unsigned int flags;
Harald Welted64c0bc2011-05-30 12:07:53 +0200248 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200249 struct tlv_parsed nm_attr;
250 uint8_t nm_chan_comb;
Harald Welte135a6482011-05-30 12:09:13 +0200251 int tsc; /* -1 == use BTS TSC */
Harald Welte6be350c2011-05-25 13:10:08 +0200252
253 struct {
254 /* Parameters below are configured by VTY */
255 int enabled;
256 uint8_t maio;
257 uint8_t hsn;
258 struct bitvec arfcns;
259 uint8_t arfcns_data[1024/8];
260 /* This is the pre-computed MA for channel assignments */
261 struct bitvec ma;
262 uint8_t ma_len; /* part of ma_data that is used */
263 uint8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
264 } hopping;
265
266 /* To which E1 subslot are we connected */
267 struct gsm_e1_subslot e1_link;
268
269 struct gsm_lchan lchan[TS_MAX_LCHAN];
270};
271
272/* One TRX in a BTS */
273struct gsm_bts_trx {
274 /* list header in bts->trx_list */
275 struct llist_head list;
276
277 struct gsm_bts *bts;
278 /* number of this TRX in the BTS */
279 uint8_t nr;
280 /* human readable name / description */
281 char *description;
282 /* how do we talk RSL with this TRX? */
283 struct gsm_e1_subslot rsl_e1_link;
284 uint8_t rsl_tei;
285 struct e1inp_sign_link *rsl_link;
286 /* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */
287 struct e1inp_sign_link *oml_link;
288
Harald Welted64c0bc2011-05-30 12:07:53 +0200289 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200290 struct tlv_parsed nm_attr;
291 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200292 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200293 } bb_transc;
294
295 uint16_t arfcn;
296 int nominal_power; /* in dBm */
297 unsigned int max_power_red; /* in actual dB */
298
Harald Welted134cc72011-06-07 00:12:53 +0200299 struct {
300 void *l1h;
301 } role_bts;
302
Harald Welte6be350c2011-05-25 13:10:08 +0200303 union {
304 struct {
305 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200306 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200307 } bbsig;
308 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200309 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200310 } pa;
311 } bs11;
312 struct {
313 unsigned int test_state;
314 uint8_t test_nr;
315 struct rxlev_stats rxlev_stat;
316 } ipaccess;
317 };
318 struct gsm_bts_trx_ts ts[TRX_NR_TS];
319};
320
321#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i])
322
323enum gsm_bts_type {
324 GSM_BTS_TYPE_UNKNOWN,
325 GSM_BTS_TYPE_BS11,
326 GSM_BTS_TYPE_NANOBTS,
327 GSM_BTS_TYPE_RBS2000,
328 GSM_BTS_TYPE_HSL_FEMTO,
Dieter Spaar16646022011-07-28 00:01:50 +0200329 GSM_BTS_TYPE_NOKIA_SITE,
Harald Welte6be350c2011-05-25 13:10:08 +0200330};
331
332struct vty;
333
334struct gsm_bts_model {
335 struct llist_head list;
336
337 enum gsm_bts_type type;
338 const char *name;
339
340 bool started;
341 int (*start)(struct gsm_network *net);
342 int (*oml_rcvmsg)(struct msgb *msg);
343
344 void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
345 void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
346 void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);
347
348 struct tlv_definition nm_att_tlvdef;
349
350 struct bitvec features;
351 uint8_t _features_data[128/8];
352};
353
354enum gsm_bts_features {
355 BTS_FEAT_HSCSD,
356 BTS_FEAT_GPRS,
357 BTS_FEAT_EGPRS,
358 BTS_FEAT_ECSD,
359 BTS_FEAT_HOPPING,
360};
361
362/*
363 * This keeps track of the paging status of one BTS. It
364 * includes a number of pending requests, a back pointer
365 * to the gsm_bts, a timer and some more state.
366 */
367struct gsm_bts_paging_state {
368 /* pending requests */
369 struct llist_head pending_requests;
370 struct gsm_bts *bts;
371
372 struct osmo_timer_list work_timer;
373 struct osmo_timer_list credit_timer;
374
375 /* free chans needed */
376 int free_chans_need;
377
378 /* load */
379 uint16_t available_slots;
380};
381
382struct gsm_envabtse {
Harald Welted64c0bc2011-05-30 12:07:53 +0200383 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200384};
385
386struct gsm_bts_gprs_nsvc {
387 struct gsm_bts *bts;
388 /* data read via VTY config file, to configure the BTS
389 * via OML from BSC */
390 int id;
391 uint16_t nsvci;
392 uint16_t local_port; /* on the BTS */
393 uint16_t remote_port; /* on the SGSN */
394 uint32_t remote_ip; /* on the SGSN */
395
Harald Welted64c0bc2011-05-30 12:07:53 +0200396 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200397};
398
399enum neigh_list_manual_mode {
400 NL_MODE_AUTOMATIC = 0,
401 NL_MODE_MANUAL = 1,
402 NL_MODE_MANUAL_SI5SEP = 2, /* SI2 and SI5 have separate neighbor lists */
403};
404
405/* One BTS */
406struct gsm_bts {
407 /* list header in net->bts_list */
408 struct llist_head list;
409
410 /* number of ths BTS in network */
411 uint8_t nr;
412 /* human readable name / description */
413 char *description;
414 /* Cell Identity */
415 uint16_t cell_identity;
416 /* location area code of this BTS */
417 uint16_t location_area_code;
418 /* Training Sequence Code */
419 uint8_t tsc;
420 /* Base Station Identification Code (BSIC) */
421 uint8_t bsic;
422 /* type of BTS */
423 enum gsm_bts_type type;
424 struct gsm_bts_model *model;
425 enum gsm_band band;
426 /* maximum Tx power that the MS is permitted to use in this cell */
427 int ms_max_power;
428
429 /* how do we talk OML with this TRX? */
430 struct gsm_e1_subslot oml_e1_link;
431 uint8_t oml_tei;
432 struct e1inp_sign_link *oml_link;
433
434 /* Abis network management O&M handle */
435 struct abis_nm_h *nmh;
Harald Welted64c0bc2011-05-30 12:07:53 +0200436
437 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200438
439 /* number of this BTS on given E1 link */
440 uint8_t bts_nr;
441
442 /* paging state and control */
443 struct gsm_bts_paging_state paging;
444
445 /* CCCH is on C0 */
446 struct gsm_bts_trx *c0;
447
448 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200449 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200450 } site_mgr;
451
452 /* bitmask of all SI that are present/valid in si_buf */
453 uint32_t si_valid;
454 /* buffers where we put the pre-computed SI */
455 sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
456
457 /* ip.accesss Unit ID's have Site/BTS/TRX layout */
458 union {
459 struct {
460 uint16_t site_id;
461 uint16_t bts_id;
462 uint32_t flags;
463 } ip_access;
464 struct {
465 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200466 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200467 } cclk;
468 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200469 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200470 } rack;
471 struct gsm_envabtse envabtse[4];
472 } bs11;
473 struct {
474 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200475 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200476 struct llist_head conn_groups;
477 } is;
478 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200479 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200480 struct llist_head conn_groups;
481 } con;
482 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200483 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200484 } dp;
485 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200486 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200487 } tf;
488 } rbs2000;
489 struct {
490 unsigned long serno;
491 } hsl;
Harald Weltec8755af2011-07-28 00:22:17 +0200492 struct {
493 uint8_t bts_type;
494 int configured:1,
495 do_reset:1,
496 wait_reset:1;
497 struct osmo_timer_list reset_timer;
498 } nokia;
Harald Welte6be350c2011-05-25 13:10:08 +0200499 };
500
501 /* Not entirely sure how ip.access specific this is */
502 struct {
503 enum bts_gprs_mode mode;
504 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200505 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200506 uint16_t nsei;
507 uint8_t timer[7];
508 } nse;
509 struct {
Harald Welted64c0bc2011-05-30 12:07:53 +0200510 struct gsm_abis_mo mo;
Harald Welte6be350c2011-05-25 13:10:08 +0200511 uint16_t bvci;
512 uint8_t timer[11];
513 } cell;
514 struct gsm_bts_gprs_nsvc nsvc[2];
515 uint8_t rac;
516 } gprs;
517
518 /* RACH NM values */
519 int rach_b_thresh;
520 int rach_ldavg_slots;
521
522 /* transceivers */
523 int num_trx;
524 struct llist_head trx_list;
525
526#ifdef ROLE_BSC
527 /* Abis NM queue */
528 struct llist_head abis_queue;
529 int abis_nm_pend;
530
531 struct gsm_network *network;
532
533 /* should the channel allocator allocate channels from high TRX to TRX0,
534 * rather than starting from TRX0 and go upwards? */
535 int chan_alloc_reverse;
536
537 enum neigh_list_manual_mode neigh_list_manual_mode;
538 /* parameters from which we build SYSTEM INFORMATION */
539 struct {
540 struct gsm48_rach_control rach_control;
541 uint8_t ncc_permitted;
542 struct gsm48_cell_sel_par cell_sel_par;
543 struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */
544 struct gsm48_cell_options cell_options;
545 struct gsm48_control_channel_descr chan_desc;
546 struct bitvec neigh_list;
547 struct bitvec cell_alloc;
548 struct bitvec si5_neigh_list;
549 struct {
550 /* bitmask large enough for all possible ARFCN's */
551 uint8_t neigh_list[1024/8];
552 uint8_t cell_alloc[1024/8];
553 /* If the user wants a different neighbor list in SI5 than in SI2 */
554 uint8_t si5_neigh_list[1024/8];
555 } data;
556 } si_common;
557
558 /* do we use static (user-defined) system information messages? (bitmask) */
559 uint32_t si_mode_static;
560#endif /* ROLE_BSC */
Harald Welte978714d2011-06-06 18:31:20 +0200561 void *role;
Harald Welte6be350c2011-05-25 13:10:08 +0200562};
563
564
Harald Welte3300c012011-06-05 13:31:33 +0200565struct gsm_bts *gsm_bts_alloc(void *talloc_ctx);
Harald Welte6be350c2011-05-25 13:10:08 +0200566struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
567
568struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
Harald Welte6be350c2011-05-25 13:10:08 +0200569
570const char *gsm_pchan_name(enum gsm_phys_chan_config c);
571enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
572const char *gsm_lchant_name(enum gsm_chan_t c);
573const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
574char *gsm_trx_name(struct gsm_bts_trx *trx);
575char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
576char *gsm_lchan_name(struct gsm_lchan *lchan);
577const char *gsm_lchans_name(enum gsm_lchan_state s);
578
Harald Welte6be350c2011-05-25 13:10:08 +0200579
Harald Welteb7849982011-06-29 16:49:03 +0200580void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
581
Harald Welte978714d2011-06-06 18:31:20 +0200582struct gsm_abis_mo *
583gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
584 struct abis_om_obj_inst *obj_inst);
585
586struct gsm_nm_state *
587gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
588 struct abis_om_obj_inst *obj_inst);
589void *
590gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
591 struct abis_om_obj_inst *obj_inst);
592
Harald Welteb7849982011-06-29 16:49:03 +0200593/* reset the state of all MO in the BTS */
594void gsm_bts_mo_reset(struct gsm_bts *bts);
595
Harald Weltef6093a42011-06-25 10:02:33 +0200596uint8_t gsm_ts2chan_nr(const struct gsm_bts_trx_ts *ts, uint8_t lchan_nr);
597uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan);
598
Harald Welte6be350c2011-05-25 13:10:08 +0200599#endif