diff options
Diffstat (limited to 'openbsc/include')
-rw-r--r-- | openbsc/include/openbsc/Makefile.am | 3 | ||||
-rw-r--r-- | openbsc/include/openbsc/abis_rsl.h | 8 | ||||
-rw-r--r-- | openbsc/include/openbsc/bitvec.h | 65 | ||||
-rw-r--r-- | openbsc/include/openbsc/call_handling.h | 64 | ||||
-rw-r--r-- | openbsc/include/openbsc/debug.h | 13 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_04_08.h | 70 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 142 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_utils.h | 4 | ||||
-rw-r--r-- | openbsc/include/openbsc/handover.h | 8 | ||||
-rw-r--r-- | openbsc/include/openbsc/meas_rep.h | 84 | ||||
-rw-r--r-- | openbsc/include/openbsc/mncc.h | 13 | ||||
-rw-r--r-- | openbsc/include/openbsc/rest_octets.h | 122 | ||||
-rw-r--r-- | openbsc/include/openbsc/rtp_proxy.h | 17 | ||||
-rw-r--r-- | openbsc/include/openbsc/signal.h | 13 | ||||
-rw-r--r-- | openbsc/include/openbsc/system_information.h | 6 | ||||
-rw-r--r-- | openbsc/include/openbsc/tlv.h | 1 | ||||
-rw-r--r-- | openbsc/include/openbsc/transaction.h | 8 | ||||
-rw-r--r-- | openbsc/include/openbsc/trau_mux.h | 2 |
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); |