aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/include
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-12-22 07:58:24 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-12-22 08:02:13 +0100
commit5c18ad08293ae6f95edd75e6bcc370fd6cff069b (patch)
tree120273d6da84a0bdb52b32f981714e9bcaea0f59 /openbsc/include
parent0d9ed87d5c7d5b6e21dc3bbb282e215068742566 (diff)
parent4f5456c040c2dd0c53fe28cb51219d668d464a21 (diff)
Merge commit 'origin/master' into on-waves/bsc-master
Conflicts: openbsc/include/openbsc/Makefile.am openbsc/include/openbsc/gsm_data.h openbsc/src/Makefile.am openbsc/src/abis_rsl.c openbsc/src/chan_alloc.c openbsc/src/gsm_04_08.c openbsc/src/gsm_data.c openbsc/src/vty_interface.c The biggest problem is the moving of the RTP code into the RSL layer. This may break quite some things...
Diffstat (limited to 'openbsc/include')
-rw-r--r--openbsc/include/openbsc/Makefile.am3
-rw-r--r--openbsc/include/openbsc/abis_rsl.h8
-rw-r--r--openbsc/include/openbsc/bitvec.h65
-rw-r--r--openbsc/include/openbsc/call_handling.h64
-rw-r--r--openbsc/include/openbsc/debug.h13
-rw-r--r--openbsc/include/openbsc/gsm_04_08.h70
-rw-r--r--openbsc/include/openbsc/gsm_data.h142
-rw-r--r--openbsc/include/openbsc/gsm_utils.h4
-rw-r--r--openbsc/include/openbsc/handover.h8
-rw-r--r--openbsc/include/openbsc/meas_rep.h84
-rw-r--r--openbsc/include/openbsc/mncc.h13
-rw-r--r--openbsc/include/openbsc/rest_octets.h122
-rw-r--r--openbsc/include/openbsc/rtp_proxy.h17
-rw-r--r--openbsc/include/openbsc/signal.h13
-rw-r--r--openbsc/include/openbsc/system_information.h6
-rw-r--r--openbsc/include/openbsc/tlv.h1
-rw-r--r--openbsc/include/openbsc/transaction.h8
-rw-r--r--openbsc/include/openbsc/trau_mux.h2
18 files changed, 536 insertions, 107 deletions
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index 9f9928c90..8c9cd2e48 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -4,4 +4,5 @@ noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \
subchan_demux.h trau_frame.h e1_input.h trau_mux.h signal.h \
gsm_utils.h ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
bsc_rll.h mncc.h talloc.h transaction.h ussd.h gsm_04_80.h \
- silent_call.h mgcp.h bssap.h
+ silent_call.h mgcp.h meas_rep.h bitvec.h rest_octets.h \
+ system_information.h handover.h bssap.h
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index a911be355..797b2f349 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -497,7 +497,7 @@ int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
u_int8_t bs_power, u_int8_t ms_power,
u_int8_t ta);
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
- u_int8_t ta);
+ u_int8_t ta, u_int8_t ho_ref);
int rsl_chan_mode_modify_req(struct gsm_lchan *ts);
int rsl_encryption_cmd(struct msgb *msg);
int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len,
@@ -537,8 +537,8 @@ int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
/* ip.access specfic RSL extensions */
int rsl_ipacc_crcx(struct gsm_lchan *lchan);
int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip,
- u_int16_t port, u_int16_t conn_id,
- u_int8_t rtp_payload2);
+ u_int16_t port, u_int8_t rtp_payload2);
+int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan);
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan);
int abis_rsl_rcvmsg(struct msgb *msg);
@@ -547,7 +547,7 @@ unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
int n_pag_blocks);
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
u_int64_t str_to_imsi(const char *imsi_str);
-u_int8_t lchan2chan_nr(struct gsm_lchan *lchan);
+u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id);
/* to be provided by external code */
diff --git a/openbsc/include/openbsc/bitvec.h b/openbsc/include/openbsc/bitvec.h
new file mode 100644
index 000000000..b35aebf16
--- /dev/null
+++ b/openbsc/include/openbsc/bitvec.h
@@ -0,0 +1,65 @@
+#ifndef _BITVEC_H
+#define _BITVEC_H
+
+/* bit vector utility routines */
+
+/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+/* In GSM mac blocks, every bit can be 0 or 1, or L or H. L/H are
+ * defined relative to the 0x2b padding pattern */
+enum bit_value {
+ ZERO = 0,
+ ONE = 1,
+ L = 2,
+ H = 3,
+};
+
+struct bitvec {
+ unsigned int cur_bit; /* curser to the next unused bit */
+ unsigned int data_len; /* length of data array in bytes */
+ u_int8_t *data; /* pointer to data array */
+};
+
+/* check if the bit is 0 or 1 for a given position inside a bitvec */
+enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr);
+
+/* get the Nth set bit inside the bit vector */
+unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n);
+
+/* Set a bit at given position */
+int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
+ enum bit_value bit);
+
+/* Set the next bit in the vector */
+int bitvec_set_bit(struct bitvec *bv, enum bit_value bit);
+
+/* Set multiple bits at the current position */
+int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count);
+
+/* Add an unsigned integer (of length count bits) to current position */
+int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count);
+
+
+/* Pad the bit vector up to a certain bit position */
+int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit);
+
+#endif /* _BITVEC_H */
diff --git a/openbsc/include/openbsc/call_handling.h b/openbsc/include/openbsc/call_handling.h
deleted file mode 100644
index 02027889e..000000000
--- a/openbsc/include/openbsc/call_handling.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2008 by Stefan Schmidt <stefan@datenfreihafen.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _CALL_HANDLING_H
-#define _CALL_HANDLING_H
-
-#include "linuxlist.h"
-#include "gsm_subscriber.h"
-#include "timer.h"
-
-/*
- * State transitions to be seen from the outside
- */
-#define CALL_STATE_NULL 0
-#define CALL_STATE_SETUP 1
-#define CALL_STATE_PROCEED 2
-#define CALL_STATE_ALERT 3
-#define CALL_STATE_CONNECT 4
-#define CALL_STATE_ACTIVE 5
-#define CALL_STATE_RELEASE 6
-
-struct call_data {
- struct llist_head entry;
- void (*state_change_cb)(int oldstate, int newstate, int event, void *data);
- void *data;
- char *destination_number;
-
- /* Internal */
- int state;
- char tmsi[GSM_TMSI_LENGTH];
- struct timer_list t30x; /* to be added for... */
-};
-
-
-int call_initiate(struct call_data *call, char *tmsi);
-void call_abort(struct call_data *call);
-
-/**
- * Get notified about new incoming calls. The call_data is owned
- * and managed by the internal call handling.
- */
-void call_set_callback(void (*cb)(struct call_data *call, void *data), void* data);
-void call_proceed(struct call_data *call_data);
-void call_connect(struct call_data *call_data);
-
-#endif /* _CALL_HANDLING_H */
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index 447c3584f..fc387cec3 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -25,6 +25,8 @@
#define DMGCP 0x40000
+#define DHO 0x80000
+
#ifdef DEBUG
#define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args)
#define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args)
@@ -42,4 +44,15 @@ void debug_use_color(int use_color);
void debug_timestamp(int enable);
extern unsigned int debug_mask;
+/* new logging interface */
+#define LOGP(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ##args)
+#define LOGPC(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ##args)
+
+/* different levels */
+#define LOGL_DEBUG 1 /* debugging information */
+#define LOGL_INFO 3
+#define LOGL_NOTICE 5 /* abnormal/unexpected condition */
+#define LOGL_ERROR 7 /* error condition, requires user action */
+#define LOGL_FATAL 8 /* fatal, program aborted */
+
#endif /* _DEBUG_H */
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index b7c8a2662..b8671554e 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -1,6 +1,8 @@
#ifndef _GSM_04_08_H
#define _GSM_04_08_H
+#include <openbsc/meas_rep.h>
+
/* GSM TS 04.08 definitions */
struct gsm_lchan;
@@ -88,6 +90,22 @@ struct gsm48_ass_cmd {
u_int8_t data[0];
} __attribute__((packed));
+/* Chapter 10.5.2.2 */
+struct gsm48_cell_desc {
+ u_int8_t bcc:3,
+ ncc:3,
+ arfcn_hi:2;
+ u_int8_t arfcn_lo;
+} __attribute__((packed));
+
+/* Chapter 9.1.15 */
+struct gsm48_ho_cmd {
+ struct gsm48_cell_desc cell_desc;
+ struct gsm48_chan_desc chan_desc;
+ u_int8_t ho_ref;
+ u_int8_t power_command;
+ u_int8_t data[0];
+} __attribute__((packed));
/* Chapter 9.1.18 */
struct gsm48_imm_ass {
@@ -169,6 +187,13 @@ struct gsm48_control_channel_descr {
u_int8_t t3212;
} __attribute__ ((packed));
+struct gsm48_cell_options {
+ u_int8_t radio_link_timeout:4,
+ dtx:2,
+ pwrc:1,
+ spare:1;
+} __attribute__ ((packed));
+
/* Section 9.2.9 CM service request */
struct gsm48_service_request {
u_int8_t cm_service_type : 4,
@@ -185,7 +210,7 @@ struct gsm48_system_information_type_1 {
struct gsm48_system_information_type_header header;
u_int8_t cell_channel_description[16];
struct gsm48_rach_control rach_control;
- u_int8_t s1_reset;
+ u_int8_t rest_octets[0]; /* NCH position on the CCCH */
} __attribute__ ((packed));
/* Section 9.1.32 System information Type 2 */
@@ -202,10 +227,10 @@ struct gsm48_system_information_type_3 {
u_int16_t cell_identity;
struct gsm48_loc_area_id lai;
struct gsm48_control_channel_descr control_channel_desc;
- u_int8_t cell_options;
+ struct gsm48_cell_options cell_options;
struct gsm48_cell_sel_par cell_sel_par;
struct gsm48_rach_control rach_control;
- u_int8_t s3_reset_octets[4];
+ u_int8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.1.36 System information Type 4 */
@@ -235,9 +260,15 @@ struct gsm48_system_information_type_6 {
u_int8_t system_information;
u_int16_t cell_identity;
struct gsm48_loc_area_id lai;
- u_int8_t cell_options;
+ struct gsm48_cell_options cell_options;
u_int8_t ncc_permitted;
- u_int8_t si_6_reset[0];
+ u_int8_t rest_octets[0];
+} __attribute__ ((packed));
+
+/* Section 9.1.43a System Information type 13 */
+struct gsm48_system_information_type_13 {
+ struct gsm48_system_information_type_header header;
+ u_int8_t rest_octets[0];
} __attribute__ ((packed));
/* Section 9.2.12 IMSI Detach Indication */
@@ -618,30 +649,6 @@ enum gsm48_reject_value {
GSM48_REJECT_MSC_TMP_NOT_REACHABLE = 16,
};
-
-/* extracted from a L3 measurement report IE */
-struct gsm_meas_rep_cell {
- u_int8_t rxlev;
- u_int8_t bcch_freq; /* fixme: translate to ARFCN */
- u_int8_t bsic;
-};
-
-struct gsm_meas_rep {
- unsigned int flags;
- u_int8_t rxlev_full;
- u_int8_t rxqual_full;
- u_int8_t rxlev_sub;
- u_int8_t rxqual_sub;
- int num_cell;
- struct gsm_meas_rep_cell cell[6];
-};
-#define MEAS_REP_F_DTX 0x01
-#define MEAS_REP_F_VALID 0x02
-#define MEAS_REP_F_BA1 0x04
-
-void gsm48_parse_meas_rep(struct gsm_meas_rep *rep, const u_int8_t *data,
- int len);
-
enum chreq_type {
CHREQ_T_EMERG_CALL,
CHREQ_T_CALL_REEST_TCH_F,
@@ -741,7 +748,6 @@ struct gsm_trans;
/* config options controlling the behaviour of the lower leves */
void gsm0408_allow_everyone(int allow);
-void gsm0408_set_reject_cause(int cause);
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
@@ -763,6 +769,8 @@ int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id,
u_int8_t apdu_len, const u_int8_t *apdu);
int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_class);
+int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
+ u_int8_t power_command, u_int8_t ho_ref);
int bsc_upqueue(struct gsm_network *net);
@@ -782,5 +790,7 @@ int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);
int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode);
int gsm48_rx_rr_modif_ack(struct msgb *msg);
+int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
+
#endif
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 874b499c9..4e1977e38 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -38,6 +38,13 @@ enum gsm_chan_t {
GSM_LCHAN_UNKNOWN,
};
+/* RRLP mode of operation */
+enum rrlp_mode {
+ RRLP_MODE_NONE,
+ RRLP_MODE_MS_BASED,
+ RRLP_MODE_MS_PREF,
+ RRLP_MODE_ASS_PREF,
+};
/* Channel Request reason */
enum gsm_chreq_reason_t {
@@ -53,6 +60,7 @@ enum gsm_chreq_reason_t {
#include <openbsc/abis_rsl.h>
#include <openbsc/mncc.h>
#include <openbsc/tlv.h>
+#include <openbsc/bitvec.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -148,6 +156,20 @@ struct gsm_loc_updating_operation {
unsigned int waiting_for_imei : 1;
};
+/* Maximum number of neighbor cells whose average we track */
+#define MAX_NEIGH_MEAS 10
+/* Maximum size of the averaging window for neighbor cells */
+#define MAX_WIN_NEIGH_AVG 10
+
+/* processed neighbor measurements for one cell */
+struct neigh_meas_proc {
+ u_int16_t arfcn;
+ u_int8_t bsic;
+ u_int8_t rxlev[MAX_WIN_NEIGH_AVG];
+ unsigned int rxlev_cnt;
+ u_int8_t last_seen_nr;
+};
+
#define MAX_A5_KEY_LEN (128/8)
#define RSL_ENC_ALG_A5(x) (x+1)
@@ -156,6 +178,13 @@ struct gsm_loc_updating_operation {
#define LCHAN_SAPI_MS 1
#define LCHAN_SAPI_NET 2
+/* state of a logical channel */
+enum gsm_lchan_state {
+ LCHAN_S_NONE, /* channel is not active */
+ LCHAN_S_ACTIVE, /* channel is active and operational */
+ LCHAN_S_INACTIVE, /* channel is set inactive */
+};
+
struct gsm_lchan {
/* The TS that we're part of */
struct gsm_bts_trx_ts *ts;
@@ -167,6 +196,8 @@ struct gsm_lchan {
enum rsl_cmod_spd rsl_cmode;
/* If TCH, traffic channel mode */
enum gsm48_chan_mode tch_mode;
+ /* State */
+ enum gsm_lchan_state state;
/* Power levels for MS and BTS */
u_int8_t bs_power;
u_int8_t ms_power;
@@ -202,11 +233,21 @@ struct gsm_lchan {
/* use count. how many users use this channel */
unsigned int use_count;
+ /* cache of last measurement reports on this lchan */
+ struct gsm_meas_rep meas_rep[6];
+ int meas_rep_idx;
+
+ /* table of neighbor cell measurements */
+ struct neigh_meas_proc neigh_meas[MAX_NEIGH_MEAS];
+
struct {
u_int32_t bound_ip;
+ u_int32_t connect_ip;
u_int16_t bound_port;
- u_int8_t rtp_payload2;
+ u_int16_t connect_port;
u_int16_t conn_id;
+ u_int8_t rtp_payload2;
+ u_int8_t speech_mode;
struct rtp_socket *rtp_socket;
} abis_ip;
};
@@ -356,7 +397,6 @@ struct gsm_bts {
/* should the channel allocator allocate channels from high TRX to TRX0,
* rather than starting from TRX0 and go upwards? */
int chan_alloc_reverse;
- int cell_barred;
/* maximum Tx power that the MS is permitted to use in this cell */
int ms_max_power;
@@ -373,8 +413,6 @@ struct gsm_bts {
/* number of this BTS on given E1 link */
u_int8_t bts_nr;
- struct gsm48_control_channel_descr chan_desc;
-
/* paging state and control */
struct gsm_bts_paging_state paging;
@@ -385,11 +423,28 @@ struct gsm_bts {
struct gsm_nm_state nm_state;
} site_mgr;
+ /* parameters from which we build SYSTEM INFORMATION */
+ struct {
+ struct gsm48_rach_control rach_control;
+ u_int8_t ncc_permitted;
+ struct gsm48_cell_sel_par cell_sel_par;
+ struct gsm48_cell_options cell_options;
+ struct gsm48_control_channel_descr chan_desc;
+ struct bitvec neigh_list;
+ struct bitvec cell_alloc;
+ struct {
+ /* bitmask large enough for all possible ARFCN's */
+ u_int8_t neigh_list[1024/8];
+ u_int8_t cell_alloc[1024/8];
+ } data;
+ } si_common;
+
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
union {
struct {
u_int16_t site_id;
u_int16_t bts_id;
+ u_int32_t flags;
} ip_access;
struct {
struct {
@@ -418,6 +473,49 @@ struct gsm_bts {
struct llist_head trx_list;
};
+/* Some statistics of our network */
+struct gsmnet_stats {
+ struct {
+ unsigned long total;
+ unsigned long no_channel;
+ } chreq;
+ struct {
+ unsigned long attempted;
+ unsigned long no_channel; /* no channel available */
+ unsigned long timeout; /* T3103 timeout */
+ unsigned long completed; /* HO COMPL received */
+ unsigned long failed; /* HO FAIL received */
+ } handover;
+ struct {
+ unsigned long attach;
+ unsigned long normal;
+ unsigned long periodic;
+ unsigned long detach;
+ } loc_upd_type;
+ struct {
+ unsigned long reject;
+ unsigned long accept;
+ } loc_upd_resp;
+ struct {
+ unsigned long attempted;
+ unsigned long detached;
+ unsigned long completed;
+ unsigned long expired;
+ } paging;
+ struct {
+ unsigned long submitted; /* MO SMS submissions */
+ unsigned long no_receiver;
+ unsigned long delivered; /* MT SMS deliveries */
+ unsigned long rp_err_mem;
+ unsigned long rp_err_other;
+ } sms;
+ struct {
+ unsigned long dialled; /* total number of dialled calls */
+ unsigned long alerted; /* we alerted the other end */
+ unsigned long connected;/* how many calls were accepted */
+ } call;
+};
+
enum gsm_auth_policy {
GSM_AUTH_POLICY_CLOSED, /* only subscribers authorized in DB */
GSM_AUTH_POLICY_ACCEPT_ALL, /* accept everyone, even if not authorized in DB */
@@ -442,8 +540,28 @@ struct gsm_network {
char *name_long;
char *name_short;
enum gsm_auth_policy auth_policy;
+ enum gsm48_reject_value reject_cause;
int a5_encryption;
int neci;
+ int send_mm_info;
+ struct {
+ int active;
+ /* Window RXLEV averaging */
+ unsigned int win_rxlev_avg; /* number of SACCH frames */
+ /* Window RXQUAL averaging */
+ unsigned int win_rxqual_avg; /* number of SACCH frames */
+ /* Window RXLEV neighbouring cells averaging */
+ unsigned int win_rxlev_avg_neigh; /* number of SACCH frames */
+
+ /* how often should we check for power budget HO */
+ unsigned int pwr_interval; /* SACCH frames */
+ /* how much better does a neighbor cell have to be ? */
+ unsigned int pwr_hysteresis; /* dBm */
+ /* maximum distacne before we try a handover */
+ unsigned int max_distance; /* TA values */
+ } handover;
+
+ struct gsmnet_stats stats;
struct gsm_audio_support **audio_support;
int audio_length;
@@ -470,6 +588,11 @@ struct gsm_network {
int T3117;
int T3119;
int T3141;
+
+ /* Radio Resource Location Protocol (TS 04.31) */
+ struct {
+ enum rrlp_mode mode;
+ } rrlp;
};
#define SMS_HDR_SIZE 128
@@ -501,6 +624,11 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
+
+/* Get reference to a neighbor cell on a given BCCH ARFCN */
+struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
+ u_int16_t arfcn, u_int8_t bsic);
+
struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
@@ -526,6 +654,7 @@ char *gsm_band_name(enum gsm_band band);
enum gsm_band gsm_band_parse(const char *mhz);
extern void *tall_bsc_ctx;
+extern int ipacc_rtp_direct;
static inline int is_ipaccess_bts(struct gsm_bts *bts)
{
@@ -554,6 +683,11 @@ static inline int is_siemens_bts(struct gsm_bts *bts)
enum gsm_auth_policy gsm_auth_policy_parse(const char *arg);
const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
+enum rrlp_mode rrlp_mode_parse(const char *arg);
+const char *rrlp_mode_name(enum rrlp_mode mode);
+
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
+struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
+
#endif
diff --git a/openbsc/include/openbsc/gsm_utils.h b/openbsc/include/openbsc/gsm_utils.h
index 1bd1bc55a..5809221a3 100644
--- a/openbsc/include/openbsc/gsm_utils.h
+++ b/openbsc/include/openbsc/gsm_utils.h
@@ -33,5 +33,9 @@ int gsm_7bit_encode(u_int8_t *result, const char *data);
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl);
+/* According to TS 08.05 Chapter 8.1.4 */
+int rxlev2dbm(u_int8_t rxlev);
+u_int8_t dbm2rxlev(int dbm);
+
void generate_backtrace();
#endif
diff --git a/openbsc/include/openbsc/handover.h b/openbsc/include/openbsc/handover.h
new file mode 100644
index 000000000..8ab1b0642
--- /dev/null
+++ b/openbsc/include/openbsc/handover.h
@@ -0,0 +1,8 @@
+#ifndef _HANDOVER_H
+#define _HANDOVER_H
+/* Hand over the specified logical channel to the specified new BTS.
+ * This is the main entry point for the actual handover algorithm,
+ * after it has decided it wants to initiate HO to a specific BTS */
+int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
+
+#endif /* _HANDOVER_H */
diff --git a/openbsc/include/openbsc/meas_rep.h b/openbsc/include/openbsc/meas_rep.h
new file mode 100644
index 000000000..fd5fced43
--- /dev/null
+++ b/openbsc/include/openbsc/meas_rep.h
@@ -0,0 +1,84 @@
+#ifndef _MEAS_REP_H
+#define _MEAS_REP_H
+
+#define MRC_F_PROCESSED 0x0001
+
+/* extracted from a L3 measurement report IE */
+struct gsm_meas_rep_cell {
+ u_int8_t rxlev;
+ u_int8_t bsic;
+ u_int16_t arfcn;
+ unsigned int flags;
+};
+
+/* RX Level and RX Quality */
+struct gsm_rx_lev_qual {
+ u_int8_t rx_lev;
+ u_int8_t rx_qual;
+};
+
+/* unidirectional measumrement report */
+struct gsm_meas_rep_unidir {
+ struct gsm_rx_lev_qual full;
+ struct gsm_rx_lev_qual sub;
+};
+
+#define MEAS_REP_F_UL_DTX 0x01
+#define MEAS_REP_F_DL_VALID 0x02
+#define MEAS_REP_F_BA1 0x04
+#define MEAS_REP_F_DL_DTX 0x08
+#define MEAS_REP_F_MS_TO 0x10
+#define MEAS_REP_F_MS_L1 0x20
+#define MEAS_REP_F_FPC 0x40
+
+/* parsed uplink and downlink measurement result */
+struct gsm_meas_rep {
+ /* back-pointer to the logical channel */
+ struct gsm_lchan *lchan;
+
+ /* number of the measurement report */
+ u_int8_t nr;
+ /* flags, see MEAS_REP_F_* */
+ unsigned int flags;
+
+ /* uplink and downlink rxlev, rxqual; full and sub */
+ struct gsm_meas_rep_unidir ul;
+ struct gsm_meas_rep_unidir dl;
+
+ u_int8_t bs_power;
+ u_int8_t ms_timing_offset;
+ struct {
+ int8_t pwr; /* MS power in dBm */
+ u_int8_t ta; /* MS timing advance */
+ } ms_l1;
+
+ /* neighbor measurement reports for up to 6 cells */
+ int num_cell;
+ struct gsm_meas_rep_cell cell[6];
+};
+
+enum meas_rep_field {
+ MEAS_REP_DL_RXLEV_FULL,
+ MEAS_REP_DL_RXLEV_SUB,
+ MEAS_REP_DL_RXQUAL_FULL,
+ MEAS_REP_DL_RXQUAL_SUB,
+ MEAS_REP_UL_RXLEV_FULL,
+ MEAS_REP_UL_RXLEV_SUB,
+ MEAS_REP_UL_RXQUAL_FULL,
+ MEAS_REP_UL_RXQUAL_SUB,
+};
+
+/* obtain an average over the last 'num' fields in the meas reps */
+int get_meas_rep_avg(const struct gsm_lchan *lchan,
+ enum meas_rep_field field, unsigned int num);
+
+/* Check if N out of M last values for FIELD are >= bd */
+int meas_rep_n_out_of_m_be(const struct gsm_lchan *lchan,
+ enum meas_rep_field field,
+ unsigned int n, unsigned int m, int be);
+
+unsigned int calc_initial_idx(unsigned int array_size,
+ unsigned int meas_rep_idx,
+ unsigned int num_values);
+
+#endif /* _MEAS_REP_H */
diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index 68d76abf8..fbf3cab1f 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -87,7 +87,8 @@ struct gsm_call {
#define MNCC_FRAME_DROP 0x0202
#define MNCC_LCHAN_MODIFY 0x0203
-#define GSM_TRAU_FRAME 0x0300
+#define GSM_TCHF_FRAME 0x0300
+#define GSM_TCHF_FRAME_EFR 0x0301
#define GSM_MAX_FACILITY 128
#define GSM_MAX_SSVERSION 128
@@ -162,6 +163,14 @@ struct gsm_mncc_cccap {
int pcp;
};
+enum {
+ GSM_MNCC_BCAP_SPEECH = 0,
+ GSM_MNCC_BCAP_UNR_DIG = 1,
+ GSM_MNCC_BCAP_AUDIO = 2,
+ GSM_MNCC_BCAP_FAX_G3 = 3,
+ GSM_MNCC_BCAP_OTHER_ITC = 5,
+ GSM_MNCC_BCAP_RESERVED = 7,
+};
struct gsm_mncc {
/* context based information */
@@ -199,7 +208,7 @@ struct gsm_mncc {
unsigned char lchan_mode;
};
-struct gsm_trau_frame {
+struct gsm_data_frame {
u_int32_t msg_type;
u_int32_t callref;
unsigned char data[0];
diff --git a/openbsc/include/openbsc/rest_octets.h b/openbsc/include/openbsc/rest_octets.h
new file mode 100644
index 000000000..4e72c0f87
--- /dev/null
+++ b/openbsc/include/openbsc/rest_octets.h
@@ -0,0 +1,122 @@
+#ifndef _REST_OCTETS_H
+#define _REST_OCTETS_H
+
+#include <sys/types.h>
+#include <openbsc/gsm_04_08.h>
+
+/* generate SI1 rest octets */
+int rest_octets_si1(u_int8_t *data, u_int8_t *nch_pos);
+
+struct gsm48_si_selection_params {
+ u_int16_t penalty_time:5,
+ temp_offs:3,
+ cell_resel_off:6,
+ cbq:1,
+ present:1;
+};
+
+struct gsm48_si_power_offset {
+ u_int8_t power_offset:2,
+ present:1;
+};
+
+struct gsm48_si3_gprs_ind {
+ u_int8_t si13_position:1,
+ ra_colour:3,
+ present:1;
+};
+
+struct gsm48_lsa_params {
+ u_int32_t prio_thr:3,
+ lsa_offset:3,
+ mcc:12,
+ mnc:12;
+ unsigned int present;
+};
+
+struct gsm48_si_ro_info {
+ struct gsm48_si_selection_params selection_params;
+ struct gsm48_si_power_offset power_offset;
+ u_int8_t si2ter_indicator;
+ u_int8_t early_cm_ctrl;
+ struct {
+ u_int8_t where:3,
+ present:1;
+ } scheduling;
+ struct gsm48_si3_gprs_ind gprs_ind;
+
+ /* SI 4 specific */
+ struct gsm48_lsa_params lsa_params;
+ u_int16_t cell_id;
+ u_int8_t break_ind; /* do we have SI7 + SI8 ? */
+};
+
+
+/* Generate SI3 Rest Octests (Chapter 10.5.2.34 / Table 10.4.72) */
+int rest_octets_si3(u_int8_t *data, const struct gsm48_si_ro_info *si3);
+
+/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */
+int rest_octets_si4(u_int8_t *data, const struct gsm48_si_ro_info *si4);
+
+enum pbcch_carrier_type {
+ PBCCH_BCCH,
+ PBCCH_ARFCN,
+ PBCCH_MAIO
+};
+
+/* TS 03.60 Chapter 6.3.3.1: Network Mode of Operation */
+enum gprs_nmo {
+ GPRS_NMO_I = 0, /* CS pagin on GPRS paging or traffic channel */
+ GPRS_NMO_II = 1, /* all paging on CCCH */
+ GPRS_NMO_III = 2, /* no paging coordination */
+};
+
+struct gprs_cell_options {
+ enum gprs_nmo nmo;
+ /* T3168: wait for packet uplink assignment message */
+ u_int32_t t3168; /* in milliseconds */
+ /* T3192: wait for release of the TBF after reception of the final block */
+ u_int32_t t3192; /* in milliseconds */
+ u_int32_t drx_timer_max;/* in seconds */
+ u_int32_t bs_cv_max;
+};
+
+/* TS 04.60 Table 12.9.2 */
+struct gprs_power_ctrl_pars {
+ u_int8_t alpha;
+ u_int8_t t_avg_w;
+ u_int8_t t_avg_t;
+ u_int8_t pc_meas_chan;
+ u_int8_t n_avg_i;
+};
+
+struct gsm48_si13_info {
+ struct gprs_cell_options cell_opts;
+ struct gprs_power_ctrl_pars pwr_ctrl_pars;
+ u_int8_t bcch_change_mark;
+ u_int8_t si_change_field;
+ u_int8_t pbcch_present;
+
+ union {
+ struct {
+ u_int8_t rac;
+ u_int8_t spgc_ccch_sup;
+ u_int8_t net_ctrl_ord;
+ u_int8_t prio_acc_thr;
+ } no_pbcch;
+ struct {
+ u_int8_t psi1_rep_per;
+ u_int8_t pb;
+ u_int8_t tsc;
+ u_int8_t tn;
+ enum pbcch_carrier_type carrier_type;
+ u_int16_t arfcn;
+ u_int8_t maio;
+ } pbcch;
+ };
+};
+
+/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */
+int rest_octets_si13(u_int8_t *data, const struct gsm48_si13_info *si13);
+
+#endif /* _REST_OCTETS_H */
diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h
index e9fc157cf..d128e4f23 100644
--- a/openbsc/include/openbsc/rtp_proxy.h
+++ b/openbsc/include/openbsc/rtp_proxy.h
@@ -34,6 +34,11 @@ enum rtp_rx_action {
RTP_RECV_UPSTREAM,
};
+enum rtp_tx_action {
+ RTP_SEND_NONE,
+ RTP_SEND_DOWNSTREAM,
+};
+
struct rtp_sub_socket {
struct sockaddr_in sin_local;
struct sockaddr_in sin_remote;
@@ -56,15 +61,25 @@ struct rtp_socket {
struct rtp_socket *other_sock;
} proxy;
struct {
- void (*recv_cb)(struct msgb *msg);
+ struct gsm_network *net;
+ u_int32_t callref;
} receive;
};
+ enum rtp_tx_action tx_action;
+ struct {
+ u_int16_t sequence;
+ u_int32_t timestamp;
+ u_int32_t ssrc;
+ struct timeval last_tv;
+ } transmit;
};
struct rtp_socket *rtp_socket_create(void);
int rtp_socket_bind(struct rtp_socket *rs, u_int32_t ip);
int rtp_socket_connect(struct rtp_socket *rs, u_int32_t ip, u_int16_t port);
int rtp_socket_proxy(struct rtp_socket *this, struct rtp_socket *other);
+int rtp_socket_upstream(struct rtp_socket *this, struct gsm_network *net, u_int32_t callref);
int rtp_socket_free(struct rtp_socket *rs);
+int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame);
#endif /* _RTP_PROXY_H */
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index fee9d5bfd..8c815f89e 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/signal.h
@@ -40,6 +40,7 @@ enum signal_subsystems {
SS_LCHAN,
SS_SUBSCR,
SS_SCALL,
+ SS_GLOBAL,
};
/* SS_PAGING signals */
@@ -58,6 +59,7 @@ enum signal_sms {
/* SS_ABISIP signals */
enum signal_abisip {
S_ABISIP_CRCX_ACK,
+ S_ABISIP_MDCX_ACK,
S_ABISIP_DLCX_IND,
};
@@ -78,12 +80,19 @@ enum signal_lchan {
* signal handler.
*/
S_LCHAN_UNEXPECTED_RELEASE,
+ S_LCHAN_ACTIVATE_ACK, /* 08.58 Channel Activate ACK */
+ S_LCHAN_ACTIVATE_NACK, /* 08.58 Channel Activate NACK */
+ S_LCHAN_HANDOVER_COMPL, /* 04.08 Handover Completed */
+ S_LCHAN_HANDOVER_FAIL, /* 04.08 Handover Failed */
+ S_LCHAN_HANDOVER_DETECT, /* 08.58 Handover Detect */
+ S_LCHAN_MEAS_REP, /* 08.58 Measurement Report */
};
/* SS_SUBSCR signals */
enum signal_subscr {
S_SUBSCR_ATTACHED,
S_SUBSCR_DETACHED,
+ S_SUBSCR_IDENTITY, /* we've received some identity information */
};
/* SS_SCALL signals */
@@ -93,6 +102,10 @@ enum signal_scall {
S_SCALL_DETACHED,
};
+enum signal_global {
+ S_GLOBAL_SHUTDOWN,
+};
+
typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data);
diff --git a/openbsc/include/openbsc/system_information.h b/openbsc/include/openbsc/system_information.h
new file mode 100644
index 000000000..982a9ac63
--- /dev/null
+++ b/openbsc/include/openbsc/system_information.h
@@ -0,0 +1,6 @@
+#ifndef _SYSTEM_INFO_H
+#define _SYSTEM_INFO_H
+
+int gsm_generate_si(u_int8_t *output, struct gsm_bts *bts, int type);
+
+#endif
diff --git a/openbsc/include/openbsc/tlv.h b/openbsc/include/openbsc/tlv.h
index 0cf4388d8..e970ce468 100644
--- a/openbsc/include/openbsc/tlv.h
+++ b/openbsc/include/openbsc/tlv.h
@@ -119,6 +119,7 @@ static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag,
return buf;
}
+/* 'val' is still in host byte order! */
static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag,
u_int16_t val)
{
diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h
index 961a64923..cf9410082 100644
--- a/openbsc/include/openbsc/transaction.h
+++ b/openbsc/include/openbsc/transaction.h
@@ -26,6 +26,9 @@ struct gsm_trans {
/* reference from MNCC or other application */
u_int32_t callref;
+ /* if traffic channel receive was requested */
+ int tch_recv;
+
union {
struct {
@@ -65,4 +68,9 @@ void trans_free(struct gsm_trans *trans);
int trans_assign_trans_id(struct gsm_subscriber *subscr,
u_int8_t protocol, u_int8_t ti_flag);
+
+/* update all transactions to use a different LCHAN, e.g.
+ * after handover has succeeded */
+int trans_lchan_change(struct gsm_lchan *lchan_old,
+ struct gsm_lchan *lchan_new);
#endif
diff --git a/openbsc/include/openbsc/trau_mux.h b/openbsc/include/openbsc/trau_mux.h
index 90535add4..8deb708de 100644
--- a/openbsc/include/openbsc/trau_mux.h
+++ b/openbsc/include/openbsc/trau_mux.h
@@ -46,4 +46,4 @@ int trau_mux_input(struct gsm_e1_subslot *src_e1_ss,
int trau_recv_lchan(struct gsm_lchan *lchan, u_int32_t callref);
/* send trau from application */
-int trau_send_lchan(struct gsm_lchan *lchan, struct decoded_trau_frame *tf);
+int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame);