From c01647914b97ab8a1079330e36d0e1d024d3a804 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 4 Sep 2017 15:15:32 +0200 Subject: move include/openbsc to include/osmocom/bsc Change-Id: I39e7b882caa98334636d19ccd104fd83d07d5055 --- include/osmocom/Makefile.am | 3 + include/osmocom/bsc/Makefile.am | 68 ++ include/osmocom/bsc/a_reset.h | 63 ++ include/osmocom/bsc/abis_nm.h | 180 ++++ include/osmocom/bsc/abis_om2000.h | 129 +++ include/osmocom/bsc/abis_rsl.h | 117 +++ include/osmocom/bsc/arfcn_range_encode.h | 26 + include/osmocom/bsc/auth.h | 22 + include/osmocom/bsc/bsc_api.h | 59 ++ include/osmocom/bsc/bsc_msc.h | 77 ++ include/osmocom/bsc/bsc_msc_data.h | 174 ++++ include/osmocom/bsc/bsc_msg_filter.h | 107 +++ include/osmocom/bsc/bsc_nat.h | 462 +++++++++ include/osmocom/bsc/bsc_nat_callstats.h | 55 ++ include/osmocom/bsc/bsc_nat_sccp.h | 105 ++ include/osmocom/bsc/bsc_rll.h | 19 + include/osmocom/bsc/bsc_subscriber.h | 43 + include/osmocom/bsc/bss.h | 20 + include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h | 32 + include/osmocom/bsc/chan_alloc.h | 54 ++ include/osmocom/bsc/common.h | 6 + include/osmocom/bsc/common_bsc.h | 9 + include/osmocom/bsc/common_cs.h | 34 + include/osmocom/bsc/crc24.h | 10 + include/osmocom/bsc/ctrl.h | 4 + include/osmocom/bsc/debug.h | 47 + include/osmocom/bsc/e1_config.h | 11 + include/osmocom/bsc/gsm_04_08_utils.h | 32 + include/osmocom/bsc/gsm_04_80.h | 25 + include/osmocom/bsc/gsm_data.h | 692 ++++++++++++++ include/osmocom/bsc/gsm_data_shared.h | 1004 ++++++++++++++++++++ include/osmocom/bsc/gsm_subscriber.h | 68 ++ include/osmocom/bsc/handover.h | 14 + include/osmocom/bsc/handover_decision.h | 7 + include/osmocom/bsc/ipaccess.h | 52 + include/osmocom/bsc/iu_dummy.h | 51 + include/osmocom/bsc/meas_feed.h | 41 + include/osmocom/bsc/meas_rep.h | 67 ++ include/osmocom/bsc/misdn.h | 27 + include/osmocom/bsc/mncc.h | 215 +++++ include/osmocom/bsc/mncc_int.h | 14 + include/osmocom/bsc/msc_ifaces.h | 42 + include/osmocom/bsc/nat_rewrite_trie.h | 47 + include/osmocom/bsc/network_listen.h | 16 + include/osmocom/bsc/openbscdefines.h | 34 + include/osmocom/bsc/osmo_bsc.h | 75 ++ include/osmocom/bsc/osmo_bsc_grace.h | 35 + include/osmocom/bsc/osmo_bsc_reset.h | 34 + include/osmocom/bsc/osmo_bsc_rf.h | 66 ++ include/osmocom/bsc/osmo_bsc_sigtran.h | 48 + include/osmocom/bsc/osmo_msc.h | 99 ++ include/osmocom/bsc/osmux.h | 41 + include/osmocom/bsc/paging.h | 77 ++ include/osmocom/bsc/pcu_if.h | 35 + include/osmocom/bsc/pcuif_proto.h | 176 ++++ include/osmocom/bsc/rest_octets.h | 140 +++ include/osmocom/bsc/rrlp.h | 7 + include/osmocom/bsc/rs232.h | 9 + include/osmocom/bsc/rtp_proxy.h | 95 ++ include/osmocom/bsc/sgsn.h | 191 ++++ include/osmocom/bsc/signal.h | 260 +++++ include/osmocom/bsc/silent_call.h | 15 + include/osmocom/bsc/smpp.h | 4 + include/osmocom/bsc/sms_queue.h | 17 + include/osmocom/bsc/socket.h | 14 + include/osmocom/bsc/system_information.h | 22 + include/osmocom/bsc/transaction.h | 102 ++ include/osmocom/bsc/trau_mux.h | 70 ++ include/osmocom/bsc/trau_upqueue.h | 7 + include/osmocom/bsc/ussd.h | 10 + include/osmocom/bsc/vty.h | 54 ++ 71 files changed, 6087 insertions(+) create mode 100644 include/osmocom/Makefile.am create mode 100644 include/osmocom/bsc/Makefile.am create mode 100644 include/osmocom/bsc/a_reset.h create mode 100644 include/osmocom/bsc/abis_nm.h create mode 100644 include/osmocom/bsc/abis_om2000.h create mode 100644 include/osmocom/bsc/abis_rsl.h create mode 100644 include/osmocom/bsc/arfcn_range_encode.h create mode 100644 include/osmocom/bsc/auth.h create mode 100644 include/osmocom/bsc/bsc_api.h create mode 100644 include/osmocom/bsc/bsc_msc.h create mode 100644 include/osmocom/bsc/bsc_msc_data.h create mode 100644 include/osmocom/bsc/bsc_msg_filter.h create mode 100644 include/osmocom/bsc/bsc_nat.h create mode 100644 include/osmocom/bsc/bsc_nat_callstats.h create mode 100644 include/osmocom/bsc/bsc_nat_sccp.h create mode 100644 include/osmocom/bsc/bsc_rll.h create mode 100644 include/osmocom/bsc/bsc_subscriber.h create mode 100644 include/osmocom/bsc/bss.h create mode 100644 include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h create mode 100644 include/osmocom/bsc/chan_alloc.h create mode 100644 include/osmocom/bsc/common.h create mode 100644 include/osmocom/bsc/common_bsc.h create mode 100644 include/osmocom/bsc/common_cs.h create mode 100644 include/osmocom/bsc/crc24.h create mode 100644 include/osmocom/bsc/ctrl.h create mode 100644 include/osmocom/bsc/debug.h create mode 100644 include/osmocom/bsc/e1_config.h create mode 100644 include/osmocom/bsc/gsm_04_08_utils.h create mode 100644 include/osmocom/bsc/gsm_04_80.h create mode 100644 include/osmocom/bsc/gsm_data.h create mode 100644 include/osmocom/bsc/gsm_data_shared.h create mode 100644 include/osmocom/bsc/gsm_subscriber.h create mode 100644 include/osmocom/bsc/handover.h create mode 100644 include/osmocom/bsc/handover_decision.h create mode 100644 include/osmocom/bsc/ipaccess.h create mode 100644 include/osmocom/bsc/iu_dummy.h create mode 100644 include/osmocom/bsc/meas_feed.h create mode 100644 include/osmocom/bsc/meas_rep.h create mode 100644 include/osmocom/bsc/misdn.h create mode 100644 include/osmocom/bsc/mncc.h create mode 100644 include/osmocom/bsc/mncc_int.h create mode 100644 include/osmocom/bsc/msc_ifaces.h create mode 100644 include/osmocom/bsc/nat_rewrite_trie.h create mode 100644 include/osmocom/bsc/network_listen.h create mode 100644 include/osmocom/bsc/openbscdefines.h create mode 100644 include/osmocom/bsc/osmo_bsc.h create mode 100644 include/osmocom/bsc/osmo_bsc_grace.h create mode 100644 include/osmocom/bsc/osmo_bsc_reset.h create mode 100644 include/osmocom/bsc/osmo_bsc_rf.h create mode 100644 include/osmocom/bsc/osmo_bsc_sigtran.h create mode 100644 include/osmocom/bsc/osmo_msc.h create mode 100644 include/osmocom/bsc/osmux.h create mode 100644 include/osmocom/bsc/paging.h create mode 100644 include/osmocom/bsc/pcu_if.h create mode 100644 include/osmocom/bsc/pcuif_proto.h create mode 100644 include/osmocom/bsc/rest_octets.h create mode 100644 include/osmocom/bsc/rrlp.h create mode 100644 include/osmocom/bsc/rs232.h create mode 100644 include/osmocom/bsc/rtp_proxy.h create mode 100644 include/osmocom/bsc/sgsn.h create mode 100644 include/osmocom/bsc/signal.h create mode 100644 include/osmocom/bsc/silent_call.h create mode 100644 include/osmocom/bsc/smpp.h create mode 100644 include/osmocom/bsc/sms_queue.h create mode 100644 include/osmocom/bsc/socket.h create mode 100644 include/osmocom/bsc/system_information.h create mode 100644 include/osmocom/bsc/transaction.h create mode 100644 include/osmocom/bsc/trau_mux.h create mode 100644 include/osmocom/bsc/trau_upqueue.h create mode 100644 include/osmocom/bsc/ussd.h create mode 100644 include/osmocom/bsc/vty.h (limited to 'include/osmocom') diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am new file mode 100644 index 000000000..cf24c62a6 --- /dev/null +++ b/include/osmocom/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = \ + bsc \ + $(NULL) diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am new file mode 100644 index 000000000..3b8dbdf12 --- /dev/null +++ b/include/osmocom/bsc/Makefile.am @@ -0,0 +1,68 @@ +noinst_HEADERS = \ + a_reset.h \ + abis_nm.h \ + abis_om2000.h \ + abis_rsl.h \ + arfcn_range_encode.h \ + auth.h \ + bsc_msc.h \ + bsc_msg_filter.h \ + bsc_nat.h \ + bsc_nat_callstats.h \ + bsc_nat_sccp.h \ + bsc_rll.h \ + bsc_subscriber.h \ + bss.h \ + bts_ipaccess_nanobts_omlattr.h \ + chan_alloc.h \ + common.h \ + common_bsc.h \ + common_cs.h \ + crc24.h \ + ctrl.h \ + debug.h \ + e1_config.h \ + gsm_04_08_utils.h \ + gsm_04_80.h \ + gsm_data.h \ + gsm_data_shared.h \ + gsm_subscriber.h \ + handover.h \ + handover_decision.h \ + ipaccess.h \ + meas_feed.h \ + meas_rep.h \ + misdn.h \ + mncc.h \ + mncc_int.h \ + msc_ifaces.h \ + nat_rewrite_trie.h \ + network_listen.h \ + openbscdefines.h \ + osmo_bsc.h \ + osmo_bsc_grace.h \ + osmo_bsc_rf.h \ + osmo_msc.h \ + osmo_bsc_sigtran.h \ + bsc_msc_data.h \ + osmux.h \ + paging.h \ + pcu_if.h \ + pcuif_proto.h \ + rest_octets.h \ + rrlp.h \ + rs232.h \ + rtp_proxy.h \ + sgsn.h \ + signal.h \ + silent_call.h \ + sms_queue.h \ + socket.h \ + system_information.h \ + transaction.h \ + trau_mux.h \ + trau_upqueue.h \ + ussd.h \ + vty.h \ + bsc_api.h \ + $(NULL) diff --git a/include/osmocom/bsc/a_reset.h b/include/osmocom/bsc/a_reset.h new file mode 100644 index 000000000..7aaab0620 --- /dev/null +++ b/include/osmocom/bsc/a_reset.h @@ -0,0 +1,63 @@ +/* (C) 2017 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#pragma once + + + +/* Reset context data (callbacks, state machine etc...) */ +struct a_reset_ctx { + + /* FSM instance, which handles the reset procedure */ + struct osmo_fsm_inst *fsm; + + /* Connection failure counter. When this counter + * reaches a certain threshold, the reset procedure + * will be triggered */ + int conn_loss_counter; + + /* A human readable name to display in the logs */ + char name[256]; + + /* Callback function to be called when a connection + * failure is detected and a rest must occur */ + void (*cb)(void *priv); + + /* Privated data for the callback function */ + void *priv; +}; + +/* Create and start state machine which handles the reset/reset-ack procedure */ +struct a_reset_ctx *a_reset_alloc(const void *ctx, const char *name, void *cb, void *priv); + +/* Tear down state machine */ +void a_reset_free(struct a_reset_ctx *reset); + +/* Confirm that we sucessfully received a reset acknowlege message */ +void a_reset_ack_confirm(struct a_reset_ctx *reset); + +/* Report a failed connection */ +void a_reset_conn_fail(struct a_reset_ctx *reset); + +/* Report a successful connection */ +void a_reset_conn_success(struct a_reset_ctx *reset); + +/* Check if we have a connection to a specified msc */ +bool a_reset_conn_ready(struct a_reset_ctx *reset); diff --git a/include/osmocom/bsc/abis_nm.h b/include/osmocom/bsc/abis_nm.h new file mode 100644 index 000000000..34f16a953 --- /dev/null +++ b/include/osmocom/bsc/abis_nm.h @@ -0,0 +1,180 @@ +/* GSM Network Management messages on the A-bis interface + * 3GPP TS 12.21 version 8.0.0 Release 1999 / ETSI TS 100 623 V8.0.0 */ + +/* (C) 2008-2009 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef _NM_H +#define _NM_H + +#include +#include +#include + +#include + +/* max number of attributes represented as 3GPP TS 52.021 ยง9.4.62 SW Description array */ +#define MAX_BTS_ATTR 5 + +struct cell_global_id { + uint16_t mcc; + uint16_t mnc; + uint16_t lac; + uint16_t ci; +}; + +/* The BCCH info from an ip.access test, in host byte order + * and already parsed... */ +struct ipac_bcch_info { + struct llist_head list; + + uint16_t info_type; + uint8_t freq_qual; + uint16_t arfcn; + uint8_t rx_lev; + uint8_t rx_qual; + int16_t freq_err; + uint16_t frame_offset; + uint32_t frame_nr_offset; + uint8_t bsic; + struct cell_global_id cgi; + uint8_t ba_list_si2[16]; + uint8_t ba_list_si2bis[16]; + uint8_t ba_list_si2ter[16]; + uint8_t ca_list_si1[16]; +}; + +/* PUBLIC */ + +struct msgb; + +struct abis_nm_cfg { + /* callback for unidirectional reports */ + int (*report_cb)(struct msgb *, + struct abis_om_fom_hdr *); + /* callback for software activate requests from BTS */ + int (*sw_act_req)(struct msgb *); +}; + +extern int abis_nm_rcvmsg(struct msgb *msg); + +int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const uint8_t *buf, int len); +int abis_nm_rx(struct msgb *msg); +int abis_nm_opstart(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0, uint8_t i1, uint8_t i2); +int abis_nm_chg_adm_state(struct gsm_bts *bts, uint8_t obj_class, uint8_t i0, + uint8_t i1, uint8_t i2, enum abis_nm_adm_state adm_state); +int abis_nm_establish_tei(struct gsm_bts *bts, uint8_t trx_nr, + uint8_t e1_port, uint8_t e1_timeslot, uint8_t e1_subslot, + uint8_t tei); +int abis_nm_conn_terr_sign(struct gsm_bts_trx *trx, + uint8_t e1_port, uint8_t e1_timeslot, uint8_t e1_subslot); +int abis_nm_conn_terr_traf(struct gsm_bts_trx_ts *ts, + uint8_t e1_port, uint8_t e1_timeslot, + uint8_t e1_subslot); +int abis_nm_get_attr(struct gsm_bts *bts, uint8_t obj_class, + uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr, + const uint8_t *attr, uint8_t attr_len); +int abis_nm_set_bts_attr(struct gsm_bts *bts, uint8_t *attr, int attr_len); +int abis_nm_set_radio_attr(struct gsm_bts_trx *trx, uint8_t *attr, int attr_len); +int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, uint8_t chan_comb); +int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1, + uint8_t i2, uint8_t i3, int nack, uint8_t *attr, int att_len); +int abis_nm_raw_msg(struct gsm_bts *bts, int len, uint8_t *msg); +int abis_nm_event_reports(struct gsm_bts *bts, int on); +int abis_nm_reset_resource(struct gsm_bts *bts); +int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname, + uint8_t win_size, int forced, + gsm_cbfn *cbfn, void *cb_data); +int abis_nm_software_load_status(struct gsm_bts *bts); +int abis_nm_software_activate(struct gsm_bts *bts, const char *fname, + gsm_cbfn *cbfn, void *cb_data); + +int abis_nm_conn_mdrop_link(struct gsm_bts *bts, uint8_t e1_port0, uint8_t ts0, + uint8_t e1_port1, uint8_t ts1); + +int abis_nm_perform_test(struct gsm_bts *bts, uint8_t obj_class, + uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr, + uint8_t test_nr, uint8_t auton_report, struct msgb *msg); + +/* Siemens / BS-11 specific */ +int abis_nm_bs11_reset_resource(struct gsm_bts *bts); +int abis_nm_bs11_db_transmission(struct gsm_bts *bts, int begin); +int abis_nm_bs11_create_object(struct gsm_bts *bts, enum abis_bs11_objtype type, + uint8_t idx, uint8_t attr_len, const uint8_t *attr); +int abis_nm_bs11_create_envaBTSE(struct gsm_bts *bts, uint8_t idx); +int abis_nm_bs11_create_bport(struct gsm_bts *bts, uint8_t idx); +int abis_nm_bs11_delete_object(struct gsm_bts *bts, + enum abis_bs11_objtype type, uint8_t idx); +int abis_nm_bs11_delete_bport(struct gsm_bts *bts, uint8_t idx); +int abis_nm_bs11_conn_oml_tei(struct gsm_bts *bts, uint8_t e1_port, + uint8_t e1_timeslot, uint8_t e1_subslot, uint8_t tei); +int abis_nm_bs11_get_oml_tei_ts(struct gsm_bts *bts); +int abis_nm_bs11_get_serno(struct gsm_bts *bts); +int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, uint8_t level); +int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx); +int abis_nm_bs11_logon(struct gsm_bts *bts, uint8_t level, const char *name, int on); +int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on); +int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on); +int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password); +int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked); +int abis_nm_bs11_get_pll_mode(struct gsm_bts *bts); +int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value); +int abis_nm_bs11_get_cclk(struct gsm_bts *bts); +int abis_nm_bs11_get_state(struct gsm_bts *bts); +int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname, + uint8_t win_size, int forced, gsm_cbfn *cbfn); +int abis_nm_bs11_set_ext_time(struct gsm_bts *bts); +int abis_nm_bs11_get_bport_line_cfg(struct gsm_bts *bts, uint8_t bport); +int abis_nm_bs11_set_bport_line_cfg(struct gsm_bts *bts, uint8_t bport, enum abis_bs11_line_cfg line_cfg); +int abis_nm_bs11_bsc_disconnect(struct gsm_bts *bts, int reconnect); +int abis_nm_bs11_restart(struct gsm_bts *bts); + +/* ip.access nanoBTS specific commands */ +int abis_nm_ipaccess_msg(struct gsm_bts *bts, uint8_t msg_type, + uint8_t obj_class, uint8_t bts_nr, + uint8_t trx_nr, uint8_t ts_nr, + uint8_t *attr, int attr_len); +int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, uint8_t *attr, + int attr_len); +int abis_nm_ipaccess_restart(struct gsm_bts_trx *trx); +int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, uint8_t obj_class, + uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr, + uint8_t *attr, uint8_t attr_len); +int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx, + uint32_t ip, uint16_t port, uint8_t stream); +void abis_nm_ipaccess_cgi(uint8_t *buf, struct gsm_bts *bts); +int ipac_parse_bcch_info(struct ipac_bcch_info *binf, uint8_t *buf); +const char *ipacc_testres_name(uint8_t res); + +/* Functions calling into other code parts */ +int nm_is_running(struct gsm_nm_state *s); + +int abis_nm_vty_init(void); + +void abis_nm_clear_queue(struct gsm_bts *bts); + +int _abis_nm_sendmsg(struct msgb *msg); + +void abis_nm_queue_send_next(struct gsm_bts *bts); /* for bs11_config. */ + +int abis_nm_select_newest_sw(const struct abis_nm_sw_desc *sw, const size_t len); + +/* Helper functions for updating attributes */ +int abis_nm_update_max_power_red(struct gsm_bts_trx *trx); + +#endif /* _NM_H */ diff --git a/include/osmocom/bsc/abis_om2000.h b/include/osmocom/bsc/abis_om2000.h new file mode 100644 index 000000000..b093a0350 --- /dev/null +++ b/include/osmocom/bsc/abis_om2000.h @@ -0,0 +1,129 @@ +#ifndef OPENBSC_ABIS_OM2K_H +#define OPENBSC_ABIS_OM2K_H +/* Ericsson RBS 2xxx GSM O&M (OM2000) messages on the A-bis interface + * implemented based on protocol trace analysis, no formal documentation */ + +/* (C) 2010-2011 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +enum abis_om2k_mo_cls { + OM2K_MO_CLS_TRXC = 0x01, + OM2K_MO_CLS_TS = 0x03, + OM2K_MO_CLS_TF = 0x04, + OM2K_MO_CLS_IS = 0x05, + OM2K_MO_CLS_CON = 0x06, + OM2K_MO_CLS_DP = 0x07, + OM2K_MO_CLS_CF = 0x0a, + OM2K_MO_CLS_TX = 0x0b, + OM2K_MO_CLS_RX = 0x0c, +}; + +enum om2k_mo_state { + OM2K_MO_S_RESET = 0, + OM2K_MO_S_STARTED, + OM2K_MO_S_ENABLED, + OM2K_MO_S_DISABLED, +}; + +/* on-wire format for IS conn group */ +struct om2k_is_conn_grp { + uint16_t icp1; + uint16_t icp2; + uint8_t cont_idx; +} __attribute__ ((packed)); + +/* internal data formant for IS conn group */ +struct is_conn_group { + struct llist_head list; + uint16_t icp1; + uint16_t icp2; + uint8_t ci; +}; + +/* on-wire format for CON Path */ +struct om2k_con_path { + uint16_t ccp; + uint8_t ci; + uint8_t tag; + uint8_t tei; +} __attribute__ ((packed)); + +/* internal data format for CON group */ +struct con_group { + /* links list of CON groups in BTS */ + struct llist_head list; + struct gsm_bts *bts; + /* CON Group ID */ + uint8_t cg; + /* list of CON paths in this group */ + struct llist_head paths; +}; + +/* internal data format for CON path */ +struct con_path { + /* links with con_group.paths */ + struct llist_head list; + /* CON Connection Point */ + uint16_t ccp; + /* Contiguity Index */ + uint8_t ci; + /* Tag */ + uint8_t tag; + /* TEI */ + uint8_t tei; +}; + +extern const struct abis_om2k_mo om2k_mo_cf; +extern const struct abis_om2k_mo om2k_mo_is; +extern const struct abis_om2k_mo om2k_mo_con; +extern const struct abis_om2k_mo om2k_mo_tf; + +extern const struct value_string om2k_mo_class_short_vals[]; + +int abis_om2k_rcvmsg(struct msgb *msg); + +extern const struct abis_om2k_mo om2k_mo_cf; + +int abis_om2k_tx_reset_cmd(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_start_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_status_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_connect_cmd(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_disconnect_cmd(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_enable_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_disable_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_test_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_op_info(struct gsm_bts *bts, const struct abis_om2k_mo *mo, + uint8_t operational); +int abis_om2k_tx_cap_req(struct gsm_bts *bts, const struct abis_om2k_mo *mo); +int abis_om2k_tx_is_conf_req(struct gsm_bts *bts); +int abis_om2k_tx_tf_conf_req(struct gsm_bts *bts); +int abis_om2k_tx_rx_conf_req(struct gsm_bts_trx *trx); +int abis_om2k_tx_tx_conf_req(struct gsm_bts_trx *trx); +int abis_om2k_tx_ts_conf_req(struct gsm_bts_trx_ts *ts); + +struct osmo_fsm_inst *om2k_bts_fsm_start(struct gsm_bts *bts); +void abis_om2k_bts_init(struct gsm_bts *bts); +void abis_om2k_trx_init(struct gsm_bts_trx *trx); + +int abis_om2k_vty_init(void); + +struct vty; +void abis_om2k_config_write_bts(struct vty *vty, struct gsm_bts *bts); + +#endif /* OPENBCS_ABIS_OM2K_H */ diff --git a/include/osmocom/bsc/abis_rsl.h b/include/osmocom/bsc/abis_rsl.h new file mode 100644 index 000000000..f983fceec --- /dev/null +++ b/include/osmocom/bsc/abis_rsl.h @@ -0,0 +1,117 @@ +/* GSM Radio Signalling Link messages on the A-bis interface + * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */ + +/* (C) 2008 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef _RSL_H +#define _RSL_H + +#include +#include +#include +#include +#include + +struct gsm_bts; +struct gsm_lchan; +struct gsm_bts_trx_ts; + +#define GSM48_LEN2PLEN(a) (((a) << 2) | 1) + +int rsl_bcch_info(const struct gsm_bts_trx *trx, enum osmo_sysinfo_type si_type, const uint8_t *data, int len); +int rsl_sacch_filling(struct gsm_bts_trx *trx, uint8_t type, + const uint8_t *data, int len); +int rsl_chan_activate(struct gsm_bts_trx *trx, uint8_t chan_nr, + uint8_t act_type, + struct rsl_ie_chan_mode *chan_mode, + struct rsl_ie_chan_ident *chan_ident, + uint8_t bs_power, uint8_t ms_power, + uint8_t ta); +int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type, + uint8_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, uint8_t paging_group, uint8_t len, + uint8_t *ms_ident, uint8_t chan_needed, bool is_gprs); +int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val); + +int rsl_data_request(struct msgb *msg, uint8_t link_id); +int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id); +int rsl_relase_request(struct gsm_lchan *lchan, uint8_t link_id); + +/* Ericcson vendor specific RSL extensions */ +int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val); + +/* Siemens vendor-specific RSL extensions */ +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, uint32_t ip, + uint16_t port, uint8_t rtp_payload2); +int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan); +int rsl_ipacc_pdch_activate(struct gsm_bts_trx_ts *ts, int act); + +int abis_rsl_rcvmsg(struct msgb *msg); + +uint64_t str_to_imsi(const char *imsi_str); +int rsl_release_request(struct gsm_lchan *lchan, uint8_t link_id, + enum rsl_rel_mode release_mode); + +int rsl_lchan_set_state(struct gsm_lchan *lchan, int); +int rsl_lchan_mark_broken(struct gsm_lchan *lchan, const char *broken); + +/* to be provided by external code */ +int rsl_deact_sacch(struct gsm_lchan *lchan); + +/* BCCH related code */ +int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf); +int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf); + +int rsl_sacch_info_modify(struct gsm_lchan *lchan, uint8_t type, + const uint8_t *data, int len); + +int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db); +int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm); + +/* SMSCB functionality */ +int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number, + struct rsl_ie_cb_cmd_type cb_command, + const uint8_t *data, int len); + +/* some Nokia specific stuff */ +int rsl_nokia_si_begin(struct gsm_bts_trx *trx); +int rsl_nokia_si_end(struct gsm_bts_trx *trx); + +/* required for Nokia BTS power control */ +int rsl_bs_power_control(struct gsm_bts_trx *trx, uint8_t channel, uint8_t reduction); + + +int rsl_release_sapis_from(struct gsm_lchan *lchan, int start, + enum rsl_rel_mode release_mode); +int rsl_start_t3109(struct gsm_lchan *lchan); + +int rsl_direct_rf_release(struct gsm_lchan *lchan); + +void dyn_ts_init(struct gsm_bts_trx_ts *ts); +int dyn_ts_switchover_start(struct gsm_bts_trx_ts *ts, + enum gsm_phys_chan_config to_pchan); + +#endif /* RSL_MT_H */ + diff --git a/include/osmocom/bsc/arfcn_range_encode.h b/include/osmocom/bsc/arfcn_range_encode.h new file mode 100644 index 000000000..7ec710c33 --- /dev/null +++ b/include/osmocom/bsc/arfcn_range_encode.h @@ -0,0 +1,26 @@ +#ifndef ARFCN_RANGE_ENCODE_H +#define ARFCN_RANGE_ENCODE_H + +#include + +enum gsm48_range { + ARFCN_RANGE_INVALID = -1, + ARFCN_RANGE_128 = 127, + ARFCN_RANGE_256 = 255, + ARFCN_RANGE_512 = 511, + ARFCN_RANGE_1024 = 1023, +}; + +#define RANGE_ENC_MAX_ARFCNS 29 + +int range_enc_determine_range(const int *arfcns, int size, int *f0_out); +int range_enc_arfcns(enum gsm48_range rng, const int *arfcns, int sze, int *out, int idx); +int range_enc_find_index(enum gsm48_range rng, const int *arfcns, int size); +int range_enc_filter_arfcns(int *arfcns, const int sze, const int f0, int *f0_included); + +int range_enc_range128(uint8_t *chan_list, int f0, int *w); +int range_enc_range256(uint8_t *chan_list, int f0, int *w); +int range_enc_range512(uint8_t *chan_list, int f0, int *w); +int range_enc_range1024(uint8_t *chan_list, int f0, int f0_incl, int *w); + +#endif diff --git a/include/osmocom/bsc/auth.h b/include/osmocom/bsc/auth.h new file mode 100644 index 000000000..b314bbf19 --- /dev/null +++ b/include/osmocom/bsc/auth.h @@ -0,0 +1,22 @@ +#ifndef _AUTH_H +#define _AUTH_H + +#include + +struct gsm_auth_tuple; + +enum auth_action { + AUTH_ERROR = -1, /* Internal error */ + AUTH_NOT_AVAIL = 0, /* No auth tuple available */ + AUTH_DO_AUTH_THEN_CIPH = 1, /* Firsth authenticate, then cipher */ + AUTH_DO_CIPH = 2, /* Only ciphering */ + AUTH_DO_AUTH = 3, /* Only authentication, no ciphering */ +}; + +extern const struct value_string auth_action_names[]; +static inline const char *auth_action_str(enum auth_action a) +{ + return get_value_string(auth_action_names, a); +} + +#endif /* _AUTH_H */ diff --git a/include/osmocom/bsc/bsc_api.h b/include/osmocom/bsc/bsc_api.h new file mode 100644 index 000000000..6ee05629f --- /dev/null +++ b/include/osmocom/bsc/bsc_api.h @@ -0,0 +1,59 @@ +/* GSM 08.08 like API for OpenBSC */ + +#ifndef OPENBSC_BSC_API_H +#define OPENBSC_BSC_API_H + +#include "gsm_data.h" + +#define BSC_API_CONN_POL_ACCEPT 0 +#define BSC_API_CONN_POL_REJECT 1 + +struct bsc_api { + /*! \brief BTS->MSC: tell MSC a SAPI was not established */ + void (*sapi_n_reject)(struct gsm_subscriber_connection *conn, int dlci); + /*! \brief MS->MSC: Tell MSC that ciphering has been enabled */ + void (*cipher_mode_compl)(struct gsm_subscriber_connection *conn, + struct msgb *msg, uint8_t chosen_encr); + /*! \brief MS->MSC: New MM context with L3 payload */ + int (*compl_l3)(struct gsm_subscriber_connection *conn, + struct msgb *msg, uint16_t chosen_channel); + /*! \brief MS->BSC/MSC: Um L3 message */ + void (*dtap)(struct gsm_subscriber_connection *conn, uint8_t link_id, + struct msgb *msg); + /*! \brief BSC->MSC: Assignment of lchan successful */ + void (*assign_compl)(struct gsm_subscriber_connection *conn, + uint8_t rr_cause, uint8_t chosen_channel, + uint8_t encr_alg_id, uint8_t speech_mode); + /*! \brief BSC->MSC: Assignment of lchan failed */ + void (*assign_fail)(struct gsm_subscriber_connection *conn, + uint8_t cause, uint8_t *rr_cause); + /*! \brief BSC->MSC: RR conn has been cleared */ + int (*clear_request)(struct gsm_subscriber_connection *conn, + uint32_t cause); + /*! \brief BSC->MSC: Classmark Update */ + void (*classmark_chg)(struct gsm_subscriber_connection *conn, + const uint8_t *cm2, uint8_t cm2_len, + const uint8_t *cm3, uint8_t cm3_len); + + /** + * Configure the multirate setting on this channel. If it is + * not implemented AMR5.9 will be used. + */ + void (*mr_config)(struct gsm_subscriber_connection *conn, + struct gsm_lchan *lchan, int full_rate); + + /** Callback for additional actions during conn cleanup */ + void (*conn_cleanup)(struct gsm_subscriber_connection *conn); +}; + +int bsc_api_init(struct gsm_network *network, struct bsc_api *api); +int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, int link_id, int allow_sacch); +int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate); +int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher, + const uint8_t *key, int len, int include_imeisv); +int gsm0808_page(struct gsm_bts *bts, unsigned int page_group, + unsigned int mi_len, uint8_t *mi, int chan_type); +int gsm0808_clear(struct gsm_subscriber_connection *conn); + +int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id); +#endif diff --git a/include/osmocom/bsc/bsc_msc.h b/include/osmocom/bsc/bsc_msc.h new file mode 100644 index 000000000..ceaea531a --- /dev/null +++ b/include/osmocom/bsc/bsc_msc.h @@ -0,0 +1,77 @@ +/* Routines to talk to the MSC using the IPA Protocol */ +/* + * (C) 2010 by Holger Hans Peter Freyther + * (C) 2010 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef BSC_MSC_H +#define BSC_MSC_H + +#include +#include +#include +#include + +#include + +struct bsc_msc_dest { + struct llist_head list; + + char *ip; + int port; + int dscp; +}; + + +struct bsc_msc_connection { + /* FIXME: Remove stuff that is no longer needed! */ + struct osmo_wqueue write_queue; + int is_connected; + int is_authenticated; + int first_contact; + + struct llist_head *dests; + + const char *name; + + void (*connection_loss) (struct bsc_msc_connection *); + void (*connected) (struct bsc_msc_connection *); + struct osmo_timer_list reconnect_timer; + struct osmo_timer_list timeout_timer; + + struct msgb *pending_msg; + + /* Sigtran connection data */ + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *sccp_user; + struct osmo_sccp_addr g_calling_addr; + struct osmo_sccp_addr g_called_addr; + struct a_reset_ctx *reset; + + int conn_id_counter; +}; + +struct bsc_msc_connection *bsc_msc_create(void *ctx, struct llist_head *dest); +int bsc_msc_connect(struct bsc_msc_connection *); +void bsc_msc_schedule_connect(struct bsc_msc_connection *); + +void bsc_msc_lost(struct bsc_msc_connection *); + +struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len); + +#endif diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h new file mode 100644 index 000000000..4a283d165 --- /dev/null +++ b/include/osmocom/bsc/bsc_msc_data.h @@ -0,0 +1,174 @@ +/* + * Data for the true BSC + * + * (C) 2010-2015 by Holger Hans Peter Freyther + * (C) 2010-2015 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/* + * NOTE: This is about a *remote* MSC for OsmoBSC and is not part of libmsc. + */ + +#ifndef _OSMO_MSC_DATA_H +#define _OSMO_MSC_DATA_H + +#include "bsc_msc.h" + +#include +#include + + +#include +#include +#include +#include +#include +#include + +#include + +struct osmo_bsc_rf; +struct gsm_network; + +struct gsm_audio_support { + uint8_t hr : 1, + ver : 7; +}; + +enum { + MSC_CON_TYPE_NORMAL, + MSC_CON_TYPE_LOCAL, +}; + +/*! /brief Information on a remote MSC for libbsc. + */ +struct bsc_msc_data { + struct llist_head entry; + + /* Back pointer */ + struct gsm_network *network; + + int allow_emerg; + int type; + + /* local call routing */ + char *local_pref; + regex_t local_pref_reg; + + + /* Connection data */ + char *bsc_token; + uint8_t bsc_key[16]; + uint8_t bsc_key_present; + + int ping_timeout; + int pong_timeout; + struct osmo_timer_list ping_timer; + struct osmo_timer_list pong_timer; + int advanced_ping; + struct bsc_msc_connection *msc_con; + int core_mnc; + int core_mcc; + int core_lac; + int core_ci; + int rtp_base; + + /* audio codecs */ + struct gsm48_multi_rate_conf amr_conf; + struct gsm_audio_support **audio_support; + int audio_length; + + /* destinations */ + struct llist_head dests; + + /* ussd welcome text */ + char *ussd_welcome_txt; + + /* mgcp agent */ + struct osmo_wqueue mgcp_agent; + + int nr; + + /* ussd msc connection lost text */ + char *ussd_msc_lost_txt; + + /* ussd text when MSC has entered the grace period */ + char *ussd_grace_txt; + + char *acc_lst_name; + + /* Sigtran connection data */ + struct { + uint32_t cs7_instance; + bool cs7_instance_valid; + struct osmo_sccp_instance *sccp; + struct osmo_sccp_user *sccp_user; + + /* Holds a copy of the our local MSC address, + * this will be the sccp-address that is associated + * with the A interface of this particular BSC, + * this address is filled up by the VTY interface */ + struct osmo_sccp_addr bsc_addr; + char *bsc_addr_name; + + /* Holds a copy of the MSC address. This is the + * address of the MSC that handles the calls of + * this BSC. The address is configured via the + * VTY interface */ + struct osmo_sccp_addr msc_addr; + char *msc_addr_name; + + struct a_reset_ctx *reset; + } a; +}; + +/* + * Per BSC data. + */ +struct osmo_bsc_data { + struct gsm_network *network; + + /* msc configuration */ + struct llist_head mscs; + + /* rf ctl related bits */ + char *mid_call_txt; + int mid_call_timeout; + char *rf_ctrl_name; + struct osmo_bsc_rf *rf_ctrl; + int auto_off_timeout; + + /* ussd text when there is no MSC available */ + char *ussd_no_msc_txt; + + char *acc_lst_name; +}; + + +int osmo_bsc_msc_init(struct bsc_msc_data *msc); +int osmo_bsc_sccp_init(struct gsm_network *gsmnet); +int msc_queue_write(struct bsc_msc_connection *conn, struct msgb *msg, int proto); +int msc_queue_write_with_ping(struct bsc_msc_connection *, struct msgb *msg, int proto); + +int osmo_bsc_audio_init(struct gsm_network *network); + +struct bsc_msc_data *osmo_msc_data_find(struct gsm_network *, int); +struct bsc_msc_data *osmo_msc_data_alloc(struct gsm_network *, int); + + +#endif diff --git a/include/osmocom/bsc/bsc_msg_filter.h b/include/osmocom/bsc/bsc_msg_filter.h new file mode 100644 index 000000000..a9dedf43c --- /dev/null +++ b/include/osmocom/bsc/bsc_msg_filter.h @@ -0,0 +1,107 @@ +#pragma once + +#include +#include +#include +#include + +#include + +struct vty; +struct gsm48_hdr; + +struct bsc_filter_reject_cause { + int lu_reject_cause; + int cm_reject_cause; +}; + +struct bsc_filter_barr_entry { + struct rb_node node; + + char *imsi; + int cm_reject_cause; + int lu_reject_cause; +}; + +enum bsc_filter_acc_ctr { + ACC_LIST_LOCAL_FILTER, + ACC_LIST_GLOBAL_FILTER, +}; + +struct bsc_msg_acc_lst { + struct llist_head list; + + /* counter */ + struct rate_ctr_group *stats; + + /* the name of the list */ + const char *name; + struct llist_head fltr_list; +}; + +struct bsc_msg_acc_lst_entry { + struct llist_head list; + + /* the filter */ + char *imsi_allow; + regex_t imsi_allow_re; + char *imsi_deny; + regex_t imsi_deny_re; + + /* reject reasons for the access lists */ + int cm_reject_cause; + int lu_reject_cause; +}; + +enum { + FLT_CON_TYPE_NONE, + FLT_CON_TYPE_LU, + FLT_CON_TYPE_CM_SERV_REQ, + FLT_CON_TYPE_PAG_RESP, + FLT_CON_TYPE_SSA, + FLT_CON_TYPE_LOCAL_REJECT, + FLT_CON_TYPE_OTHER, +}; + + +struct bsc_filter_state { + char *imsi; + int imsi_checked; + int con_type; +}; + +struct bsc_filter_request { + void *ctx; + struct rb_root *black_list; + struct llist_head *access_lists; + const char *local_lst_name; + const char *global_lst_name; + int bsc_nr; +}; + + +int bsc_filter_barr_adapt(void *ctx, struct rb_root *rbtree, const struct osmo_config_list *); +int bsc_filter_barr_find(struct rb_root *root, const char *imsi, int *cm, int *lu); + +/** + * Content filtering. + */ +int bsc_msg_filter_initial(struct gsm48_hdr *hdr, size_t size, + struct bsc_filter_request *req, + int *con_type, char **imsi, + struct bsc_filter_reject_cause *cause); +int bsc_msg_filter_data(struct gsm48_hdr *hdr, size_t size, + struct bsc_filter_request *req, + struct bsc_filter_state *state, + struct bsc_filter_reject_cause *cause); + +/* IMSI allow/deny handling */ +struct bsc_msg_acc_lst *bsc_msg_acc_lst_find(struct llist_head *lst, const char *name); +struct bsc_msg_acc_lst *bsc_msg_acc_lst_get(void *ctx, struct llist_head *lst, const char *name); +void bsc_msg_acc_lst_delete(struct bsc_msg_acc_lst *lst); + +struct bsc_msg_acc_lst_entry *bsc_msg_acc_lst_entry_create(struct bsc_msg_acc_lst *); +int bsc_msg_acc_lst_check_allow(struct bsc_msg_acc_lst *lst, const char *imsi); + +void bsc_msg_lst_vty_init(void *ctx, struct llist_head *lst, int node); +void bsc_msg_acc_lst_write(struct vty *vty, struct bsc_msg_acc_lst *lst); diff --git a/include/osmocom/bsc/bsc_nat.h b/include/osmocom/bsc/bsc_nat.h new file mode 100644 index 000000000..452daf2ab --- /dev/null +++ b/include/osmocom/bsc/bsc_nat.h @@ -0,0 +1,462 @@ +/* + * (C) 2010-2012 by Holger Hans Peter Freyther + * (C) 2010-2012 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef BSC_NAT_H +#define BSC_NAT_H + +#include + +#include "bsc_msg_filter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DIR_BSC 1 +#define DIR_MSC 2 + +#define PAGIN_GROUP_UNASSIGNED -1 + +struct sccp_source_reference; +struct nat_sccp_connection; +struct bsc_nat_parsed; +struct bsc_nat; +struct bsc_nat_ussd_con; +struct nat_rewrite_rule; + +/* + * Is this terminated to the MSC, to the local machine (release + * handling for IMSI filtering) or to a USSD provider? + */ +enum { + NAT_CON_END_MSC, + NAT_CON_END_LOCAL, + NAT_CON_END_USSD, +}; + +/* + * Pending command entry + */ +struct bsc_cmd_list { + struct llist_head list_entry; + + struct osmo_timer_list timeout; + + /* The NATed ID used on the bsc_con*/ + int nat_id; + + /* The control connection from which the command originated */ + struct ctrl_connection *ccon; + + /* The command from the control connection */ + struct ctrl_cmd *cmd; +}; + +/* + * Per BSC data structure + */ +struct bsc_connection { + struct llist_head list_entry; + + /* do we know anything about this BSC? */ + int authenticated; + uint8_t last_rand[16]; + + /* the fd we use to communicate */ + struct osmo_wqueue write_queue; + + /* incoming message buffer */ + struct msgb *pending_msg; + + /* the BSS associated */ + struct bsc_config *cfg; + + /* a timeout node */ + struct osmo_timer_list id_timeout; + + /* pong timeout */ + struct osmo_timer_list ping_timeout; + struct osmo_timer_list pong_timeout; + + /* mgcp related code */ + char *_endpoint_status; + int number_multiplexes; + int max_endpoints; + int last_endpoint; + int next_transaction; + uint32_t pending_dlcx_count; + struct llist_head pending_dlcx; + + /* track the pending commands for this BSC */ + struct llist_head cmd_pending; + int last_id; + + /* a back pointer */ + struct bsc_nat *nat; +}; + +/** + * Stats per BSC + */ +struct bsc_config_stats { + struct rate_ctr_group *ctrg; +}; + +enum bsc_cfg_ctr { + BCFG_CTR_SCCP_CONN, + BCFG_CTR_SCCP_CALLS, + BCFG_CTR_NET_RECONN, + BCFG_CTR_DROPPED_SCCP, + BCFG_CTR_DROPPED_CALLS, + BCFG_CTR_REJECTED_CR, + BCFG_CTR_REJECTED_MSG, + BCFG_CTR_ILL_PACKET, + BCFG_CTR_CON_TYPE_LU, + BCFG_CTR_CON_CMSERV_RQ, + BCFG_CTR_CON_PAG_RESP, + BCFG_CTR_CON_SSA, + BCFG_CTR_CON_OTHER, +}; + +/** + * One BSC entry in the config + */ +struct bsc_config { + struct llist_head entry; + + uint8_t key[16]; + uint8_t key_present; + char *token; + int nr; + + char *description; + + /* imsi white and blacklist */ + char *acc_lst_name; + + int forbid_paging; + int paging_group; + + /* audio handling */ + int max_endpoints; + + /* used internally for reload handling */ + bool remove; + bool token_updated; + + /* backpointer */ + struct bsc_nat *nat; + + struct bsc_config_stats stats; + + struct llist_head lac_list; + + /* Osmux is enabled/disabled per BSC */ + int osmux; +}; + +struct bsc_lac_entry { + struct llist_head entry; + uint16_t lac; +}; + +struct bsc_nat_paging_group { + struct llist_head entry; + + /* list of lac entries */ + struct llist_head lists; + int nr; +}; + +/** + * BSCs point of view of endpoints + */ +struct bsc_endpoint { + /* the operation that is carried out */ + int transaction_state; + /* the pending transaction id */ + char *transaction_id; + /* the bsc we are talking to */ + struct bsc_connection *bsc; +}; + +/** + * Statistic for the nat. + */ +struct bsc_nat_statistics { + struct { + struct osmo_counter *conn; + struct osmo_counter *calls; + } sccp; + + struct { + struct osmo_counter *reconn; + struct osmo_counter *auth_fail; + } bsc; + + struct { + struct osmo_counter *reconn; + } msc; + + struct { + struct osmo_counter *reconn; + } ussd; +}; + +/** + * the structure of the "nat" network + */ +struct bsc_nat { + /* active SCCP connections that need patching */ + struct llist_head sccp_connections; + + /* active BSC connections that need patching */ + struct llist_head bsc_connections; + + /* access lists */ + struct llist_head access_lists; + + /* paging groups */ + struct llist_head paging_groups; + + /* known BSC's */ + struct llist_head bsc_configs; + int num_bsc; + int bsc_ip_dscp; + + /* MGCP config */ + struct mgcp_config *mgcp_cfg; + uint8_t mgcp_msg[4096]; + int mgcp_length; + int mgcp_ipa; + int sdp_ensure_amr_mode_set; + + /* msc things */ + struct llist_head dests; + struct bsc_msc_dest *main_dest; + struct bsc_msc_connection *msc_con; + char *token; + + /* timeouts */ + int auth_timeout; + int ping_timeout; + int pong_timeout; + + struct bsc_endpoint *bsc_endpoints; + + /* path to file with BSC config */ + char *include_file; + char *include_base; + char *resolved_path; + + /* filter */ + char *acc_lst_name; + + /* Barring of subscribers with a rb tree */ + struct rb_root imsi_black_list; + char *imsi_black_list_fn; + + /* number rewriting */ + char *num_rewr_name; + struct llist_head num_rewr; + char *num_rewr_post_name; + struct llist_head num_rewr_post; + + char *smsc_rewr_name; + struct llist_head smsc_rewr; + char *tpdest_match_name; + struct llist_head tpdest_match; + char *sms_clear_tp_srr_name; + struct llist_head sms_clear_tp_srr; + char *sms_num_rewr_name; + struct llist_head sms_num_rewr; + + /* more rewriting */ + char *num_rewr_trie_name; + struct nat_rewrite *num_rewr_trie; + + /* USSD messages we want to match */ + char *ussd_lst_name; + char *ussd_query; + regex_t ussd_query_re; + char *ussd_token; + char *ussd_local; + struct osmo_fd ussd_listen; + struct bsc_nat_ussd_con *ussd_con; + + /* for maintainenance */ + int blocked; + + /* statistics */ + struct bsc_nat_statistics stats; + + /* control interface */ + struct ctrl_handle *ctrl; +}; + +struct bsc_nat_ussd_con { + struct osmo_wqueue queue; + struct bsc_nat *nat; + int authorized; + + struct msgb *pending_msg; + + struct osmo_timer_list auth_timeout; +}; + +/* create and init the structures */ +struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, + unsigned int number); +struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num); +struct bsc_config *bsc_config_by_token(struct bsc_nat *nat, const char *token, int len); +void bsc_config_free(struct bsc_config *); +void bsc_config_add_lac(struct bsc_config *cfg, int lac); +void bsc_config_del_lac(struct bsc_config *cfg, int lac); +int bsc_config_handles_lac(struct bsc_config *cfg, int lac); + +struct bsc_nat *bsc_nat_alloc(void); +struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat); +void bsc_nat_set_msc_ip(struct bsc_nat *bsc, const char *ip); + +void sccp_connection_destroy(struct nat_sccp_connection *); +void bsc_close_connection(struct bsc_connection *); + +const char *bsc_con_type_to_string(int type); + +/** + * parse the given message into the above structure + */ +struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg); + +/** + * filter based on IP Access header in both directions + */ +int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed); +int bsc_nat_vty_init(struct bsc_nat *nat); +int bsc_nat_find_paging(struct msgb *msg, const uint8_t **,int *len); + +/** + * SCCP patching and handling + */ +struct nat_sccp_connection *create_sccp_src_ref(struct bsc_connection *bsc, struct bsc_nat_parsed *parsed); +int update_sccp_src_ref(struct nat_sccp_connection *sccp, struct bsc_nat_parsed *parsed); +void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed); +struct nat_sccp_connection *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *); +struct nat_sccp_connection *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_connection *); +struct nat_sccp_connection *bsc_nat_find_con_by_bsc(struct bsc_nat *, struct sccp_source_reference *); + +/** + * MGCP/Audio handling + */ +int bsc_mgcp_nr_multiplexes(int max_endpoints); +int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length); +int bsc_mgcp_assign_patch(struct nat_sccp_connection *, struct msgb *msg); +void bsc_mgcp_init(struct nat_sccp_connection *); +void bsc_mgcp_dlcx(struct nat_sccp_connection *); +void bsc_mgcp_free_endpoints(struct bsc_nat *nat); +int bsc_mgcp_nat_init(struct bsc_nat *nat); + +struct nat_sccp_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number); +struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip, + int port, int osmux, int *first_payload_type, int mode_set); +void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg); + +void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc); +int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]); +uint32_t bsc_mgcp_extract_ci(const char *resp); + + +int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id); +int bsc_do_write(struct osmo_wqueue *queue, struct msgb *msg, int id); +int bsc_write_msg(struct osmo_wqueue *queue, struct msgb *msg); +int bsc_write_cb(struct osmo_fd *bfd, struct msgb *msg); + +int bsc_nat_msc_is_connected(struct bsc_nat *nat); + +int bsc_conn_type_to_ctr(struct nat_sccp_connection *conn); + +struct gsm48_hdr *bsc_unpack_dtap(struct bsc_nat_parsed *parsed, struct msgb *msg, uint32_t *len); + +/** USSD filtering */ +int bsc_ussd_init(struct bsc_nat *nat); +int bsc_ussd_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parsed, struct msgb *msg); +int bsc_ussd_close_connections(struct bsc_nat *nat); + +struct msgb *bsc_nat_rewrite_msg(struct bsc_nat *nat, struct msgb *msg, struct bsc_nat_parsed *, const char *imsi); + +/** paging group handling */ +struct bsc_nat_paging_group *bsc_nat_paging_group_num(struct bsc_nat *nat, int group); +struct bsc_nat_paging_group *bsc_nat_paging_group_create(struct bsc_nat *nat, int group); +void bsc_nat_paging_group_delete(struct bsc_nat_paging_group *); +void bsc_nat_paging_group_add_lac(struct bsc_nat_paging_group *grp, int lac); +void bsc_nat_paging_group_del_lac(struct bsc_nat_paging_group *grp, int lac); + +/** + * Number rewriting support below + */ +struct bsc_nat_num_rewr_entry { + struct llist_head list; + + regex_t msisdn_reg; + regex_t num_reg; + + char *replace; + uint8_t is_prefix_lookup; +}; + +void bsc_nat_num_rewr_entry_adapt(void *ctx, struct llist_head *head, const struct osmo_config_list *); + +void bsc_nat_send_mgcp_to_msc(struct bsc_nat *bsc_nat, struct msgb *msg); +void bsc_nat_handle_mgcp(struct bsc_nat *bsc, struct msgb *msg); + +struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, + const char *bind_addr, int port); +void bsc_nat_ctrl_del_pending(struct bsc_cmd_list *pending); +int bsc_nat_handle_ctrlif_msg(struct bsc_connection *bsc, struct msgb *msg); + +int bsc_nat_extract_lac(struct bsc_connection *bsc, struct nat_sccp_connection *con, + struct bsc_nat_parsed *parsed, struct msgb *msg); + +int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg, + struct bsc_nat_parsed *, int *con_type, char **imsi, + struct bsc_filter_reject_cause *cause); +int bsc_nat_filter_dt(struct bsc_connection *bsc, struct msgb *msg, + struct nat_sccp_connection *con, struct bsc_nat_parsed *parsed, + struct bsc_filter_reject_cause *cause); + +/** + * CTRL interface helper + */ +void bsc_nat_inform_reject(struct bsc_connection *bsc, const char *imsi); + +/* + * Use for testing + */ +void bsc_nat_free(struct bsc_nat *nat); + +#endif diff --git a/include/osmocom/bsc/bsc_nat_callstats.h b/include/osmocom/bsc/bsc_nat_callstats.h new file mode 100644 index 000000000..64f9bfc0a --- /dev/null +++ b/include/osmocom/bsc/bsc_nat_callstats.h @@ -0,0 +1,55 @@ +/* + * (C) 2010-2012 by Holger Hans Peter Freyther + * (C) 2010-2012 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef BSC_NAT_CALLSTATS_H +#define BSC_NAT_CALLSTATS_H + +#include + +#include + +struct bsc_nat_call_stats { + struct llist_head entry; + + struct sccp_source_reference remote_ref; + struct sccp_source_reference src_ref; /* as seen by the MSC */ + + /* mgcp options */ + uint32_t ci; + int bts_rtp_port; + int net_rtp_port; + struct in_addr bts_addr; + struct in_addr net_addr; + + + /* as witnessed by the NAT */ + uint32_t net_ps; + uint32_t net_os; + uint32_t bts_pr; + uint32_t bts_or; + uint32_t bts_expected; + uint32_t bts_jitter; + int bts_loss; + + uint32_t trans_id; + int msc_endpoint; +}; + +#endif diff --git a/include/osmocom/bsc/bsc_nat_sccp.h b/include/osmocom/bsc/bsc_nat_sccp.h new file mode 100644 index 000000000..082466408 --- /dev/null +++ b/include/osmocom/bsc/bsc_nat_sccp.h @@ -0,0 +1,105 @@ +/* NAT utilities using SCCP types */ +/* + * (C) 2010 by Holger Hans Peter Freyther + * (C) 2010 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef BSC_NAT_SCCP_H +#define BSC_NAT_SCCP_H + +#include "bsc_msg_filter.h" + +#include + +/* + * For the NAT we will need to analyze and later patch + * the received message. This would require us to parse + * the IPA and SCCP header twice. Instead of doing this + * we will have one analyze structure and have the patching + * and filter operate on the same structure. + */ +struct bsc_nat_parsed { + /* ip access prototype */ + int ipa_proto; + + /* source local reference */ + struct sccp_source_reference *src_local_ref; + + /* destination local reference */ + struct sccp_source_reference *dest_local_ref; + + /* original value */ + struct sccp_source_reference original_dest_ref; + + /* called ssn number */ + int called_ssn; + + /* calling ssn number */ + int calling_ssn; + + /* sccp message type */ + int sccp_type; + + /* bssap type, e.g. 0 for BSS Management */ + int bssap; + + /* the gsm0808 message type */ + int gsm_type; +}; + +/* + * Per SCCP source local reference patch table. It needs to + * be updated on new SCCP connections, connection confirm and reject, + * and on the loss of the BSC connection. + */ +struct nat_sccp_connection { + struct llist_head list_entry; + + struct bsc_connection *bsc; + struct bsc_msc_connection *msc_con; + + struct sccp_source_reference real_ref; + struct sccp_source_reference patched_ref; + struct sccp_source_reference remote_ref; + int has_remote_ref; + + /* status */ + int con_local; + int authorized; + + struct bsc_filter_state filter_state; + + uint16_t lac; + uint16_t ci; + + /* remember which Transactions we run over the bypass */ + char ussd_ti[8]; + + /* + * audio handling. Remember if we have ever send a CRCX, + * remember the endpoint used by the MSC and BSC. + */ + int msc_endp; + int bsc_endp; + + /* timeout handling */ + struct timespec creation_time; +}; + + +#endif diff --git a/include/osmocom/bsc/bsc_rll.h b/include/osmocom/bsc/bsc_rll.h new file mode 100644 index 000000000..3afe4a8f3 --- /dev/null +++ b/include/osmocom/bsc/bsc_rll.h @@ -0,0 +1,19 @@ +#ifndef _BSC_RLL_H +#define _BSC_RLL_H + +#include + +enum bsc_rllr_ind { + BSC_RLLR_IND_EST_CONF, + BSC_RLLR_IND_REL_IND, + BSC_RLLR_IND_ERR_IND, + BSC_RLLR_IND_TIMEOUT, +}; + +int rll_establish(struct gsm_lchan *lchan, uint8_t link_id, + void (*cb)(struct gsm_lchan *, uint8_t, void *, + enum bsc_rllr_ind), + void *data); +void rll_indication(struct gsm_lchan *lchan, uint8_t link_id, uint8_t type); + +#endif /* _BSC_RLL_H */ diff --git a/include/osmocom/bsc/bsc_subscriber.h b/include/osmocom/bsc/bsc_subscriber.h new file mode 100644 index 000000000..324734f9a --- /dev/null +++ b/include/osmocom/bsc/bsc_subscriber.h @@ -0,0 +1,43 @@ +/* GSM subscriber details for use in BSC land */ + +#pragma once + +#include + +#include +#include + +struct log_target; + +struct bsc_subscr { + struct llist_head entry; + int use_count; + + char imsi[GSM23003_IMSI_MAX_DIGITS+1]; + uint32_t tmsi; + uint16_t lac; +}; + +const char *bsc_subscr_name(struct bsc_subscr *bsub); + +struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list, + const char *imsi); +struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list, + uint32_t tmsi); + +struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list, + const char *imsi); +struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list, + uint32_t tmsi); + +void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi); + +struct bsc_subscr *_bsc_subscr_get(struct bsc_subscr *bsub, + const char *file, int line); +struct bsc_subscr *_bsc_subscr_put(struct bsc_subscr *bsub, + const char *file, int line); +#define bsc_subscr_get(bsub) _bsc_subscr_get(bsub, __BASE_FILE__, __LINE__) +#define bsc_subscr_put(bsub) _bsc_subscr_put(bsub, __BASE_FILE__, __LINE__) + +void log_set_filter_bsc_subscr(struct log_target *target, + struct bsc_subscr *bsub); diff --git a/include/osmocom/bsc/bss.h b/include/osmocom/bsc/bss.h new file mode 100644 index 000000000..b12487d02 --- /dev/null +++ b/include/osmocom/bsc/bss.h @@ -0,0 +1,20 @@ +#ifndef _BSS_H_ +#define _BSS_H_ + +#include + +struct msgb; + +/* start and stop network */ +extern int bsc_network_alloc(mncc_recv_cb_t mncc_recv); +extern int bsc_network_configure(const char *cfg_file); +extern int bsc_shutdown_net(struct gsm_network *net); + +/* register all supported BTS */ +extern int bts_init(void); +extern int bts_model_bs11_init(void); +extern int bts_model_rbs2k_init(void); +extern int bts_model_nanobts_init(void); +extern int bts_model_nokia_site_init(void); +extern int bts_model_sysmobts_init(void); +#endif diff --git a/include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h b/include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h new file mode 100644 index 000000000..bc7860b2d --- /dev/null +++ b/include/osmocom/bsc/bts_ipaccess_nanobts_omlattr.h @@ -0,0 +1,32 @@ +/* OML attribute table generator for ipaccess nanobts */ + +/* (C) 2016 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +struct msgb *nanobts_attr_bts_get(struct gsm_bts *bts); +struct msgb *nanobts_attr_nse_get(struct gsm_bts *bts); +struct msgb *nanobts_attr_cell_get(struct gsm_bts *bts); +struct msgb *nanobts_attr_nscv_get(struct gsm_bts *bts); +struct msgb *nanobts_attr_radio_get(struct gsm_bts *bts, + struct gsm_bts_trx *trx); diff --git a/include/osmocom/bsc/chan_alloc.h b/include/osmocom/bsc/chan_alloc.h new file mode 100644 index 000000000..7388e14c5 --- /dev/null +++ b/include/osmocom/bsc/chan_alloc.h @@ -0,0 +1,54 @@ +/* Management functions to allocate/release struct gsm_lchan */ +/* (C) 2008 by Harald Welte + * (C) 2009 by Holger Hans Peter Freyther + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#ifndef _CHAN_ALLOC_H +#define _CHAN_ALLOC_H + +#include "gsm_data.h" + +struct gsm_subscriber_connection; + +/* Find an allocated channel for a specified subscriber */ +struct gsm_subscriber_connection *connection_for_subscr(struct vlr_subscr *vsub); + +/* Allocate a logical channel (SDCCH, TCH, ...) */ +struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type, int allow_bigger); + +/* Free a logical channel (SDCCH, TCH, ...) */ +void lchan_free(struct gsm_lchan *lchan); +void lchan_reset(struct gsm_lchan *lchan); + +/* Release the given lchan */ +int lchan_release(struct gsm_lchan *lchan, int sacch_deact, enum rsl_rel_mode release_mode); + +struct load_counter { + unsigned int total; + unsigned int used; +}; + +struct pchan_load { + struct load_counter pchan[_GSM_PCHAN_MAX]; +}; + +void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts); +void network_chan_load(struct pchan_load *pl, struct gsm_network *net); + +int trx_is_usable(struct gsm_bts_trx *trx); + +#endif /* _CHAN_ALLOC_H */ diff --git a/include/osmocom/bsc/common.h b/include/osmocom/bsc/common.h new file mode 100644 index 000000000..d91b3d39e --- /dev/null +++ b/include/osmocom/bsc/common.h @@ -0,0 +1,6 @@ +#pragma once + +enum nsap_addr_enc { + NSAP_ADDR_ENC_X213, + NSAP_ADDR_ENC_V4RAW, +}; diff --git a/include/osmocom/bsc/common_bsc.h b/include/osmocom/bsc/common_bsc.h new file mode 100644 index 000000000..08394e989 --- /dev/null +++ b/include/osmocom/bsc/common_bsc.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +struct gsm_network *bsc_network_init(void *ctx, + uint16_t country_code, + uint16_t network_code, + mncc_recv_cb_t mncc_recv); diff --git a/include/osmocom/bsc/common_cs.h b/include/osmocom/bsc/common_cs.h new file mode 100644 index 000000000..09a4b0224 --- /dev/null +++ b/include/osmocom/bsc/common_cs.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +struct msgb; +struct gsm_network; + +typedef int (*mncc_recv_cb_t)(struct gsm_network *, struct msgb *); + +struct vty; + +#define MAX_A5_KEY_LEN (128/8) + +struct gsm_encr { + uint8_t alg_id; + uint8_t key_len; + uint8_t key[MAX_A5_KEY_LEN]; +}; + +struct gsm_network *gsm_network_init(void *ctx, + uint16_t country_code, + uint16_t network_code, + mncc_recv_cb_t mncc_recv); + +int common_cs_vty_init(struct gsm_network *network, + int (* config_write_net )(struct vty *)); +struct gsm_network *gsmnet_from_vty(struct vty *v); + +struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value); +int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type); +int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length, + char *mi_string, uint8_t *mi_type); +struct msgb *gsm48_create_loc_upd_rej(uint8_t cause); diff --git a/include/osmocom/bsc/crc24.h b/include/osmocom/bsc/crc24.h new file mode 100644 index 000000000..756638c03 --- /dev/null +++ b/include/osmocom/bsc/crc24.h @@ -0,0 +1,10 @@ +#ifndef _CRC24_H +#define _CRC24_H + +#include + +#define INIT_CRC24 0xffffff + +uint32_t crc24_calc(uint32_t fcs, uint8_t *cp, unsigned int len); + +#endif diff --git a/include/osmocom/bsc/ctrl.h b/include/osmocom/bsc/ctrl.h new file mode 100644 index 000000000..c5ac21092 --- /dev/null +++ b/include/osmocom/bsc/ctrl.h @@ -0,0 +1,4 @@ +#pragma once + +struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, + const char *bind_addr, uint16_t port); diff --git a/include/osmocom/bsc/debug.h b/include/osmocom/bsc/debug.h new file mode 100644 index 000000000..65e197d52 --- /dev/null +++ b/include/osmocom/bsc/debug.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +#define DEBUG +#include + +/* Debug Areas of the code */ +enum { + DRLL, + DCC, + DMM, + DRR, + DRSL, + DNM, + DMNCC, + DPAG, + DMEAS, + DSCCP, + DMSC, + DMGCP, + DHO, + DDB, + DREF, + DGPRS, + DNS, + DBSSGP, + DLLC, + DSNDCP, + DSLHC, + DNAT, + DCTRL, + DSMPP, + DFILTER, + DGTPHUB, + DRANAP, + DSUA, + DV42BIS, + DPCU, + DVLR, + DIUCS, + DSIGTRAN, + Debug_LastEntry, +}; + +extern const struct log_info log_info; diff --git a/include/osmocom/bsc/e1_config.h b/include/osmocom/bsc/e1_config.h new file mode 100644 index 000000000..909e3cc8a --- /dev/null +++ b/include/osmocom/bsc/e1_config.h @@ -0,0 +1,11 @@ +#ifndef _E1_CONFIG_H +#define _E1_CONFIG_H + +#include + +int e1_reconfig_ts(struct gsm_bts_trx_ts *ts); +int e1_reconfig_trx(struct gsm_bts_trx *trx); +int e1_reconfig_bts(struct gsm_bts *bts); + +#endif /* _E1_CONFIG_H */ + diff --git a/include/osmocom/bsc/gsm_04_08_utils.h b/include/osmocom/bsc/gsm_04_08_utils.h new file mode 100644 index 000000000..625f173ca --- /dev/null +++ b/include/osmocom/bsc/gsm_04_08_utils.h @@ -0,0 +1,32 @@ +#pragma once + +void gsm_net_update_ctype(struct gsm_network *network); +enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra); +int get_reason_by_chreq(uint8_t ra, int neci); +int gsm48_send_rr_release(struct gsm_lchan *lchan); +int send_siemens_mrpci(struct gsm_lchan *lchan, + uint8_t *classmark2_lv); +int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, + struct msgb *msg, struct bsc_subscr *bsub); +int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv); +void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd, + const struct gsm_lchan *lchan); +int gsm48_multirate_config(uint8_t *lv, const struct amr_multirate_conf *mr, const struct amr_mode *modes); +int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan, + uint8_t power_command, uint8_t ho_ref); +int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_command); +int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode); +int gsm48_rx_rr_modif_ack(struct msgb *msg); +int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg); +int gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn); +int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value); + +#define GSM48_ALLOC_SIZE 2048 +#define GSM48_ALLOC_HEADROOM 256 + +static inline struct msgb *gsm48_msgb_alloc_name(const char *name) +{ + return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM, + name); +} diff --git a/include/osmocom/bsc/gsm_04_80.h b/include/osmocom/bsc/gsm_04_80.h new file mode 100644 index 000000000..d65f640bc --- /dev/null +++ b/include/osmocom/bsc/gsm_04_80.h @@ -0,0 +1,25 @@ +#ifndef _GSM_04_80_H +#define _GSM_04_80_H + +#include +#include +#include + +struct gsm_subscriber_connection; + +int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn, + const struct msgb *in_msg, const char* response_text, + const struct ss_request *req); +int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn, + const struct msgb *msg, + const struct ss_request *request); + +int msc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level, + const char *text); +int msc_send_ussd_release_complete(struct gsm_subscriber_connection *conn); + +int bsc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level, + const char *text); +int bsc_send_ussd_release_complete(struct gsm_subscriber_connection *conn); + +#endif diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h new file mode 100644 index 000000000..ef041d665 --- /dev/null +++ b/include/osmocom/bsc/gsm_data.h @@ -0,0 +1,692 @@ +#ifndef _GSM_DATA_H +#define _GSM_DATA_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + +/** annotations for msgb ownership */ +#define __uses + +#define OBSC_NM_W_ACK_CB(__msgb) (__msgb)->cb[3] + +struct mncc_sock_state; +struct gsm_subscriber_group; +struct bsc_subscr; +struct vlr_instance; +struct vlr_subscr; +struct ranap_ue_conn_ctx; +struct gprs_ra_id; + +#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3] + +#define tmsi_from_string(str) strtoul(str, NULL, 10) + +/* 3-bit long values */ +#define EARFCN_PRIO_INVALID 8 +#define EARFCN_MEAS_BW_INVALID 8 +/* 5-bit long values */ +#define EARFCN_QRXLV_INVALID 32 +#define EARFCN_THRESH_LOW_INVALID 32 + +enum gsm_security_event { + GSM_SECURITY_NOAVAIL, + GSM_SECURITY_AUTH_FAILED, + GSM_SECURITY_SUCCEEDED, + GSM_SECURITY_ALREADY, +}; + +struct msgb; +typedef int gsm_cbfn(unsigned int hooknum, + unsigned int event, + struct msgb *msg, + void *data, void *param); + +/* Real authentication information containing Ki */ +enum gsm_auth_algo { + AUTH_ALGO_NONE, + AUTH_ALGO_XOR, + AUTH_ALGO_COMP128v1, +}; + +struct gsm_auth_info { + enum gsm_auth_algo auth_algo; + unsigned int a3a8_ki_len; + uint8_t a3a8_ki[16]; +}; + +struct gsm_auth_tuple { + int use_count; + int key_seq; + struct osmo_auth_vector vec; +}; +#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */ + +/* + * AUTHENTICATION/CIPHERING state + */ +struct gsm_security_operation { + struct gsm_auth_tuple atuple; + gsm_cbfn *cb; + void *cb_data; +}; + +/* + * A dummy to keep a connection up for at least + * a couple of seconds to work around MSC issues. + */ +struct gsm_anchor_operation { + struct osmo_timer_list timeout; +}; + +/* 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 { + uint16_t arfcn; + uint8_t bsic; + uint8_t rxlev[MAX_WIN_NEIGH_AVG]; + unsigned int rxlev_cnt; + uint8_t last_seen_nr; +}; + +enum ran_type { + RAN_UNKNOWN, + RAN_GERAN_A, /* 2G / A-interface */ + RAN_UTRAN_IU, /* 3G / Iu-interface (IuCS or IuPS) */ +}; + +extern const struct value_string ran_type_names[]; +static inline const char *ran_type_name(enum ran_type val) +{ return get_value_string(ran_type_names, val); } + +struct gsm_classmark { + bool classmark1_set; + struct gsm48_classmark1 classmark1; + uint8_t classmark2_len; + uint8_t classmark2[3]; + uint8_t classmark3_len; + uint8_t classmark3[14]; /* if cm3 gets extended by spec, it will be truncated */ +}; + +enum integrity_protection_state { + INTEGRITY_PROTECTION_NONE = 0, + INTEGRITY_PROTECTION_IK = 1, + INTEGRITY_PROTECTION_IK_CK = 2, +}; + +/* active radio connection of a mobile subscriber */ +struct gsm_subscriber_connection { + /* global linked list of subscriber_connections */ + struct llist_head entry; + + /* usage count. If this drops to zero, we start the release + * towards A/Iu */ + uint32_t use_count; + + /* The MS has opened the conn with a CM Service Request, and we shall + * keep it open for an actual request (or until timeout). */ + bool received_cm_service_request; + + /* libbsc subscriber information (if available) */ + struct bsc_subscr *bsub; + + /* libmsc/libvlr subscriber information (if available) */ + struct vlr_subscr *vsub; + + /* LU expiration handling */ + uint8_t expire_timer_stopped; + /* SMS helpers for libmsc */ + uint8_t next_rp_ref; + + /* + * Operations that have a state and might be pending + */ + struct gsm_security_operation *sec_operation; + struct gsm_anchor_operation *anch_operation; + + struct osmo_fsm_inst *conn_fsm; + + /* Are we part of a special "silent" call */ + int silent_call; + + /* MNCC rtp bridge markers */ + int mncc_rtp_bridge; + int mncc_rtp_create_pending; + int mncc_rtp_connect_pending; + + /* bsc structures */ + struct osmo_bsc_sccp_con *sccp_con; /* BSC */ + + /* back pointers */ + struct gsm_network *network; + + bool in_release; + struct gsm_lchan *lchan; /* BSC */ + struct gsm_lchan *ho_lchan; /* BSC */ + struct gsm_bts *bts; /* BSC */ + + /* for assignment handling */ + struct osmo_timer_list T10; /* BSC */ + struct gsm_lchan *secondary_lchan; /* BSC */ + + /* connected via 2G or 3G? */ + enum ran_type via_ran; + + struct gsm_classmark classmark; + + uint16_t lac; + struct gsm_encr encr; + + struct { + unsigned int mgcp_rtp_endpoint; + uint16_t port_subscr; + uint16_t port_cn; + } rtp; + + /* which Iu-CS connection, if any. */ + struct { + struct ranap_ue_conn_ctx *ue_ctx; + uint8_t rab_id; + } iu; + + struct { + /* A pointer to the SCCP user that handles + * the SCCP connections for this subscriber + * connection */ + struct osmo_sccp_user *scu; + + /* The address of the BSC that is associated + * with this subscriber connection */ + struct osmo_sccp_addr bsc_addr; + + /* The connection identifier that is used + * to reference the SCCP connection that is + * associated with this subscriber connection */ + int conn_id; + } a; +}; + + +#define ROLE_BSC +#include "gsm_data_shared.h" + + +enum { + BSC_CTR_CHREQ_TOTAL, + BSC_CTR_CHREQ_NO_CHANNEL, + BSC_CTR_HANDOVER_ATTEMPTED, + BSC_CTR_HANDOVER_NO_CHANNEL, + BSC_CTR_HANDOVER_TIMEOUT, + BSC_CTR_HANDOVER_COMPLETED, + BSC_CTR_HANDOVER_FAILED, + BSC_CTR_PAGING_ATTEMPTED, + BSC_CTR_PAGING_DETACHED, + BSC_CTR_PAGING_COMPLETED, + BSC_CTR_PAGING_EXPIRED, + BSC_CTR_CHAN_RF_FAIL, + BSC_CTR_CHAN_RLL_ERR, + BSC_CTR_BTS_OML_FAIL, + BSC_CTR_BTS_RSL_FAIL, + BSC_CTR_CODEC_AMR_F, + BSC_CTR_CODEC_AMR_H, + BSC_CTR_CODEC_EFR, + BSC_CTR_CODEC_V1_FR, + BSC_CTR_CODEC_V1_HR, +}; + +static const struct rate_ctr_desc bsc_ctr_description[] = { + [BSC_CTR_CHREQ_TOTAL] = {"chreq.total", "Received channel requests."}, + [BSC_CTR_CHREQ_NO_CHANNEL] = {"chreq.no_channel", "Sent to MS no channel available."}, + [BSC_CTR_HANDOVER_ATTEMPTED] = {"handover.attempted", "Received handover attempts."}, + [BSC_CTR_HANDOVER_NO_CHANNEL] = {"handover.no_channel", "Sent no channel available responses."}, + [BSC_CTR_HANDOVER_TIMEOUT] = {"handover.timeout", "Count the amount of timeouts of timer T3103."}, + [BSC_CTR_HANDOVER_COMPLETED] = {"handover.completed", "Received handover completed."}, + [BSC_CTR_HANDOVER_FAILED] = {"handover.failed", "Receive HO FAIL messages."}, + [BSC_CTR_PAGING_ATTEMPTED] = {"paging.attempted", "Paging attempts for a MS."}, + [BSC_CTR_PAGING_DETACHED] = {"paging.detached", "Counts the amount of paging attempts which couldn't sent out any paging request because no responsible bts found."}, + [BSC_CTR_PAGING_COMPLETED] = {"paging.completed", "Paging successful completed."}, + [BSC_CTR_PAGING_EXPIRED] = {"paging.expired", "Paging Request expired because of timeout T3113."}, + [BSC_CTR_CHAN_RF_FAIL] = {"chan.rf_fail", "Received a RF failure indication from BTS."}, + [BSC_CTR_CHAN_RLL_ERR] = {"chan.rll_err", "Received a RLL failure with T200 cause from BTS."}, + [BSC_CTR_BTS_OML_FAIL] = {"bts.oml_fail", "Received a TEI down on a OML link."}, + [BSC_CTR_BTS_RSL_FAIL] = {"bts.rsl_fail", "Received a TEI down on a OML link."}, + [BSC_CTR_CODEC_AMR_F] = {"bts.codec_amr_f", "Count the usage of AMR/F codec by channel mode requested."}, + [BSC_CTR_CODEC_AMR_H] = {"bts.codec_amr_h", "Count the usage of AMR/H codec by channel mode requested."}, + [BSC_CTR_CODEC_EFR] = {"bts.codec_efr", "Count the usage of EFR codec by channel mode requested."}, + [BSC_CTR_CODEC_V1_FR] = {"bts.codec_fr", "Count the usage of FR codec by channel mode requested."}, + [BSC_CTR_CODEC_V1_HR] = {"bts.codec_hr", "Count the usage of HR codec by channel mode requested."}, +}; + +enum { + MSC_CTR_LOC_UPDATE_TYPE_ATTACH, + MSC_CTR_LOC_UPDATE_TYPE_NORMAL, + MSC_CTR_LOC_UPDATE_TYPE_PERIODIC, + MSC_CTR_LOC_UPDATE_TYPE_DETACH, + MSC_CTR_LOC_UPDATE_FAILED, + MSC_CTR_LOC_UPDATE_COMPLETED, + MSC_CTR_SMS_SUBMITTED, + MSC_CTR_SMS_NO_RECEIVER, + MSC_CTR_SMS_DELIVERED, + MSC_CTR_SMS_RP_ERR_MEM, + MSC_CTR_SMS_RP_ERR_OTHER, + MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR, + MSC_CTR_CALL_MO_SETUP, + MSC_CTR_CALL_MO_CONNECT_ACK, + MSC_CTR_CALL_MT_SETUP, + MSC_CTR_CALL_MT_CONNECT, + MSC_CTR_CALL_ACTIVE, + MSC_CTR_CALL_COMPLETE, + MSC_CTR_CALL_INCOMPLETE, +}; + +static const struct rate_ctr_desc msc_ctr_description[] = { + [MSC_CTR_LOC_UPDATE_TYPE_ATTACH] = {"loc_update_type.attach", "Received location update imsi attach requests."}, + [MSC_CTR_LOC_UPDATE_TYPE_NORMAL] = {"loc_update_type.normal", "Received location update normal requests."}, + [MSC_CTR_LOC_UPDATE_TYPE_PERIODIC] = {"loc_update_type.periodic", "Received location update periodic requests."}, + [MSC_CTR_LOC_UPDATE_TYPE_DETACH] = {"loc_update_type.detach", "Received location update detach indication."}, + [MSC_CTR_LOC_UPDATE_FAILED] = {"loc_update_resp.failed", "Rejected location updates."}, + [MSC_CTR_LOC_UPDATE_COMPLETED] = {"loc_update_resp.completed", "Successful location updates."}, + [MSC_CTR_SMS_SUBMITTED] = {"sms.submitted", "Received a RPDU from a MS (MO)."}, + [MSC_CTR_SMS_NO_RECEIVER] = {"sms.no_receiver", "Counts SMS which couldn't routed because no receiver found."}, + [MSC_CTR_SMS_DELIVERED] = {"sms.delivered", "Global SMS Deliver attempts."}, + [MSC_CTR_SMS_RP_ERR_MEM] = {"sms.rp_err_mem", "CAUSE_MT_MEM_EXCEEDED errors of MS responses on a sms deliver attempt."}, + [MSC_CTR_SMS_RP_ERR_OTHER] = {"sms.rp_err_other", "Other error of MS responses on a sms delive attempt."}, + [MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR] = {"sms.deliver_unknown_error", "Unknown error occured during sms delivery."}, + /* FIXME: count also sms delivered */ + [MSC_CTR_CALL_MO_SETUP] = {"call.mo_setup", "Received setup requests from a MS to init a MO call."}, + [MSC_CTR_CALL_MO_CONNECT_ACK] = {"call.mo_connect_ack", "Received a connect ack from MS of a MO call. Call is now succesful connected up."}, + [MSC_CTR_CALL_MT_SETUP] = {"call.mt_setup", "Sent setup requests to the MS (MT)."}, + [MSC_CTR_CALL_MT_CONNECT] = {"call.mt_connect", "Sent a connect to the MS (MT)."}, + [MSC_CTR_CALL_ACTIVE] = {"call.active", "Count total amount of calls that ever reached active state."}, + [MSC_CTR_CALL_COMPLETE] = {"call.complete", "Count total amount of calls which got terminated by disconnect req or ind after reaching active state."}, + [MSC_CTR_CALL_INCOMPLETE] = {"call.incomplete", "Count total amount of call which got terminated by any other reason after reaching active state."}, +}; + + +static const struct rate_ctr_group_desc bsc_ctrg_desc = { + "bsc", + "base station controller", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(bsc_ctr_description), + bsc_ctr_description, +}; + +static const struct rate_ctr_group_desc msc_ctrg_desc = { + "msc", + "mobile switching center", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(msc_ctr_description), + msc_ctr_description, +}; + +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 */ + GSM_AUTH_POLICY_TOKEN, /* accept first, send token per sms, then revoke authorization */ + GSM_AUTH_POLICY_REGEXP, /* accept IMSIs matching given regexp */ +}; + +#define GSM_T3101_DEFAULT 10 /* s */ +#define GSM_T3103_DEFAULT 5 /* s */ +#define GSM_T3105_DEFAULT 100 /* ms */ +#define GSM_T3107_DEFAULT 5 /* s */ +#define GSM_T3109_DEFAULT 19 /* s, must be 2s + radio_link_timeout*0.48 */ +#define GSM_T3111_DEFAULT 2 /* s */ +#define GSM_T3113_DEFAULT 60 +#define GSM_T3115_DEFAULT 10 +#define GSM_T3117_DEFAULT 10 +#define GSM_T3119_DEFAULT 10 +#define GSM_T3122_DEFAULT 10 +#define GSM_T3141_DEFAULT 10 + +struct gsm_tz { + int override; /* if 0, use system's time zone instead. */ + int hr; /* hour */ + int mn; /* minute */ + int dst; /* daylight savings */ +}; + +struct gsm_network { + /* TODO MSCSPLIT the gsm_network struct is basically a kitchen sink for + * global settings and variables, "madly" mixing BSC and MSC stuff. Split + * this in e.g. struct osmo_bsc and struct osmo_msc, with the things + * these have in common, like country and network code, put in yet + * separate structs and placed as members in osmo_bsc and osmo_msc. */ + + /* global parameters */ + uint16_t country_code; + uint16_t network_code; + char *name_long; + char *name_short; + enum gsm_auth_policy auth_policy; + regex_t authorized_regexp; + char *authorized_reg_str; + enum gsm48_reject_value reject_cause; + int a5_encryption; + bool authentication_required; + 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 rate_ctr_group *bsc_ctrs; + struct rate_ctr_group *msc_ctrs; + struct osmo_counter *active_calls; + + /* layer 4 */ + struct mncc_sock_state *mncc_state; + mncc_recv_cb_t mncc_recv; + struct llist_head upqueue; + /* + * TODO: Move the trans_list into the subscriber connection and + * create a pending list for MT transactions. These exist before + * we have a subscriber connection. + */ + struct llist_head trans_list; + struct bsc_api *bsc_api; + + unsigned int num_bts; + struct llist_head bts_list; + + /* timer values */ + int T3101; + int T3103; + int T3105; + int T3107; + int T3109; + int T3111; + int T3113; + int T3115; + int T3117; + int T3119; + int T3122; + int T3141; + + /* timer to expire old location updates */ + struct osmo_timer_list subscr_expire_timer; + + /* Radio Resource Location Protocol (TS 04.31) */ + struct { + enum rrlp_mode mode; + } rrlp; + + enum gsm_chan_t ctype_by_chreq[18]; + + /* Use a TCH for handling requests of type paging any */ + int pag_any_tch; + + /* MSC data in case we are a true BSC */ + struct osmo_bsc_data *bsc_data; + + struct gsm_sms_queue *sms_queue; + + /* control interface */ + struct ctrl_handle *ctrl; + + /* Allow or disallow TCH/F on dynamic TCH/F_TCH/H_PDCH; OS#1778 */ + bool dyn_ts_allow_tch_f; + + /* all active subscriber connections. */ + struct llist_head subscr_conns; + + /* if override is nonzero, this timezone data is used for all MM + * contexts. */ + /* TODO: in OsmoNITB, tz-override used to be BTS-specific. To enable + * BTS|RNC specific timezone overrides for multi-tz networks in + * OsmoMSC, this should be tied to the location area code (LAC). */ + struct gsm_tz tz; + + /* List of all struct bsc_subscr used in libbsc. This llist_head is + * allocated so that the llist_head pointer itself can serve as a + * talloc context (useful to not have to pass the entire gsm_network + * struct to the bsc_subscr_* API, and for bsc_susbscr unit tests to + * not require gsm_data.h). In an MSC-without-BSC environment, this + * pointer is NULL to indicate absence of a bsc_subscribers list. */ + struct llist_head *bsc_subscribers; + + /* MSC: GSUP server address of the HLR */ + const char *gsup_server_addr_str; + uint16_t gsup_server_port; + + struct vlr_instance *vlr; + + /* Periodic location update default value */ + uint8_t t3212; + + struct { + struct mgcpgw_client_conf conf; + struct mgcpgw_client *client; + } mgcpgw; + + struct { + /* CS7 instance id number (set via VTY) */ + uint32_t cs7_instance; + int rab_assign_addr_enc; + struct osmo_sccp_instance *sccp; + } iu; + + struct { + /* CS7 instance id number (set via VTY) */ + uint32_t cs7_instance; + /* A list with the context information about + * all BSCs we have connections with */ + struct llist_head bscs; + struct osmo_sccp_instance *sccp; + } a; +}; + +struct osmo_esme; + +enum gsm_sms_source_id { + SMS_SOURCE_UNKNOWN = 0, + SMS_SOURCE_MS, /* received from MS */ + SMS_SOURCE_VTY, /* received from VTY */ + SMS_SOURCE_SMPP, /* received via SMPP */ +}; + +#define SMS_HDR_SIZE 128 +#define SMS_TEXT_SIZE 256 + +struct gsm_sms_addr { + uint8_t ton; + uint8_t npi; + char addr[21+1]; +}; + +struct gsm_sms { + unsigned long long id; + struct vlr_subscr *receiver; + struct gsm_sms_addr src, dst; + enum gsm_sms_source_id source; + + struct { + uint8_t transaction_id; + uint32_t msg_ref; + } gsm411; + + struct { + struct osmo_esme *esme; + uint32_t sequence_nr; + int transaction_mode; + char msg_id[16]; + } smpp; + + unsigned long validity_minutes; + time_t created; + bool is_report; + uint8_t reply_path_req; + uint8_t status_rep_req; + uint8_t ud_hdr_ind; + uint8_t protocol_id; + uint8_t data_coding_scheme; + uint8_t msg_ref; + uint8_t user_data_len; + uint8_t user_data[SMS_TEXT_SIZE]; + + char text[SMS_TEXT_SIZE]; +}; + +extern void talloc_ctx_init(void *ctx_root); + +int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type); + +enum gsm_bts_type parse_btstype(const char *arg); +const char *btstype2str(enum gsm_bts_type type); +struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac, + struct gsm_bts *start_bts); + +extern void *tall_bsc_ctx; +extern int ipacc_rtp_direct; + +/* this actaully refers to the IPA transport, not the BTS model */ +static inline int is_ipaccess_bts(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_NANOBTS: + case GSM_BTS_TYPE_OSMOBTS: + return 1; + default: + break; + } + return 0; +} + +static inline int is_sysmobts_v2(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_OSMOBTS: + return 1; + default: + break; + } + return 0; +} + +static inline int is_siemens_bts(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_BS11: + return 1; + default: + break; + } + + return 0; +} + +static inline int is_nokia_bts(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_NOKIA_SITE: + return 1; + default: + break; + } + + return 0; +} + +static inline int is_e1_bts(struct gsm_bts *bts) +{ + switch (bts->type) { + case GSM_BTS_TYPE_BS11: + case GSM_BTS_TYPE_RBS2000: + case GSM_BTS_TYPE_NOKIA_SITE: + return 1; + default: + break; + } + + return 0; +} + +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); + +enum bts_gprs_mode bts_gprs_mode_parse(const char *arg, int *valid); +const char *bts_gprs_mode_name(enum bts_gprs_mode mode); +int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode); + +int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts); +void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts); + +int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat); +int gsm_bts_model_register(struct gsm_bts_model *model); + +struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lchan); +void bsc_subscr_con_free(struct gsm_subscriber_connection *conn); + +struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network); +void msc_subscr_con_free(struct gsm_subscriber_connection *conn); + +struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, + enum gsm_bts_type type, + uint8_t bsic); + +void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr, + uint8_t e1_ts, uint8_t e1_ts_ss); + +void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked); +bool gsm_btsmodel_has_feature(struct gsm_bts_model *model, enum gsm_bts_features feat); +struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr); +int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx); +int gsm_bts_set_system_infos(struct gsm_bts *bts); + +/* generic E1 line operations for all ISDN-based BTS. */ +extern struct e1inp_line_ops bts_isdn_e1inp_line_ops; + +extern const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1]; +extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1]; + +/* control interface handling */ +int bsc_base_ctrl_cmds_install(void); +int msc_ctrl_cmds_install(struct gsm_network *net); + +/* dependency handling */ +void bts_depend_mark(struct gsm_bts *bts, int dep); +void bts_depend_clear(struct gsm_bts *bts, int dep); +int bts_depend_check(struct gsm_bts *bts); +int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other); + +int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts); +void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value); + +bool classmark_is_r99(struct gsm_classmark *cm); + +#endif /* _GSM_DATA_H */ diff --git a/include/osmocom/bsc/gsm_data_shared.h b/include/osmocom/bsc/gsm_data_shared.h new file mode 100644 index 000000000..6ce571edd --- /dev/null +++ b/include/osmocom/bsc/gsm_data_shared.h @@ -0,0 +1,1004 @@ +#ifndef _GSM_DATA_SHAREDH +#define _GSM_DATA_SHAREDH + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef ROLE_BSC +#include +#endif + +#include +#include + +/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1: + 4-bit index is used (2#1111 = 10#15) */ +#define SI2Q_MAX_NUM 16 +/* length in bits (for single SI2quater message) */ +#define SI2Q_MAX_LEN 160 +#define SI2Q_MIN_LEN 18 + +struct osmo_bsc_data; + +struct osmo_bsc_sccp_con; +struct gsm_sms_queue; + +/* 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 { + GSM_CHREQ_REASON_EMERG, + GSM_CHREQ_REASON_PAG, + GSM_CHREQ_REASON_CALL, + GSM_CHREQ_REASON_LOCATION_UPD, + GSM_CHREQ_REASON_OTHER, + GSM_CHREQ_REASON_PDCH, +}; + +/* lchans 0..3 are SDCCH in combined channel configuration, + use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */ +#define CCCH_LCHAN 4 + +#define TRX_NR_TS 8 +#define TS_MAX_LCHAN 8 + +#define HARDCODED_ARFCN 123 +#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */ + +/* for multi-drop config */ +#define HARDCODED_BTS0_TS 1 +#define HARDCODED_BTS1_TS 6 +#define HARDCODED_BTS2_TS 11 + +#define MAX_VERSION_LENGTH 64 + +#define MAX_BTS_FEATURES 128 + +enum gsm_hooks { + GSM_HOOK_NM_SWLOAD, + GSM_HOOK_RR_PAGING, + GSM_HOOK_RR_SECURITY, +}; + +enum gsm_paging_event { + GSM_PAGING_SUCCEEDED, + GSM_PAGING_EXPIRED, + GSM_PAGING_OOM, + GSM_PAGING_BUSY, +}; + +enum bts_gprs_mode { + BTS_GPRS_NONE = 0, + BTS_GPRS_GPRS = 1, + BTS_GPRS_EGPRS = 2, +}; + +struct gsm_lchan; +struct gsm_mncc; +struct osmo_rtp_socket; +struct rtp_socket; +struct bsc_api; + +/* Network Management State */ +struct gsm_nm_state { + uint8_t operational; + uint8_t administrative; + uint8_t availability; +}; + +struct gsm_abis_mo { + uint8_t obj_class; + uint8_t procedure_pending; + struct abis_om_obj_inst obj_inst; + const char *name; + struct gsm_nm_state nm_state; + struct tlv_parsed *nm_attr; + struct gsm_bts *bts; +}; + +/* Ericsson OM2000 Managed Object */ +struct abis_om2k_mo { + uint8_t class; + uint8_t bts; + uint8_t assoc_so; + uint8_t inst; +} __attribute__ ((packed)); + +struct om2k_mo { + struct abis_om2k_mo addr; + struct osmo_fsm_inst *fsm; +}; + +#define A38_XOR_MIN_KEY_LEN 12 +#define A38_XOR_MAX_KEY_LEN 16 +#define A38_COMP128_KEY_LEN 16 +#define RSL_ENC_ALG_A5(x) (x+1) +#define MAX_EARFCN_LIST 32 + +/* is the data link established? who established it? */ +#define LCHAN_SAPI_UNUSED 0 +#define LCHAN_SAPI_MS 1 +#define LCHAN_SAPI_NET 2 +#define LCHAN_SAPI_REL 3 + +/* state of a logical channel */ +enum gsm_lchan_state { + LCHAN_S_NONE, /* channel is not active */ + LCHAN_S_ACT_REQ, /* channel activation requested */ + LCHAN_S_ACTIVE, /* channel is active and operational */ + LCHAN_S_REL_REQ, /* channel release has been requested */ + LCHAN_S_REL_ERR, /* channel is in an error state */ + LCHAN_S_BROKEN, /* channel is somehow unusable */ + LCHAN_S_INACTIVE, /* channel is set inactive */ +}; + +/* BTS ONLY */ +#define MAX_NUM_UL_MEAS 104 +#define LC_UL_M_F_L1_VALID (1 << 0) +#define LC_UL_M_F_RES_VALID (1 << 1) + +struct bts_ul_meas { + /* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */ + uint16_t ber10k; + /* timing advance offset (in quarter bits) */ + int16_t ta_offs_qbits; + /* C/I ratio in dB */ + float c_i; + /* flags */ + uint8_t is_sub:1; + /* RSSI in dBm * -1 */ + uint8_t inv_rssi; +}; + +struct bts_codec_conf { + uint8_t hr; + uint8_t efr; + uint8_t amr; +}; + +struct amr_mode { + uint8_t mode; + uint8_t threshold; + uint8_t hysteresis; +}; + +struct amr_multirate_conf { + uint8_t gsm48_ie[2]; + struct amr_mode ms_mode[4]; + struct amr_mode bts_mode[4]; + uint8_t num_modes; +}; +/* /BTS ONLY */ + +enum lchan_csd_mode { + LCHAN_CSD_M_NT, + LCHAN_CSD_M_T_1200_75, + LCHAN_CSD_M_T_600, + LCHAN_CSD_M_T_1200, + LCHAN_CSD_M_T_2400, + LCHAN_CSD_M_T_9600, + LCHAN_CSD_M_T_14400, + LCHAN_CSD_M_T_29000, + LCHAN_CSD_M_T_32000, +}; + +/* State of the SAPIs in the lchan */ +enum lchan_sapi_state { + LCHAN_SAPI_S_NONE, + LCHAN_SAPI_S_REQ, + LCHAN_SAPI_S_ASSIGNED, + LCHAN_SAPI_S_REL, + LCHAN_SAPI_S_ERROR, +}; + +struct gsm_lchan { + /* The TS that we're part of */ + struct gsm_bts_trx_ts *ts; + /* The logical subslot number in the TS */ + uint8_t nr; + /* The logical channel type */ + enum gsm_chan_t type; + /* RSL channel mode */ + enum rsl_cmod_spd rsl_cmode; + /* If TCH, traffic channel mode */ + enum gsm48_chan_mode tch_mode; + enum lchan_csd_mode csd_mode; + /* State */ + enum gsm_lchan_state state; + const char *broken_reason; + /* Power levels for MS and BTS */ + uint8_t bs_power; + uint8_t ms_power; + /* Encryption information */ + struct gsm_encr encr; + + /* AMR bits */ + uint8_t mr_ms_lv[7]; + uint8_t mr_bts_lv[7]; + + /* Established data link layer services */ + uint8_t sapis[8]; + int sacch_deact; + + struct { + uint32_t bound_ip; + uint32_t connect_ip; + uint16_t bound_port; + uint16_t connect_port; + uint16_t conn_id; + uint8_t rtp_payload; + uint8_t rtp_payload2; + uint8_t speech_mode; +#ifdef ROLE_BSC + struct rtp_socket *rtp_socket; + + /* info we need to postpone the AoIP + * assignment completed message */ + struct { + uint8_t rr_cause; + uint8_t chosen_channel; + uint8_t encr_alg_id; + uint8_t speech_mode; + bool valid; + } ass_compl; +#else + struct osmo_rtp_socket *rtp_socket; +#endif + } abis_ip; + + uint8_t rqd_ta; + + char *name; + +#ifdef ROLE_BSC + struct osmo_timer_list T3101; + struct osmo_timer_list T3109; + struct osmo_timer_list T3111; + struct osmo_timer_list error_timer; + struct osmo_timer_list act_timer; + struct osmo_timer_list rel_work; + uint8_t error_cause; + + /* table of neighbor cell measurements */ + struct neigh_meas_proc neigh_meas[MAX_NEIGH_MEAS]; + + /* cache of last measurement reports on this lchan */ + struct gsm_meas_rep meas_rep[6]; + int meas_rep_idx; + + /* GSM Random Access data */ + struct gsm48_req_ref *rqd_ref; + + struct gsm_subscriber_connection *conn; + + struct { + /* channel activation type and handover ref */ + uint8_t act_type; + uint8_t ho_ref; + struct gsm48_req_ref *rqd_ref; + uint8_t rqd_ta; + } dyn; +#else + /* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23. + * Currently we don't share these headers so this is a magic number. */ + struct llist_head sapi_cmds; + uint8_t sapis_dl[23]; + uint8_t sapis_ul[23]; + struct lapdm_channel lapdm_ch; + struct llist_head dl_tch_queue; + struct { + /* bitmask of all SI that are present/valid in si_buf */ + uint32_t valid; + uint32_t last; + /* buffers where we put the pre-computed SI: + SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */ + sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM]; + } si; + struct { + uint8_t flags; + /* RSL measurment result number, 0 at lchan_act */ + uint8_t res_nr; + /* current Tx power level of the BTS */ + uint8_t bts_tx_pwr; + /* number of measurements stored in array below */ + uint8_t num_ul_meas; + struct bts_ul_meas uplink[MAX_NUM_UL_MEAS]; + /* last L1 header from the MS */ + uint8_t l1_info[2]; + struct gsm_meas_rep_unidir ul_res; + } meas; + struct { + struct amr_multirate_conf amr_mr; + struct { + struct osmo_fsm_inst *dl_amr_fsm; + /* TCH cache */ + uint8_t cache[20]; + /* FACCH cache */ + uint8_t facch[GSM_MACBLOCK_LEN]; + uint8_t len; + uint32_t fn; + bool is_update; + /* set for each SID frame to detect talkspurt for codecs + without explicit ONSET event */ + bool ul_sid; + /* indicates if DTXd was active during DL measurement + period */ + bool dl_active; + } dtx; + uint8_t last_cmr; + uint32_t last_fn; + } tch; + + /* 3GPP TS 48.058 ยง 9.3.37: [0; 255] ok, -1 means invalid*/ + int16_t ms_t_offs; + /* 3GPP TS 45.010 ยง 1.2 round trip propagation delay (in symbols) or -1 */ + int16_t p_offs; + + /* BTS-side ciphering state (rx only, bi-directional, ...) */ + uint8_t ciph_state; + uint8_t ciph_ns; + uint8_t loopback; + struct { + uint8_t active; + uint8_t ref; + /* T3105: PHYS INF retransmission */ + struct osmo_timer_list t3105; + /* counts up to Ny1 */ + unsigned int phys_info_count; + } ho; + /* S counter for link loss */ + int s; + /* Kind of the release/activation. E.g. RSL or PCU */ + int rel_act_kind; + /* RTP header Marker bit to indicate beginning of speech after pause */ + bool rtp_tx_marker; + /* power handling */ + struct { + uint8_t current; + uint8_t fixed; + } ms_power_ctrl; + + struct msgb *pending_rel_ind_msg; +#endif +}; + +enum { + TS_F_PDCH_ACTIVE = 0x1000, + TS_F_PDCH_ACT_PENDING = 0x2000, + TS_F_PDCH_DEACT_PENDING = 0x4000, + TS_F_PDCH_PENDING_MASK = 0x6000 /*< + TS_F_PDCH_ACT_PENDING | TS_F_PDCH_DEACT_PENDING */ +} gsm_bts_trx_ts_flags; + +/* One Timeslot in a TRX */ +struct gsm_bts_trx_ts { + struct gsm_bts_trx *trx; + /* number of this timeslot at the TRX */ + uint8_t nr; + + enum gsm_phys_chan_config pchan; + + struct { + enum gsm_phys_chan_config pchan_is; + enum gsm_phys_chan_config pchan_want; + struct msgb *pending_chan_activ; + } dyn; + + unsigned int flags; + struct gsm_abis_mo mo; + struct tlv_parsed nm_attr; + uint8_t nm_chan_comb; + int tsc; /* -1 == use BTS TSC */ + + struct { + /* Parameters below are configured by VTY */ + int enabled; + uint8_t maio; + uint8_t hsn; + struct bitvec arfcns; + uint8_t arfcns_data[1024/8]; + /* This is the pre-computed MA for channel assignments */ + struct bitvec ma; + uint8_t ma_len; /* part of ma_data that is used */ + uint8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */ + } hopping; + + /* To which E1 subslot are we connected */ + struct gsm_e1_subslot e1_link; + + union { + struct { + struct om2k_mo om2k_mo; + } rbs2000; + }; + + struct gsm_lchan lchan[TS_MAX_LCHAN]; +}; + +/* One TRX in a BTS */ +struct gsm_bts_trx { + /* list header in bts->trx_list */ + struct llist_head list; + + struct gsm_bts *bts; + /* number of this TRX in the BTS */ + uint8_t nr; + /* human readable name / description */ + char *description; + /* how do we talk RSL with this TRX? */ + struct gsm_e1_subslot rsl_e1_link; + uint8_t rsl_tei; + struct e1inp_sign_link *rsl_link; + + /* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */ + struct e1inp_sign_link *oml_link; + + struct gsm_abis_mo mo; + struct tlv_parsed nm_attr; + struct { + struct gsm_abis_mo mo; + } bb_transc; + + uint16_t arfcn; + int nominal_power; /* in dBm */ + unsigned int max_power_red; /* in actual dB */ + +#ifndef ROLE_BSC + struct trx_power_params power_params; + int ms_power_control; + + struct { + void *l1h; + } role_bts; +#endif + + union { + struct { + struct { + struct gsm_abis_mo mo; + } bbsig; + struct { + struct gsm_abis_mo mo; + } pa; + } bs11; + struct { + unsigned int test_state; + uint8_t test_nr; + struct rxlev_stats rxlev_stat; + } ipaccess; + struct { + struct { + struct om2k_mo om2k_mo; + } trxc; + struct { + struct om2k_mo om2k_mo; + } rx; + struct { + struct om2k_mo om2k_mo; + } tx; + } rbs2000; + }; + struct gsm_bts_trx_ts ts[TRX_NR_TS]; +}; + +#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i]) +#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i)) +#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0]) +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0]) + +enum gsm_bts_type { + GSM_BTS_TYPE_UNKNOWN, + GSM_BTS_TYPE_BS11, + GSM_BTS_TYPE_NANOBTS, + GSM_BTS_TYPE_RBS2000, + GSM_BTS_TYPE_NOKIA_SITE, + GSM_BTS_TYPE_OSMOBTS, + _NUM_GSM_BTS_TYPE +}; + +enum gsm_bts_type_variant { + BTS_UNKNOWN, + BTS_OSMO_LITECELL15, + BTS_OSMO_OCTPHY, + BTS_OSMO_SYSMO, + BTS_OSMO_TRX, + _NUM_BTS_VARIANT +}; + +/* Used by OML layer for BTS Attribute reporting */ +enum bts_attribute { + BTS_TYPE_VARIANT, + BTS_SUB_MODEL, + TRX_PHY_VERSION, +}; + +struct vty; + +struct gsm_bts_model { + struct llist_head list; + + enum gsm_bts_type type; + enum gsm_bts_type_variant variant; + const char *name; + + bool started; + int (*start)(struct gsm_network *net); + int (*oml_rcvmsg)(struct msgb *msg); + + void (*e1line_bind_ops)(struct e1inp_line *line); + + void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts); + void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx); + void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts); + + struct tlv_definition nm_att_tlvdef; + + /* features of a given BTS model set via gsm_bts_model_register() locally */ + struct bitvec features; + uint8_t _features_data[MAX_BTS_FEATURES/8]; +}; + +/* N. B: always add new features to the end of the list (right before _NUM_BTS_FEAT) to avoid breaking compatibility + with BTS compiled against earlier version of this header */ +enum gsm_bts_features { + BTS_FEAT_HSCSD, + BTS_FEAT_GPRS, + BTS_FEAT_EGPRS, + BTS_FEAT_ECSD, + BTS_FEAT_HOPPING, + BTS_FEAT_MULTI_TSC, + BTS_FEAT_OML_ALERTS, + BTS_FEAT_AGCH_PCH_PROP, + BTS_FEAT_CBCH, + _NUM_BTS_FEAT +}; + +extern const struct value_string gsm_bts_features_descs[]; + +/* + * This keeps track of the paging status of one BTS. It + * includes a number of pending requests, a back pointer + * to the gsm_bts, a timer and some more state. + */ +struct gsm_bts_paging_state { + /* pending requests */ + struct llist_head pending_requests; + struct gsm_bts *bts; + + struct osmo_timer_list work_timer; + struct osmo_timer_list credit_timer; + + /* free chans needed */ + int free_chans_need; + + /* load */ + uint16_t available_slots; +}; + +struct gsm_envabtse { + struct gsm_abis_mo mo; +}; + +struct gsm_bts_gprs_nsvc { + struct gsm_bts *bts; + /* data read via VTY config file, to configure the BTS + * via OML from BSC */ + int id; + uint16_t nsvci; + uint16_t local_port; /* on the BTS */ + uint16_t remote_port; /* on the SGSN */ + uint32_t remote_ip; /* on the SGSN */ + + struct gsm_abis_mo mo; +}; + +enum gprs_rlc_par { + RLC_T3142, + RLC_T3169, + RLC_T3191, + RLC_T3193, + RLC_T3195, + RLC_N3101, + RLC_N3103, + RLC_N3105, + CV_COUNTDOWN, + T_DL_TBF_EXT, /* ms */ + T_UL_TBF_EXT, /* ms */ + _NUM_RLC_PAR +}; + +enum gprs_cs { + GPRS_CS1, + GPRS_CS2, + GPRS_CS3, + GPRS_CS4, + GPRS_MCS1, + GPRS_MCS2, + GPRS_MCS3, + GPRS_MCS4, + GPRS_MCS5, + GPRS_MCS6, + GPRS_MCS7, + GPRS_MCS8, + GPRS_MCS9, + _NUM_GRPS_CS +}; + +struct gprs_rlc_cfg { + uint16_t parameter[_NUM_RLC_PAR]; + struct { + uint16_t repeat_time; /* ms */ + uint8_t repeat_count; + } paging; + uint32_t cs_mask; /* bitmask of gprs_cs */ + uint8_t initial_cs; + uint8_t initial_mcs; +}; + + +enum neigh_list_manual_mode { + NL_MODE_AUTOMATIC = 0, + NL_MODE_MANUAL = 1, + NL_MODE_MANUAL_SI5SEP = 2, /* SI2 and SI5 have separate neighbor lists */ +}; + +enum bts_loc_fix { + BTS_LOC_FIX_INVALID = 0, + BTS_LOC_FIX_2D = 1, + BTS_LOC_FIX_3D = 2, +}; + +extern const struct value_string bts_loc_fix_names[]; + +struct bts_location { + struct llist_head list; + time_t tstamp; + enum bts_loc_fix valid; + double lat; + double lon; + double height; +}; + +/* One BTS */ +struct gsm_bts { + /* list header in net->bts_list */ + struct llist_head list; + + /* Geographical location of the BTS */ + struct llist_head loc_list; + + /* number of ths BTS in network */ + uint8_t nr; + /* human readable name / description */ + char *description; + /* Cell Identity */ + uint16_t cell_identity; + /* location area code of this BTS */ + uint16_t location_area_code; + /* Base Station Identification Code (BSIC), lower 3 bits is BCC, + * which is used as TSC for the CCCH */ + uint8_t bsic; + /* type of BTS */ + enum gsm_bts_type type; + enum gsm_bts_type_variant variant; + struct gsm_bts_model *model; + enum gsm_band band; + char version[MAX_VERSION_LENGTH]; + char sub_model[MAX_VERSION_LENGTH]; + + /* features of a given BTS set/reported via OML */ + struct bitvec features; + uint8_t _features_data[MAX_BTS_FEATURES/8]; + + /* Connected PCU version (if any) */ + char pcu_version[MAX_VERSION_LENGTH]; + + /* maximum Tx power that the MS is permitted to use in this cell */ + int ms_max_power; + + /* how do we talk OML with this TRX? */ + struct gsm_e1_subslot oml_e1_link; + uint8_t oml_tei; + struct e1inp_sign_link *oml_link; + + /* Abis network management O&M handle */ + struct abis_nm_h *nmh; + + struct gsm_abis_mo mo; + + /* number of this BTS on given E1 link */ + uint8_t bts_nr; + + /* DTX features of this BTS */ + enum gsm48_dtx_mode dtxu; + bool dtxd; + + /* paging state and control */ + struct gsm_bts_paging_state paging; + + /* CCCH is on C0 */ + struct gsm_bts_trx *c0; + + struct { + struct gsm_abis_mo mo; + } site_mgr; + + /* bitmask of all SI that are present/valid in si_buf */ + uint32_t si_valid; + /* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */ + uint8_t si2q_index; /* distinguish individual SI2quater messages */ + uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */ + /* buffers where we put the pre-computed SI */ + sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM]; + /* offsets used while generating SI2quater */ + size_t e_offset; + size_t u_offset; + + /* ip.accesss Unit ID's have Site/BTS/TRX layout */ + union { + struct { + uint16_t site_id; + uint16_t bts_id; + uint32_t flags; + uint32_t rsl_ip; + } ip_access; + struct { + struct { + struct gsm_abis_mo mo; + } cclk; + struct { + struct gsm_abis_mo mo; + } rack; + struct gsm_envabtse envabtse[4]; + } bs11; + struct { + struct { + struct om2k_mo om2k_mo; + struct gsm_abis_mo mo; + struct llist_head conn_groups; + } cf; + struct { + struct om2k_mo om2k_mo; + struct gsm_abis_mo mo; + struct llist_head conn_groups; + } is; + struct { + struct om2k_mo om2k_mo; + struct gsm_abis_mo mo; + struct llist_head conn_groups; + } con; + struct { + struct om2k_mo om2k_mo; + struct gsm_abis_mo mo; + } dp; + struct { + struct om2k_mo om2k_mo; + struct gsm_abis_mo mo; + } tf; + uint32_t use_superchannel:1; + } rbs2000; + struct { + uint8_t bts_type; + unsigned int configured:1, + skip_reset:1, + no_loc_rel_cnf:1, + bts_reset_timer_cnf, + did_reset:1, + wait_reset:1; + struct osmo_timer_list reset_timer; + } nokia; + }; + + /* Not entirely sure how ip.access specific this is */ + struct { + uint8_t supports_egprs_11bit_rach; + enum bts_gprs_mode mode; + struct { + struct gsm_abis_mo mo; + uint16_t nsei; + uint8_t timer[7]; + } nse; + struct { + struct gsm_abis_mo mo; + uint16_t bvci; + uint8_t timer[11]; + struct gprs_rlc_cfg rlc_cfg; + } cell; + struct gsm_bts_gprs_nsvc nsvc[2]; + uint8_t rac; + uint8_t net_ctrl_ord; + bool ctrl_ack_type_use_block; + } gprs; + + /* RACH NM values */ + int rach_b_thresh; + int rach_ldavg_slots; + + /* transceivers */ + int num_trx; + struct llist_head trx_list; + + /* SI related items */ + int force_combined_si; + int bcch_change_mark; + +#ifdef ROLE_BSC + /* Abis NM queue */ + struct llist_head abis_queue; + int abis_nm_pend; + + struct gsm_network *network; + + /* should the channel allocator allocate channels from high TRX to TRX0, + * rather than starting from TRX0 and go upwards? */ + int chan_alloc_reverse; + + enum neigh_list_manual_mode neigh_list_manual_mode; + /* parameters from which we build SYSTEM INFORMATION */ + struct { + struct gsm48_rach_control rach_control; + uint8_t ncc_permitted; + struct gsm48_cell_sel_par cell_sel_par; + struct gsm48_si_selection_params cell_ro_sel_par; /* rest octet */ + struct gsm48_cell_options cell_options; + struct gsm48_control_channel_descr chan_desc; + struct bitvec neigh_list; + struct bitvec cell_alloc; + struct bitvec si5_neigh_list; + struct osmo_earfcn_si2q si2quater_neigh_list; + size_t uarfcn_length; /* index for uarfcn and scramble lists */ + struct { + /* bitmask large enough for all possible ARFCN's */ + uint8_t neigh_list[1024/8]; + uint8_t cell_alloc[1024/8]; + /* If the user wants a different neighbor list in SI5 than in SI2 */ + uint8_t si5_neigh_list[1024/8]; + uint8_t meas_bw_list[MAX_EARFCN_LIST]; + uint16_t earfcn_list[MAX_EARFCN_LIST]; + uint16_t uarfcn_list[MAX_EARFCN_LIST]; + uint16_t scramble_list[MAX_EARFCN_LIST]; + } data; + } si_common; + bool early_classmark_allowed; + /* for testing only: Have an infinitely long radio link timeout */ + bool infinite_radio_link_timeout; + + /* do we use static (user-defined) system information messages? (bitmask) */ + uint32_t si_mode_static; + + /* exclude the BTS from the global RF Lock handling */ + int excl_from_rf_lock; + + /* supported codecs beside FR */ + struct bts_codec_conf codec; + + /* BTS dependencies bit field */ + uint32_t depends_on[256/(8*4)]; + + /* full and half rate multirate config */ + struct amr_multirate_conf mr_full; + struct amr_multirate_conf mr_half; + + /* PCU socket state */ + char *pcu_sock_path; + struct pcu_sock_state *pcu_state; + +#endif /* ROLE_BSC */ + void *role; +}; + + +struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num); +struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num); + +struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); +struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num); + +enum gsm_bts_type str2btstype(const char *arg); +const char *btstype2str(enum gsm_bts_type type); + +enum bts_attribute str2btsattr(const char *s); +const char *btsatttr2str(enum bts_attribute v); + +enum gsm_bts_type_variant str2btsvariant(const char *arg); +const char *btsvariant2str(enum gsm_bts_type_variant v); + +extern const struct value_string gsm_chreq_descs[]; +const struct value_string gsm_pchant_names[13]; +const struct value_string gsm_pchant_descs[13]; +const char *gsm_pchan_name(enum gsm_phys_chan_config c); +enum gsm_phys_chan_config gsm_pchan_parse(const char *name); +const char *gsm_lchant_name(enum gsm_chan_t c); +const char *gsm_chreq_name(enum gsm_chreq_reason_t c); +char *gsm_trx_name(const struct gsm_bts_trx *trx); +char *gsm_ts_name(const struct gsm_bts_trx_ts *ts); +char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts); +char *gsm_lchan_name_compute(const struct gsm_lchan *lchan); +const char *gsm_lchans_name(enum gsm_lchan_state s); + +static inline char *gsm_lchan_name(const struct gsm_lchan *lchan) +{ + return lchan->name; +} + +static inline int gsm_bts_set_feature(struct gsm_bts *bts, enum gsm_bts_features feat) +{ + OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES); + return bitvec_set_bit_pos(&bts->features, feat, 1); +} + +static inline bool gsm_bts_has_feature(const struct gsm_bts *bts, enum gsm_bts_features feat) +{ + OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES); + return bitvec_get_bit_pos(&bts->features, feat); +} + +void gsm_abis_mo_reset(struct gsm_abis_mo *mo); + +struct gsm_abis_mo * +gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class, + const struct abis_om_obj_inst *obj_inst); + +struct gsm_nm_state * +gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class, + const struct abis_om_obj_inst *obj_inst); +void * +gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class, + const struct abis_om_obj_inst *obj_inst); + +/* reset the state of all MO in the BTS */ +void gsm_bts_mo_reset(struct gsm_bts *bts); + +uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan, + uint8_t ts_nr, uint8_t lchan_nr); +uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan); +uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan, + enum gsm_phys_chan_config as_pchan); + +/* return the gsm_lchan for the CBCH (if it exists at all) */ +struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts); + +/* + * help with parsing regexps + */ +int gsm_parse_reg(void *ctx, regex_t *reg, char **str, + int argc, const char **argv) __attribute__ ((warn_unused_result)); + +static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts) +{ + if (ts->tsc != -1) + return ts->tsc; + else + return ts->trx->bts->bsic & 7; +} + +struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr, + int *rc); + +enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts); +uint8_t ts_subslots(struct gsm_bts_trx_ts *ts); +bool ts_is_tch(struct gsm_bts_trx_ts *ts); + +#endif diff --git a/include/osmocom/bsc/gsm_subscriber.h b/include/osmocom/bsc/gsm_subscriber.h new file mode 100644 index 000000000..ca66d47a9 --- /dev/null +++ b/include/osmocom/bsc/gsm_subscriber.h @@ -0,0 +1,68 @@ +#ifndef _GSM_SUBSCR_H +#define _GSM_SUBSCR_H + +#include + +#include +#include + +#include + +#define GSM_NAME_LENGTH 160 + +#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */ +#define GSM_MIN_EXTEN 20000 +#define GSM_MAX_EXTEN 49999 + +#define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001 +/* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */ + +#define GSM_SUBSCRIBER_NO_EXPIRATION 0x0 + +enum gsm_subscriber_field { + GSM_SUBSCRIBER_IMSI, + GSM_SUBSCRIBER_TMSI, + GSM_SUBSCRIBER_EXTENSION, + GSM_SUBSCRIBER_ID, +}; + +enum gsm_subscriber_update_reason { + GSM_SUBSCRIBER_UPDATE_ATTACHED, + GSM_SUBSCRIBER_UPDATE_DETACHED, + GSM_SUBSCRIBER_UPDATE_EQUIPMENT, +}; + +/* + * Struct for pending channel requests. This is managed in the + * llist_head requests of each subscriber. The reference counting + * should work in such a way that a subscriber with a pending request + * remains in memory. + */ +struct subscr_request { + struct llist_head entry; + + /* human readable label to be able to log pending request kinds */ + const char *label; + + /* the callback data */ + gsm_cbfn *cbfn; + void *param; +}; + +int subscr_update(struct vlr_subscr *vsub, int reason); + +/* + * Paging handling with authentication + */ +struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub, + gsm_cbfn *cbfn, void *param, + const char *label); + +void subscr_remove_request(struct subscr_request *req); +int subscr_rx_paging_response(struct msgb *msg, + struct gsm_subscriber_connection *conn); + +int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, + struct msgb *msg, void *data, void *param); + +#endif /* _GSM_SUBSCR_H */ diff --git a/include/osmocom/bsc/handover.h b/include/osmocom/bsc/handover.h new file mode 100644 index 000000000..3fe71a28b --- /dev/null +++ b/include/osmocom/bsc/handover.h @@ -0,0 +1,14 @@ +#ifndef _HANDOVER_H +#define _HANDOVER_H + +struct gsm_subscriber_connection; + +int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts); + +/* clear any operation for this connection */ +void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan); + +/* Return the old lchan or NULL. This is meant for audio handling */ +struct gsm_lchan *bsc_handover_pending(struct gsm_lchan *new_lchan); + +#endif /* _HANDOVER_H */ diff --git a/include/osmocom/bsc/handover_decision.h b/include/osmocom/bsc/handover_decision.h new file mode 100644 index 000000000..81078b05d --- /dev/null +++ b/include/osmocom/bsc/handover_decision.h @@ -0,0 +1,7 @@ +#ifndef _HANDOVER_DECISION_H +#define _HANDOVER_DECISION_H + +void on_dso_load_ho_dec(void); + +#endif /* _HANDOVER_DECISION_H */ + diff --git a/include/osmocom/bsc/ipaccess.h b/include/osmocom/bsc/ipaccess.h new file mode 100644 index 000000000..82e89c27d --- /dev/null +++ b/include/osmocom/bsc/ipaccess.h @@ -0,0 +1,52 @@ +#ifndef _IPACCESS_H +#define _IPACCESS_H + +#include +#include "gsm_subscriber.h" +#include +#include +#include + +struct ipac_msgt_sccp_state { + uint8_t src_ref[3]; + uint8_t dst_ref[3]; + uint8_t trans_id; + uint8_t invoke_id; + char imsi[GSM23003_IMSI_MAX_DIGITS+1]; + uint8_t data[0]; +} __attribute__((packed)); + +/* + * @add_remove 0 for remove, 1 for add, 3 to asK + * @nr_lacs Number of extra lacs inside this package + * @lac One lac entry + */ +struct ipac_ext_lac_cmd { + uint8_t add_remove; + uint8_t nr_extra_lacs; + uint16_t lac; + uint8_t data[0]; +} __attribute__((packed)); + +void ipaccess_drop_oml(struct gsm_bts *bts); +void ipaccess_drop_rsl(struct gsm_bts_trx *trx); + +struct sdp_header_item { + struct sdp_header_entry header_entry; + struct llist_head entry; + off_t absolute_offset; +}; + +struct sdp_header { + struct sdp_firmware firmware_info; + + /* for more_magic a list of sdp_header_entry_list */ + struct llist_head header_list; + + /* the entry of the sdp_header */ + struct llist_head entry; +}; + +int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned base_offset, struct llist_head *list); + +#endif /* _IPACCESS_H */ diff --git a/include/osmocom/bsc/iu_dummy.h b/include/osmocom/bsc/iu_dummy.h new file mode 100644 index 000000000..d5e142801 --- /dev/null +++ b/include/osmocom/bsc/iu_dummy.h @@ -0,0 +1,51 @@ +/* Trivial switch-off of external Iu dependencies, + * allowing to run full unit tests even when built without Iu support. */ + +/* + * (C) 2016,2017 by sysmocom s.f.m.c. GmbH + * + * Author: Neels Hofmeyr + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include + +#include + +struct msgb; +struct gsm_auth_tuple; +struct RANAP_Cause; +struct osmo_auth_vector; + +struct ranap_ue_conn_ctx { + struct llist_head list; + uint32_t conn_id; +}; + +int ranap_iu_tx(struct msgb *msg, uint8_t sapi); +int ranap_iu_tx_sec_mode_cmd(struct ranap_ue_conn_ctx *uectx, struct osmo_auth_vector *vec, + int send_ck); +int ranap_iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac); +int ranap_iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t rac); +struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, + uint16_t rtp_port, + bool use_x213_nsap); +int ranap_iu_rab_act(struct ranap_ue_conn_ctx *ue_ctx, struct msgb *msg); +int ranap_iu_tx_common_id(struct ranap_ue_conn_ctx *uectx, const char *imsi); +int ranap_iu_tx_release(struct ranap_ue_conn_ctx *ctx, const struct RANAP_Cause *cause); diff --git a/include/osmocom/bsc/meas_feed.h b/include/osmocom/bsc/meas_feed.h new file mode 100644 index 000000000..55bce098e --- /dev/null +++ b/include/osmocom/bsc/meas_feed.h @@ -0,0 +1,41 @@ +#ifndef _OPENBSC_MEAS_FEED_H +#define _OPENBSC_MEAS_FEED_H + +#include + +#include + +struct meas_feed_hdr { + uint8_t msg_type; + uint8_t reserved; + uint16_t version; +}; + +struct meas_feed_meas { + struct meas_feed_hdr hdr; + char imsi[15+1]; + char name[31+1]; + char scenario[31+1]; + struct gsm_meas_rep mr; + /* The logical channel type, enum gsm_chan_t */ + uint8_t lchan_type; + /* The physical channel type, enum gsm_phys_chan_config */ + uint8_t pchan_type; + /* number of ths BTS in network */ + uint8_t bts_nr; + /* number of this TRX in the BTS */ + uint8_t trx_nr; + /* number of this timeslot at the TRX */ + uint8_t ts_nr; + /* The logical subslot number in the TS */ + uint8_t ss_nr; +}; + +enum meas_feed_msgtype { + MEAS_FEED_MEAS = 0, +}; + +#define MEAS_FEED_VERSION 1 + + +#endif diff --git a/include/osmocom/bsc/meas_rep.h b/include/osmocom/bsc/meas_rep.h new file mode 100644 index 000000000..b0c03f0bb --- /dev/null +++ b/include/osmocom/bsc/meas_rep.h @@ -0,0 +1,67 @@ +#ifndef _MEAS_REP_H +#define _MEAS_REP_H + +#include + +#include + +#define MRC_F_PROCESSED 0x0001 + +/* extracted from a L3 measurement report IE */ +struct gsm_meas_rep_cell { + uint8_t rxlev; + uint8_t bsic; + uint8_t neigh_idx; + uint16_t arfcn; + unsigned int flags; +}; + +#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 */ + uint8_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; + + uint8_t bs_power; + /* according to 3GPP TS 48.058 ยง MS Timing Offset [-63; 192] */ + int16_t ms_timing_offset; + struct { + int8_t pwr; /* MS power in dBm */ + uint8_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]; +}; + +/* 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/include/osmocom/bsc/misdn.h b/include/osmocom/bsc/misdn.h new file mode 100644 index 000000000..9851ad32c --- /dev/null +++ b/include/osmocom/bsc/misdn.h @@ -0,0 +1,27 @@ +/* (C) 2008 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef MISDN_H +#define MISDN_H + +#include + +int mi_setup(int cardnr, struct e1inp_line *line, int release_l2); +int mi_e1_line_update(struct e1inp_line *line); + +#endif diff --git a/include/osmocom/bsc/mncc.h b/include/osmocom/bsc/mncc.h new file mode 100644 index 000000000..881e0418e --- /dev/null +++ b/include/osmocom/bsc/mncc.h @@ -0,0 +1,215 @@ +/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface + * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */ + +/* (C) 2008-2009 by Harald Welte + * (C) 2008, 2009 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef _MNCC_H +#define _MNCC_H + +#include +#include + +#include + +struct gsm_network; +struct msgb; + + +/* One end of a call */ +struct gsm_call { + struct llist_head entry; + + /* network handle */ + void *net; + + /* the 'local' transaction */ + uint32_t callref; + /* the 'remote' transaction */ + uint32_t remote_ref; +}; + +#define MNCC_SETUP_REQ 0x0101 +#define MNCC_SETUP_IND 0x0102 +#define MNCC_SETUP_RSP 0x0103 +#define MNCC_SETUP_CNF 0x0104 +#define MNCC_SETUP_COMPL_REQ 0x0105 +#define MNCC_SETUP_COMPL_IND 0x0106 +/* MNCC_REJ_* is perfomed via MNCC_REL_* */ +#define MNCC_CALL_CONF_IND 0x0107 +#define MNCC_CALL_PROC_REQ 0x0108 +#define MNCC_PROGRESS_REQ 0x0109 +#define MNCC_ALERT_REQ 0x010a +#define MNCC_ALERT_IND 0x010b +#define MNCC_NOTIFY_REQ 0x010c +#define MNCC_NOTIFY_IND 0x010d +#define MNCC_DISC_REQ 0x010e +#define MNCC_DISC_IND 0x010f +#define MNCC_REL_REQ 0x0110 +#define MNCC_REL_IND 0x0111 +#define MNCC_REL_CNF 0x0112 +#define MNCC_FACILITY_REQ 0x0113 +#define MNCC_FACILITY_IND 0x0114 +#define MNCC_START_DTMF_IND 0x0115 +#define MNCC_START_DTMF_RSP 0x0116 +#define MNCC_START_DTMF_REJ 0x0117 +#define MNCC_STOP_DTMF_IND 0x0118 +#define MNCC_STOP_DTMF_RSP 0x0119 +#define MNCC_MODIFY_REQ 0x011a +#define MNCC_MODIFY_IND 0x011b +#define MNCC_MODIFY_RSP 0x011c +#define MNCC_MODIFY_CNF 0x011d +#define MNCC_MODIFY_REJ 0x011e +#define MNCC_HOLD_IND 0x011f +#define MNCC_HOLD_CNF 0x0120 +#define MNCC_HOLD_REJ 0x0121 +#define MNCC_RETRIEVE_IND 0x0122 +#define MNCC_RETRIEVE_CNF 0x0123 +#define MNCC_RETRIEVE_REJ 0x0124 +#define MNCC_USERINFO_REQ 0x0125 +#define MNCC_USERINFO_IND 0x0126 +#define MNCC_REJ_REQ 0x0127 +#define MNCC_REJ_IND 0x0128 + +#define MNCC_BRIDGE 0x0200 +#define MNCC_FRAME_RECV 0x0201 +#define MNCC_FRAME_DROP 0x0202 +#define MNCC_LCHAN_MODIFY 0x0203 +#define MNCC_RTP_CREATE 0x0204 +#define MNCC_RTP_CONNECT 0x0205 +#define MNCC_RTP_FREE 0x0206 + +#define GSM_TCHF_FRAME 0x0300 +#define GSM_TCHF_FRAME_EFR 0x0301 +#define GSM_TCHH_FRAME 0x0302 +#define GSM_TCH_FRAME_AMR 0x0303 +#define GSM_BAD_FRAME 0x03ff + +#define MNCC_SOCKET_HELLO 0x0400 + +#define GSM_MAX_FACILITY 128 +#define GSM_MAX_SSVERSION 128 +#define GSM_MAX_USERUSER 128 + +#define MNCC_F_BEARER_CAP 0x0001 +#define MNCC_F_CALLED 0x0002 +#define MNCC_F_CALLING 0x0004 +#define MNCC_F_REDIRECTING 0x0008 +#define MNCC_F_CONNECTED 0x0010 +#define MNCC_F_CAUSE 0x0020 +#define MNCC_F_USERUSER 0x0040 +#define MNCC_F_PROGRESS 0x0080 +#define MNCC_F_EMERGENCY 0x0100 +#define MNCC_F_FACILITY 0x0200 +#define MNCC_F_SSVERSION 0x0400 +#define MNCC_F_CCCAP 0x0800 +#define MNCC_F_KEYPAD 0x1000 +#define MNCC_F_SIGNAL 0x2000 + +struct gsm_mncc { + /* context based information */ + uint32_t msg_type; + uint32_t callref; + + /* which fields are present */ + uint32_t fields; + + /* data derived informations (MNCC_F_ based) */ + struct gsm_mncc_bearer_cap bearer_cap; + struct gsm_mncc_number called; + struct gsm_mncc_number calling; + struct gsm_mncc_number redirecting; + struct gsm_mncc_number connected; + struct gsm_mncc_cause cause; + struct gsm_mncc_progress progress; + struct gsm_mncc_useruser useruser; + struct gsm_mncc_facility facility; + struct gsm_mncc_cccap cccap; + struct gsm_mncc_ssversion ssversion; + struct { + int sup; + int inv; + } clir; + int signal; + + /* data derived information, not MNCC_F based */ + int keypad; + int more; + int notify; /* 0..127 */ + int emergency; + char imsi[16]; +}; + +struct gsm_data_frame { + uint32_t msg_type; + uint32_t callref; + unsigned char data[0]; +}; + +#define MNCC_SOCK_VERSION 5 +struct gsm_mncc_hello { + uint32_t msg_type; + uint32_t version; + + /* send the sizes of the structs */ + uint32_t mncc_size; + uint32_t data_frame_size; + + /* send some offsets */ + uint32_t called_offset; + uint32_t signal_offset; + uint32_t emergency_offset; +}; + +struct gsm_mncc_rtp { + uint32_t msg_type; + uint32_t callref; + uint32_t ip; + uint16_t port; + uint32_t payload_type; + uint32_t payload_msg_type; +}; + +struct gsm_mncc_bridge { + uint32_t msg_type; + uint32_t callref[2]; +}; + +const char *get_mncc_name(int value); +void mncc_set_cause(struct gsm_mncc *data, int loc, int val); +void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg); + +/* input from CC code into mncc_builtin */ +int int_mncc_recv(struct gsm_network *net, struct msgb *msg); + +/* input from CC code into mncc_sock */ +int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg); + +int mncc_sock_init(struct gsm_network *net, const char *sock_path); + +#define mncc_is_data_frame(msg_type) \ + (msg_type == GSM_TCHF_FRAME \ + || msg_type == GSM_TCHF_FRAME_EFR \ + || msg_type == GSM_TCHH_FRAME \ + || msg_type == GSM_TCH_FRAME_AMR \ + || msg_type == GSM_BAD_FRAME) + + +#endif diff --git a/include/osmocom/bsc/mncc_int.h b/include/osmocom/bsc/mncc_int.h new file mode 100644 index 000000000..213ce1414 --- /dev/null +++ b/include/osmocom/bsc/mncc_int.h @@ -0,0 +1,14 @@ +#ifndef _MNCC_INT_H +#define _MNCC_INT_H + +#include + +struct mncc_int { + uint8_t def_codec[2]; +}; + +extern struct mncc_int mncc_int; + +uint8_t mncc_codec_for_mode(int lchan_type); + +#endif diff --git a/include/osmocom/bsc/msc_ifaces.h b/include/osmocom/bsc/msc_ifaces.h new file mode 100644 index 000000000..dadb82800 --- /dev/null +++ b/include/osmocom/bsc/msc_ifaces.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +/* These are the interfaces of the MSC layer towards (from?) the BSC and RNC, + * i.e. in the direction towards the mobile device (MS aka UE). + * + * 2G will use the A-interface, + * 3G aka UMTS will use the Iu-interface (for the MSC, it's IuCS). + * + * To allow linking parts of the MSC code without having to include entire + * infrastructures of external libraries, the core transmitting and receiving + * functions are left unimplemented. For example, a unit test does not need to + * link against external ASN1 libraries if it is never going to encode actual + * outgoing messages. It is up to each building scope to implement real world + * functions or to plug mere dummy implementations. + * + * For example, msc_tx_dtap(conn, msg), depending on conn->via_iface, will call + * either iu_tx() or a_tx() [note: at time of writing, the A-interface is not + * yet implemented]. When you try to link against libmsc, you will find that + * the compiler complains about an undefined reference to iu_tx(). If you, + * however, link against libiu as well as the osmo-iuh libs (etc.), iu_tx() is + * available. A unit test may instead simply implement a dummy iu_tx() function + * and not link against osmo-iuh, see tests/libiudummy/. + */ + +/* Each main linkage must implement this function (see comment above). */ +extern int iu_tx(struct msgb *msg, uint8_t sapi); + +int msc_tx_dtap(struct gsm_subscriber_connection *conn, + struct msgb *msg); + +int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn); +int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value); + +int msc_tx_common_id(struct gsm_subscriber_connection *conn); +int msc_call_assignment(struct gsm_trans *trans); +int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2); +void msc_call_release(struct gsm_trans *trans); +int msc_call_connect(struct gsm_trans *trans, uint16_t port, uint32_t ip); diff --git a/include/osmocom/bsc/nat_rewrite_trie.h b/include/osmocom/bsc/nat_rewrite_trie.h new file mode 100644 index 000000000..0571099c6 --- /dev/null +++ b/include/osmocom/bsc/nat_rewrite_trie.h @@ -0,0 +1,47 @@ +/* + * (C) 2013 by On-Waves + * (C) 2013 by Holger Hans Peter Freyther + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +#ifndef NAT_REWRITE_FILE_H +#define NAT_REWRITE_FILE_H + +#include + +struct vty; + +struct nat_rewrite_rule { + /* For digits 0-9 and + */ + struct nat_rewrite_rule *rules[11]; + + char empty; + char prefix[14]; + char rewrite[6]; +}; + +struct nat_rewrite { + struct nat_rewrite_rule rule; + size_t prefixes; +}; + + +struct nat_rewrite *nat_rewrite_parse(void *ctx, const char *filename); +struct nat_rewrite_rule *nat_rewrite_lookup(struct nat_rewrite *, const char *prefix); +void nat_rewrite_dump(struct nat_rewrite *rewr); +void nat_rewrite_dump_vty(struct vty *vty, struct nat_rewrite *rewr); + +#endif diff --git a/include/osmocom/bsc/network_listen.h b/include/osmocom/bsc/network_listen.h new file mode 100644 index 000000000..68d07093d --- /dev/null +++ b/include/osmocom/bsc/network_listen.h @@ -0,0 +1,16 @@ +#ifndef _OPENBSC_NWL_H +#define _OPENBSC_NWL_H + +#include +#include + +void ipac_nwl_init(void); + +/* Start a NWL test. It will raise the S_IPAC_TEST_COMPLETE signal. */ +int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr, + const uint8_t *phys_conf, unsigned int phys_conf_len); + +int ipac_rxlevstat2whitelist(uint16_t *buf, const struct rxlev_stats *st, uint8_t min_rxlev, + uint16_t max_num_arfcns); + +#endif /* _OPENBSC_NWL_H */ diff --git a/include/osmocom/bsc/openbscdefines.h b/include/osmocom/bsc/openbscdefines.h new file mode 100644 index 000000000..c6ac153b8 --- /dev/null +++ b/include/osmocom/bsc/openbscdefines.h @@ -0,0 +1,34 @@ +/* + * (C) 2009 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef OPENBSCDEFINES_H +#define OPENBSCDEFINES_H + +#ifdef BUILDING_ON_WINDOWS + #ifdef BUILDING_OPENBSC + #define BSC_API __declspec(dllexport) + #else + #define BSC_API __declspec(dllimport) + #endif +#else + #define BSC_API __attribute__((visibility("default"))) +#endif + +#endif diff --git a/include/osmocom/bsc/osmo_bsc.h b/include/osmocom/bsc/osmo_bsc.h new file mode 100644 index 000000000..5ebea5079 --- /dev/null +++ b/include/osmocom/bsc/osmo_bsc.h @@ -0,0 +1,75 @@ +/* OpenBSC BSC code */ + +#ifndef OSMO_BSC_H +#define OSMO_BSC_H + +#include "bsc_api.h" +#include "bsc_msg_filter.h" + +#define BSS_SEND_USSD 1 + +enum bsc_con { + BSC_CON_SUCCESS, + BSC_CON_REJECT_NO_LINK, + BSC_CON_REJECT_RF_GRACE, + BSC_CON_NO_MEM, +}; + +struct sccp_connection; +struct bsc_msc_data; +struct bsc_msc_connection; + +struct osmo_bsc_sccp_con { + struct llist_head entry; + + int ciphering_handled; + + /* for audio handling */ + uint16_t cic; + uint32_t rtp_ip; + int rtp_port; + + /* for advanced ping/pong */ + int send_ping; + + /* SCCP connection realted */ + struct sccp_connection *sccp; + struct bsc_msc_data *msc; + struct osmo_timer_list sccp_it_timeout; + struct osmo_timer_list sccp_cc_timeout; + + struct llist_head sccp_queue; + unsigned int sccp_queue_size; + + struct gsm_subscriber_connection *conn; + uint8_t new_subscriber; + + struct bsc_filter_state filter_state; + + /* Sigtran connection ID */ + int conn_id; +}; + +struct bsc_api *osmo_bsc_api(); + +int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg); +int bsc_open_connection(struct osmo_bsc_sccp_con *sccp, struct msgb *msg); +enum bsc_con bsc_create_new_connection(struct gsm_subscriber_connection *conn, + struct bsc_msc_data *msc, int send_ping); +int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp); + +struct bsc_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn, struct msgb *); +int bsc_scan_bts_msg(struct gsm_subscriber_connection *conn, struct msgb *msg); +int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg); +int bsc_send_welcome_ussd(struct gsm_subscriber_connection *conn); + +int bsc_handle_udt(struct bsc_msc_data *msc, struct msgb *msg, unsigned int length); +int bsc_handle_dt(struct osmo_bsc_sccp_con *conn, struct msgb *msg, unsigned int len); + +int bsc_ctrl_cmds_install(); + +void bsc_gen_location_state_trap(struct gsm_bts *bts); + +struct llist_head *bsc_access_lists(void); + +#endif diff --git a/include/osmocom/bsc/osmo_bsc_grace.h b/include/osmocom/bsc/osmo_bsc_grace.h new file mode 100644 index 000000000..b7950ce50 --- /dev/null +++ b/include/osmocom/bsc/osmo_bsc_grace.h @@ -0,0 +1,35 @@ +/* + * (C) 2010-2013 by Holger Hans Peter Freyther + * (C) 2010-2013 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef OSMO_BSC_GRACE_H +#define OSMO_BSC_GRACE_H + +#include +#include + +struct bsc_msc_data; + +int bsc_grace_allow_new_connection(struct gsm_network *net, struct gsm_bts *bts); +int bsc_grace_paging_request(enum signal_rf rf_policy, + struct bsc_subscr *subscr, + int chan_needed, + struct bsc_msc_data *msc); + +#endif diff --git a/include/osmocom/bsc/osmo_bsc_reset.h b/include/osmocom/bsc/osmo_bsc_reset.h new file mode 100644 index 000000000..578f763e6 --- /dev/null +++ b/include/osmocom/bsc/osmo_bsc_reset.h @@ -0,0 +1,34 @@ +/* (C) 2017 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/* Create and start state machine which handles the reset/reset-ack procedure */ +void start_reset_fsm(struct bsc_msc_data *msc); + +/* Confirm that we sucessfully received a reset acknowlege message */ +void reset_ack_confirm(struct bsc_msc_data *msc); + +/* Report a failed connection */ +void report_conn_fail(struct bsc_msc_data *msc); + +/* Report a successful connection */ +void report_conn_success(struct bsc_msc_data *msc); + +/* Check if we have a connection to a specified msc */ +bool sccp_conn_ready(struct bsc_msc_data *msc); diff --git a/include/osmocom/bsc/osmo_bsc_rf.h b/include/osmocom/bsc/osmo_bsc_rf.h new file mode 100644 index 000000000..56ac980ca --- /dev/null +++ b/include/osmocom/bsc/osmo_bsc_rf.h @@ -0,0 +1,66 @@ +#ifndef OSMO_BSC_RF +#define OSMO_BSC_RF + +#include +#include +#include + +enum osmo_bsc_rf_opstate { + OSMO_BSC_RF_OPSTATE_INOPERATIONAL, + OSMO_BSC_RF_OPSTATE_OPERATIONAL, +}; + +enum osmo_bsc_rf_adminstate { + OSMO_BSC_RF_ADMINSTATE_UNLOCKED, + OSMO_BSC_RF_ADMINSTATE_LOCKED, +}; + +enum osmo_bsc_rf_policy { + OSMO_BSC_RF_POLICY_OFF, + OSMO_BSC_RF_POLICY_ON, + OSMO_BSC_RF_POLICY_GRACE, + OSMO_BSC_RF_POLICY_UNKNOWN, +}; + + +struct gsm_network; + +struct osmo_bsc_rf { + /* the value of signal.h */ + int policy; + struct osmo_fd listen; + struct gsm_network *gsm_network; + + const char *last_state_command; + + char *last_rf_lock_ctrl_command; + + /* delay the command */ + char last_request; + struct osmo_timer_list delay_cmd; + + /* verify that RF is up as it should be */ + struct osmo_timer_list rf_check; + + /* some handling for the automatic grace switch */ + struct osmo_timer_list grace_timeout; + + /* auto RF switch-off due lack of MSC connection */ + struct osmo_timer_list auto_off_timer; +}; + +struct osmo_bsc_rf_conn { + struct osmo_wqueue queue; + struct osmo_bsc_rf *rf; +}; + +const char *osmo_bsc_rf_get_opstate_name(enum osmo_bsc_rf_opstate opstate); +const char *osmo_bsc_rf_get_adminstate_name(enum osmo_bsc_rf_adminstate adminstate); +const char *osmo_bsc_rf_get_policy_name(enum osmo_bsc_rf_policy policy); +enum osmo_bsc_rf_opstate osmo_bsc_rf_get_opstate_by_bts(struct gsm_bts *bts); +enum osmo_bsc_rf_adminstate osmo_bsc_rf_get_adminstate_by_bts(struct gsm_bts *bts); +enum osmo_bsc_rf_policy osmo_bsc_rf_get_policy_by_bts(struct gsm_bts *bts); +struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net); +void osmo_bsc_rf_schedule_lock(struct osmo_bsc_rf *rf, char cmd); + +#endif diff --git a/include/osmocom/bsc/osmo_bsc_sigtran.h b/include/osmocom/bsc/osmo_bsc_sigtran.h new file mode 100644 index 000000000..89649036e --- /dev/null +++ b/include/osmocom/bsc/osmo_bsc_sigtran.h @@ -0,0 +1,48 @@ +/* (C) 2017 by Sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#include +#include + +/* Allocate resources to make a new connection oriented sigtran connection + * (not the connection ittself!) */ +enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, struct bsc_msc_data *msc); + +/* Open a new connection oriented sigtran connection */ +int osmo_bsc_sigtran_open_conn(const struct osmo_bsc_sccp_con *conn, struct msgb *msg); + +/* Send data to MSC */ +int osmo_bsc_sigtran_send(const struct osmo_bsc_sccp_con *conn, struct msgb *msg); + +/* Delete a connection from the list with open connections + * (called by osmo_bsc_api.c on failing open connections and + * locally, when a connection is closed by the MSC */ +int osmo_bsc_sigtran_del_conn(struct osmo_bsc_sccp_con *sccp); + +/* Initalize osmo sigtran backhaul */ +int osmo_bsc_sigtran_init(struct llist_head *mscs); + +/* Close all open sigtran connections and channels */ +void osmo_bsc_sigtran_reset(const struct bsc_msc_data *msc); + +/* Send reset-ack to MSC */ +void osmo_bsc_sigtran_tx_reset_ack(const struct bsc_msc_data *msc); diff --git a/include/osmocom/bsc/osmo_msc.h b/include/osmocom/bsc/osmo_msc.h new file mode 100644 index 000000000..c08cb26b1 --- /dev/null +++ b/include/osmocom/bsc/osmo_msc.h @@ -0,0 +1,99 @@ +/* Routines for the MSC handling */ + +#ifndef OSMO_MSC_H +#define OSMO_MSC_H + +#include +#include + +#include + +#include "bsc_api.h" + +#define MSC_HLR_REMOTE_IP_DEFAULT "127.0.0.1" +#define MSC_HLR_REMOTE_PORT_DEFAULT OSMO_GSUP_PORT + +enum subscr_conn_fsm_event { + /* Mark 0 as invalid to catch uninitialized vars */ + SUBSCR_CONN_E_INVALID = 0, + /* Timeout on connection establishment starts */ + SUBSCR_CONN_E_START, + /* LU or Process Access FSM has determined that this conn is good */ + SUBSCR_CONN_E_ACCEPTED, + /* received first reply from MS in "real" CC, SMS, USSD communication */ + SUBSCR_CONN_E_COMMUNICATING, + /* Some async action has completed, check again whether all is done */ + SUBSCR_CONN_E_BUMP, + /* MS/BTS/BSC originated close request */ + SUBSCR_CONN_E_MO_CLOSE, + /* MSC originated close request, e.g. failed authentication */ + SUBSCR_CONN_E_CN_CLOSE, +}; + +enum subscr_conn_fsm_state { + SUBSCR_CONN_S_INIT, + SUBSCR_CONN_S_NEW, + SUBSCR_CONN_S_ACCEPTED, + SUBSCR_CONN_S_COMMUNICATING, + SUBSCR_CONN_S_RELEASED, +}; + +enum subscr_conn_from { + SUBSCR_CONN_FROM_INVALID, + SUBSCR_CONN_FROM_LU, + SUBSCR_CONN_FROM_CM_SERVICE_REQ, + SUBSCR_CONN_FROM_PAGING_RESP, +}; + +extern const struct value_string subscr_conn_from_names[]; +static inline const char *subscr_conn_from_name(enum subscr_conn_from val) +{ + return get_value_string(subscr_conn_from_names, val); +} + +enum msc_compl_l3_rc { + MSC_CONN_ACCEPT = 0, + MSC_CONN_REJECT = 1, +}; + +struct bsc_api *msc_bsc_api(); + +int msc_create_conn_fsm(struct gsm_subscriber_connection *conn, const char *id); + +int msc_vlr_alloc(struct gsm_network *net); +int msc_vlr_start(struct gsm_network *net); + +void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci); +int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause); +int msc_compl_l3(struct gsm_subscriber_connection *conn, + struct msgb *msg, uint16_t chosen_channel); +void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, + struct msgb *msg); +void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn, + struct msgb *msg, uint8_t alg_id); +void msc_rx_sec_mode_compl(struct gsm_subscriber_connection *conn); +void msc_classmark_chg(struct gsm_subscriber_connection *conn, + const uint8_t *cm2, uint8_t cm2_len, + const uint8_t *cm3, uint8_t cm3_len); +void msc_assign_fail(struct gsm_subscriber_connection *conn, + uint8_t cause, uint8_t *rr_cause); + +void msc_subscr_conn_init(void); +bool msc_subscr_conn_is_accepted(struct gsm_subscriber_connection *conn); +void msc_subscr_conn_communicating(struct gsm_subscriber_connection *conn); +void msc_subscr_conn_close(struct gsm_subscriber_connection *conn, + uint32_t cause); + +#define msc_subscr_conn_get(conn) \ + _msc_subscr_conn_get(conn, __BASE_FILE__, __LINE__) +#define msc_subscr_conn_put(conn) \ + _msc_subscr_conn_put(conn, __BASE_FILE__, __LINE__) +struct gsm_subscriber_connection * +_msc_subscr_conn_get(struct gsm_subscriber_connection *conn, + const char *file, int line); +void _msc_subscr_conn_put(struct gsm_subscriber_connection *conn, + const char *file, int line); + +void msc_stop_paging(struct vlr_subscr *vsub); + +#endif diff --git a/include/osmocom/bsc/osmux.h b/include/osmocom/bsc/osmux.h new file mode 100644 index 000000000..f3ea72a85 --- /dev/null +++ b/include/osmocom/bsc/osmux.h @@ -0,0 +1,41 @@ +#ifndef _OPENBSC_OSMUX_H_ +#define _OPENBSC_OSMUX_H_ + +#include + +#define OSMUX_PORT 1984 + +enum { + OSMUX_ROLE_BSC = 0, + OSMUX_ROLE_BSC_NAT, +}; + +int osmux_init(int role, struct mgcp_config *cfg); +int osmux_enable_endpoint(struct mgcp_endpoint *endp, struct in_addr *addr, uint16_t port); +void osmux_disable_endpoint(struct mgcp_endpoint *endp); +void osmux_allocate_cid(struct mgcp_endpoint *endp); +void osmux_release_cid(struct mgcp_endpoint *endp); + +int osmux_xfrm_to_rtp(struct mgcp_endpoint *endp, int type, char *buf, int rc); +int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp); + +int osmux_send_dummy(struct mgcp_endpoint *endp); + +int osmux_get_cid(void); +void osmux_put_cid(uint8_t osmux_cid); +int osmux_used_cid(void); + +enum osmux_state { + OSMUX_STATE_DISABLED = 0, + OSMUX_STATE_NEGOTIATING, + OSMUX_STATE_ACTIVATING, + OSMUX_STATE_ENABLED, +}; + +enum osmux_usage { + OSMUX_USAGE_OFF = 0, + OSMUX_USAGE_ON = 1, + OSMUX_USAGE_ONLY = 2, +}; + +#endif diff --git a/include/osmocom/bsc/paging.h b/include/osmocom/bsc/paging.h new file mode 100644 index 000000000..e917772a7 --- /dev/null +++ b/include/osmocom/bsc/paging.h @@ -0,0 +1,77 @@ +/* Paging helper and manager.... */ +/* (C) 2009 by Holger Hans Peter Freyther + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef PAGING_H +#define PAGING_H + +#include +#include + +#include +#include + +#include +#include + +/** + * A pending paging request + */ +struct gsm_paging_request { + /* list_head for list of all paging requests */ + struct llist_head entry; + /* the subscriber which we're paging. Later gsm_paging_request + * should probably become a part of the bsc_subsrc struct? */ + struct bsc_subscr *bsub; + /* back-pointer to the BTS on which we are paging */ + struct gsm_bts *bts; + /* what kind of channel type do we ask the MS to establish */ + int chan_type; + + /* Timer 3113: how long do we try to page? */ + struct osmo_timer_list T3113; + + /* How often did we ask the BTS to page? */ + int attempts; + + /* callback to be called in case paging completes */ + gsm_cbfn *cbfn; + void *cbfn_param; +}; + +/* schedule paging request */ +int paging_request(struct gsm_network *network, struct bsc_subscr *bsub, + int type, gsm_cbfn *cbfn, void *data); +int paging_request_bts(struct gsm_bts *bts, struct bsc_subscr *bsub, + int type, gsm_cbfn *cbfn, void *data); + +/* stop paging requests */ +void paging_request_stop(struct llist_head *bts_list, + struct gsm_bts *_bts, struct bsc_subscr *bsub, + struct gsm_subscriber_connection *conn, + struct msgb *msg); + +/* update paging load */ +void paging_update_buffer_space(struct gsm_bts *bts, uint16_t); + +/* pending paging requests */ +unsigned int paging_pending_requests_nr(struct gsm_bts *bts); + +void *paging_get_data(struct gsm_bts *bts, struct bsc_subscr *bsub); + +#endif diff --git a/include/osmocom/bsc/pcu_if.h b/include/osmocom/bsc/pcu_if.h new file mode 100644 index 000000000..1f398b4aa --- /dev/null +++ b/include/osmocom/bsc/pcu_if.h @@ -0,0 +1,35 @@ +#ifndef _PCU_IF_H +#define _PCU_IF_H + +#include + +extern int pcu_direct; + +struct pcu_sock_state { + struct gsm_network *net; + struct osmo_fd listen_bfd; /* fd for listen socket */ + struct osmo_fd conn_bfd; /* fd for connection to lcr */ + struct llist_head upqueue; /* queue for sending messages */ +}; + +/* PCU relevant information has changed; Inform PCU (if connected) */ +void pcu_info_update(struct gsm_bts *bts); + +/* Forward rach indication to PCU */ +int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn, + uint8_t is_11bit, enum ph_burst_type burst_type); + +/* Confirm the sending of an immediate assignment to the pcu */ +int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli); + + +/* Confirm the sending of an immediate assignment to the pcu */ +int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli); + +/* Open connection to PCU */ +int pcu_sock_init(const char *path, struct gsm_bts *bts); + +/* Close connection to PCU */ +void pcu_sock_exit(struct gsm_bts *bts); + +#endif /* _PCU_IF_H */ diff --git a/include/osmocom/bsc/pcuif_proto.h b/include/osmocom/bsc/pcuif_proto.h new file mode 100644 index 000000000..eb28d66bc --- /dev/null +++ b/include/osmocom/bsc/pcuif_proto.h @@ -0,0 +1,176 @@ +#ifndef _PCUIF_PROTO_H +#define _PCUIF_PROTO_H + +#define PCU_IF_VERSION 0x08 + +/* msg_type */ +#define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ +#define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */ +#define PCU_IF_MSG_DATA_IND 0x02 /* receive data from given channel */ +#define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */ +#define PCU_IF_MSG_RTS_REQ 0x10 /* ready to send request */ +#define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */ +#define PCU_IF_MSG_INFO_IND 0x32 /* retrieve BTS info */ +#define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */ +#define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */ +#define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */ + +/* sapi */ +#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */ +#define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */ +#define PCU_IF_SAPI_PCH 0x03 /* paging/assignment on PCH */ +#define PCU_IF_SAPI_BCCH 0x04 /* SI on BCCH */ +#define PCU_IF_SAPI_PDTCH 0x05 /* packet data/control/ccch block */ +#define PCU_IF_SAPI_PRACH 0x06 /* packet random access channel */ +#define PCU_IF_SAPI_PTCCH 0x07 /* packet TA control channel */ +#define PCU_IF_SAPI_AGCH_DT 0x08 /* assignment on AGCH but with additional TLLI */ + +/* flags */ +#define PCU_IF_FLAG_ACTIVE (1 << 0)/* BTS is active */ +#define PCU_IF_FLAG_SYSMO (1 << 1)/* access PDCH of sysmoBTS directly */ +#define PCU_IF_FLAG_CS1 (1 << 16) +#define PCU_IF_FLAG_CS2 (1 << 17) +#define PCU_IF_FLAG_CS3 (1 << 18) +#define PCU_IF_FLAG_CS4 (1 << 19) +#define PCU_IF_FLAG_MCS1 (1 << 20) +#define PCU_IF_FLAG_MCS2 (1 << 21) +#define PCU_IF_FLAG_MCS3 (1 << 22) +#define PCU_IF_FLAG_MCS4 (1 << 23) +#define PCU_IF_FLAG_MCS5 (1 << 24) +#define PCU_IF_FLAG_MCS6 (1 << 25) +#define PCU_IF_FLAG_MCS7 (1 << 26) +#define PCU_IF_FLAG_MCS8 (1 << 27) +#define PCU_IF_FLAG_MCS9 (1 << 28) + +struct gsm_pcu_if_data { + uint8_t sapi; + uint8_t len; + uint8_t data[162]; + uint32_t fn; + uint16_t arfcn; + uint8_t trx_nr; + uint8_t ts_nr; + uint8_t block_nr; + int8_t rssi; + uint16_t ber10k; /*!< \brief BER in units of 0.01% */ + int16_t ta_offs_qbits; /* !< \brief Burst TA Offset in quarter bits */ + int16_t lqual_cb; /* !< \brief Link quality in centiBel */ +} __attribute__ ((packed)); + +/* data confirmation with direct tlli (instead of raw mac block with tlli) */ +struct gsm_pcu_if_data_cnf_dt { + uint8_t sapi; + uint32_t tlli; + uint32_t fn; + uint16_t arfcn; + uint8_t trx_nr; + uint8_t ts_nr; + uint8_t block_nr; + int8_t rssi; + uint16_t ber10k; /*!< \brief BER in units of 0.01% */ + int16_t ta_offs_qbits; /* !< \brief Burst TA Offset in quarter bits */ + int16_t lqual_cb; /* !< \brief Link quality in centiBel */ +} __attribute__ ((packed)); + +struct gsm_pcu_if_rts_req { + uint8_t sapi; + uint8_t spare[3]; + uint32_t fn; + uint16_t arfcn; + uint8_t trx_nr; + uint8_t ts_nr; + uint8_t block_nr; +} __attribute__ ((packed)); + +struct gsm_pcu_if_rach_ind { + uint8_t sapi; + uint16_t ra; + int16_t qta; + uint32_t fn; + uint16_t arfcn; + uint8_t is_11bit; + uint8_t burst_type; +} __attribute__ ((packed)); + +struct gsm_pcu_if_info_trx { + uint16_t arfcn; + uint8_t pdch_mask; /* PDCH channels per TS */ + uint8_t spare; + uint8_t tsc[8]; /* TSC per channel */ + uint32_t hlayer1; +} __attribute__ ((packed)); + +struct gsm_pcu_if_info_ind { + uint32_t version; + uint32_t flags; + struct gsm_pcu_if_info_trx trx[8]; /* TRX infos per BTS */ + uint8_t bsic; + /* RAI */ + uint16_t mcc, mnc, lac, rac; + /* NSE */ + uint16_t nsei; + uint8_t nse_timer[7]; + uint8_t cell_timer[11]; + /* cell */ + uint16_t cell_id; + uint16_t repeat_time; + uint8_t repeat_count; + uint16_t bvci; + uint8_t t3142; + uint8_t t3169; + uint8_t t3191; + uint8_t t3193_10ms; + uint8_t t3195; + uint8_t n3101; + uint8_t n3103; + uint8_t n3105; + uint8_t cv_countdown; + uint16_t dl_tbf_ext; + uint16_t ul_tbf_ext; + uint8_t initial_cs; + uint8_t initial_mcs; + /* NSVC */ + uint16_t nsvci[2]; + uint16_t local_port[2]; + uint16_t remote_port[2]; + uint32_t remote_ip[2]; +} __attribute__ ((packed)); + +struct gsm_pcu_if_act_req { + uint8_t activate; + uint8_t trx_nr; + uint8_t ts_nr; + uint8_t spare; +} __attribute__ ((packed)); + +struct gsm_pcu_if_time_ind { + uint32_t fn; +} __attribute__ ((packed)); + +struct gsm_pcu_if_pag_req { + uint8_t sapi; + uint8_t chan_needed; + uint8_t identity_lv[9]; +} __attribute__ ((packed)); + +struct gsm_pcu_if { + /* context based information */ + uint8_t msg_type; /* message type */ + uint8_t bts_nr; /* bts number */ + uint8_t spare[2]; + + union { + struct gsm_pcu_if_data data_req; + struct gsm_pcu_if_data data_cnf; + struct gsm_pcu_if_data_cnf_dt data_cnf_dt; + struct gsm_pcu_if_data data_ind; + struct gsm_pcu_if_rts_req rts_req; + struct gsm_pcu_if_rach_ind rach_ind; + struct gsm_pcu_if_info_ind info_ind; + struct gsm_pcu_if_act_req act_req; + struct gsm_pcu_if_time_ind time_ind; + struct gsm_pcu_if_pag_req pag_req; + } u; +} __attribute__ ((packed)); + +#endif /* _PCUIF_PROTO_H */ diff --git a/include/osmocom/bsc/rest_octets.h b/include/osmocom/bsc/rest_octets.h new file mode 100644 index 000000000..374b1ba10 --- /dev/null +++ b/include/osmocom/bsc/rest_octets.h @@ -0,0 +1,140 @@ +#ifndef _REST_OCTETS_H +#define _REST_OCTETS_H + +#include +#include + +struct gsm_bts; + +/* generate SI1 rest octets */ +int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net); +int rest_octets_si2quater(uint8_t *data, struct gsm_bts *bts); +int rest_octets_si6(uint8_t *data, bool is1800_net); + +struct gsm48_si_selection_params { + uint16_t penalty_time:5, + temp_offs:3, + cell_resel_off:6, + cbq:1, + present:1; +}; + +struct gsm48_si_power_offset { + uint8_t power_offset:2, + present:1; +}; + +struct gsm48_si3_gprs_ind { + uint8_t si13_position:1, + ra_colour:3, + present:1; +}; + +struct gsm48_lsa_params { + uint32_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; + uint8_t si2ter_indicator; + uint8_t early_cm_ctrl; + struct { + uint8_t where:3, + present:1; + } scheduling; + struct gsm48_si3_gprs_ind gprs_ind; + /* SI 3 specific */ + uint8_t si2quater_indicator; + /* SI 4 specific */ + struct gsm48_lsa_params lsa_params; + uint16_t cell_id; + uint8_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(uint8_t *data, const struct gsm48_si_ro_info *si3); + +/* Generate SI4 Rest Octets (Chapter 10.5.2.35) */ +int rest_octets_si4(uint8_t *data, const struct gsm48_si_ro_info *si4, int len); + +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 */ +}; + +/* TS 04.60 12.24 */ +struct gprs_cell_options { + enum gprs_nmo nmo; + /* T3168: wait for packet uplink assignment message */ + uint32_t t3168; /* in milliseconds */ + /* T3192: wait for release of the TBF after reception of the final block */ + uint32_t t3192; /* in milliseconds */ + uint32_t drx_timer_max;/* in seconds */ + uint32_t bs_cv_max; + uint8_t supports_egprs_11bit_rach; + bool ctrl_ack_type_use_block; /* use PACKET CONTROL ACKNOWLEDGMENT */ + + uint8_t ext_info_present; + struct { + uint8_t egprs_supported; + uint8_t use_egprs_p_ch_req; + uint8_t bep_period; + uint8_t pfc_supported; + uint8_t dtm_supported; + uint8_t bss_paging_coordination; + } ext_info; +}; + +/* TS 04.60 Table 12.9.2 */ +struct gprs_power_ctrl_pars { + uint8_t alpha; + uint8_t t_avg_w; + uint8_t t_avg_t; + uint8_t pc_meas_chan; + uint8_t n_avg_i; +}; + +struct gsm48_si13_info { + struct gprs_cell_options cell_opts; + struct gprs_power_ctrl_pars pwr_ctrl_pars; + uint8_t bcch_change_mark; + uint8_t si_change_field; + uint8_t pbcch_present; + + union { + struct { + uint8_t rac; + uint8_t spgc_ccch_sup; + uint8_t net_ctrl_ord; + uint8_t prio_acc_thr; + } no_pbcch; + struct { + uint8_t psi1_rep_per; + uint8_t pb; + uint8_t tsc; + uint8_t tn; + enum pbcch_carrier_type carrier_type; + uint16_t arfcn; + uint8_t maio; + } pbcch; + }; +}; + +/* Generate SI13 Rest Octests (Chapter 10.5.2.37b) */ +int rest_octets_si13(uint8_t *data, const struct gsm48_si13_info *si13); + +#endif /* _REST_OCTETS_H */ diff --git a/include/osmocom/bsc/rrlp.h b/include/osmocom/bsc/rrlp.h new file mode 100644 index 000000000..c89402a2d --- /dev/null +++ b/include/osmocom/bsc/rrlp.h @@ -0,0 +1,7 @@ +#ifndef _RRLP_H +#define _RRLP_H + +void on_dso_load_rrlp(void); + +#endif /* _RRLP_H */ + diff --git a/include/osmocom/bsc/rs232.h b/include/osmocom/bsc/rs232.h new file mode 100644 index 000000000..61187ca62 --- /dev/null +++ b/include/osmocom/bsc/rs232.h @@ -0,0 +1,9 @@ +#ifndef _RS232_H +#define _RS232_H + +int rs232_setup(const char *serial_port, unsigned int delay_ms, + struct gsm_bts *bts); + +int handle_serial_msg(struct msgb *msg); + +#endif /* _RS232_H */ diff --git a/include/osmocom/bsc/rtp_proxy.h b/include/osmocom/bsc/rtp_proxy.h new file mode 100644 index 000000000..918420ce5 --- /dev/null +++ b/include/osmocom/bsc/rtp_proxy.h @@ -0,0 +1,95 @@ +#ifndef _RTP_PROXY_H +#define _RTP_PROXY_H + +/* RTP proxy handling for ip.access nanoBTS */ + +/* (C) 2009 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + + +#include + +#include +#include + +#include + +#define RTP_PT_GSM_FULL 3 +#define RTP_PT_GSM_HALF 96 +#define RTP_PT_GSM_EFR 97 +#define RTP_PT_AMR 98 +#define RTP_LEN_GSM_FULL 33 +#define RTP_LEN_GSM_HALF 15 +#define RTP_LEN_GSM_EFR 31 +#define RTP_GSM_DURATION 160 + +enum rtp_rx_action { + RTP_NONE, + RTP_PROXY, + 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; + + struct osmo_fd bfd; + /* linked list of to-be-transmitted msgb's */ + struct llist_head tx_queue; +}; + +struct rtp_socket { + struct llist_head list; + + struct rtp_sub_socket rtp; + struct rtp_sub_socket rtcp; + + /* what should we do on receive? */ + enum rtp_rx_action rx_action; + union { + struct { + struct rtp_socket *other_sock; + } proxy; + struct { + struct gsm_network *net; + uint32_t callref; + } receive; + }; + enum rtp_tx_action tx_action; + struct { + uint16_t sequence; + uint32_t timestamp; + uint32_t ssrc; + struct timeval last_tv; + } transmit; +}; + +struct rtp_socket *rtp_socket_create(void); +int rtp_socket_bind(struct rtp_socket *rs, uint32_t ip); +int rtp_socket_connect(struct rtp_socket *rs, uint32_t ip, uint16_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, uint32_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/include/osmocom/bsc/sgsn.h b/include/osmocom/bsc/sgsn.h new file mode 100644 index 000000000..f71b6491a --- /dev/null +++ b/include/osmocom/bsc/sgsn.h @@ -0,0 +1,191 @@ +#ifndef _SGSN_H +#define _SGSN_H + + +#include +#include +#include +#include +#include +#include + +#include + +struct gprs_gsup_client; +struct hostent; + +enum sgsn_auth_policy { + SGSN_AUTH_POLICY_OPEN, + SGSN_AUTH_POLICY_CLOSED, + SGSN_AUTH_POLICY_ACL_ONLY, + SGSN_AUTH_POLICY_REMOTE +}; + + +enum sgsn_rate_ctr_keys { + CTR_LLC_DL_BYTES, + CTR_LLC_UL_BYTES, + CTR_LLC_DL_PACKETS, + CTR_LLC_UL_PACKETS, + CTR_GPRS_ATTACH_REQUEST, + CTR_GPRS_ATTACH_ACKED, + CTR_GPRS_ATTACH_REJECTED, + CTR_GPRS_DETACH_REQUEST, + CTR_GPRS_DETACH_ACKED, + CTR_GPRS_ROUTING_AREA_REQUEST, + CTR_GPRS_ROUTING_AREA_ACKED, + CTR_GPRS_ROUTING_AREA_REJECT, + /* PDP single packet counter / GSM 04.08 9.5.1 - 9.5.9 */ + CTR_PDP_ACTIVATE_REQUEST, + CTR_PDP_ACTIVATE_REJECT, + CTR_PDP_ACTIVATE_ACCEPT, + CTR_PDP_REQUEST_ACTIVATE, /* unused */ + CTR_PDP_REQUEST_ACTIVATE_REJ, /* unused */ + CTR_PDP_MODIFY_REQUEST, /* unsued */ + CTR_PDP_MODIFY_ACCEPT, /* unused */ + CTR_PDP_DL_DEACTIVATE_REQUEST, + CTR_PDP_DL_DEACTIVATE_ACCEPT, + CTR_PDP_UL_DEACTIVATE_REQUEST, + CTR_PDP_UL_DEACTIVATE_ACCEPT, +}; + +struct sgsn_cdr { + char *filename; + int interval; +}; + +struct sgsn_config { + /* parsed from config file */ + + char *gtp_statedir; + struct sockaddr_in gtp_listenaddr; + + /* misc */ + struct gprs_ns_inst *nsi; + + enum sgsn_auth_policy auth_policy; + enum gprs_ciph_algo cipher; + struct llist_head imsi_acl; + + struct sockaddr_in gsup_server_addr; + int gsup_server_port; + + int require_authentication; + int require_update_location; + + /* CDR configuration */ + struct sgsn_cdr cdr; + + struct { + int T3312; + int T3322; + int T3350; + int T3360; + int T3370; + int T3313; + int T3314; + int T3316; + int T3385; + int T3386; + int T3395; + int T3397; + } timers; + + int dynamic_lookup; + + struct oap_client_config oap; + + /* RFC1144 TCP/IP header compression */ + struct { + int active; + int passive; + int s01; + } pcomp_rfc1144; + + /* V.42vis data compression */ + struct { + int active; + int passive; + int p0; + int p1; + int p2; + } dcomp_v42bis; + + struct { + int rab_assign_addr_enc; + } iu; +}; + +struct sgsn_instance { + char *config_file; + struct sgsn_config cfg; + /* File descriptor wrappers for LibGTP */ + struct osmo_fd gtp_fd0; + struct osmo_fd gtp_fd1c; + struct osmo_fd gtp_fd1u; + /* Timer for libGTP */ + struct osmo_timer_list gtp_timer; + /* GSN instance for libgtp */ + struct gsn_t *gsn; + /* Subscriber */ + struct gsup_client *gsup_client; + /* LLME inactivity timer */ + struct osmo_timer_list llme_timer; + + /* c-ares event loop integration */ + struct osmo_timer_list ares_timer; + struct llist_head ares_fds; + ares_channel ares_channel; + struct ares_addr_node *ares_servers; + + struct rate_ctr_group *rate_ctrs; +}; + +extern struct sgsn_instance *sgsn; + +/* sgsn_vty.c */ + +int sgsn_vty_init(struct sgsn_config *cfg); +int sgsn_parse_config(const char *config_file); + +/* sgsn.c */ + +/* Main input function for Gb proxy */ +int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci); + + +struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, + struct sgsn_mm_ctx *mmctx, + uint16_t nsapi, + struct tlv_parsed *tp); +int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx); +void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen); + +/* gprs_sndcp.c */ + +/* Entry point for the SNSM-ACTIVATE.indication */ +int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); +/* Entry point for the SNSM-DEACTIVATE.indication */ +int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); +/* Called by SNDCP when it has received/re-assembled a N-PDU */ +int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi, + struct msgb *msg, uint32_t npdu_len, uint8_t *npdu); +int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi, + void *mmcontext); +int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle, + uint8_t *hdr, uint16_t len); + + +/* + * CDR related functionality + */ +int sgsn_cdr_init(struct sgsn_instance *sgsn); + + +/* + * C-ARES related functionality + */ +int sgsn_ares_init(struct sgsn_instance *sgsn); +int sgsn_ares_query(struct sgsn_instance *sgsm, const char *name, ares_host_callback cb, void *data); + +#endif diff --git a/include/osmocom/bsc/signal.h b/include/osmocom/bsc/signal.h new file mode 100644 index 000000000..feab246c2 --- /dev/null +++ b/include/osmocom/bsc/signal.h @@ -0,0 +1,260 @@ +/* Generic signalling/notification infrastructure */ +/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther + * (C) 2009 by Harald Welte + * (C) 2010 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef OPENBSC_SIGNAL_H +#define OPENBSC_SIGNAL_H + +#include +#include + +#include + +#include + +/* + * Signalling subsystems + */ +enum signal_subsystems { + SS_PAGING, + SS_SMS, + SS_ABISIP, + SS_NM, + SS_LCHAN, + SS_SUBSCR, + SS_SCALL, + SS_CHALLOC, + SS_IPAC_NWL, + SS_RF, + SS_MSC, + SS_HO, + SS_CCCH, + SS_SGSN, +}; + +/* SS_PAGING signals */ +enum signal_paging { + S_PAGING_SUCCEEDED, + S_PAGING_EXPIRED, +}; + +/* SS_SMS signals */ +enum signal_sms { + S_SMS_SUBMITTED, /* A SMS has been successfully submitted to us */ + S_SMS_DELIVERED, /* A SMS has been successfully delivered to a MS */ + S_SMS_SMMA, /* A MS tells us it has more space available */ + S_SMS_MEM_EXCEEDED, /* A MS tells us it has no more space available */ + S_SMS_UNKNOWN_ERROR, /* A MS tells us it has an error */ +}; + +/* SS_ABISIP signals */ +enum signal_abisip { + S_ABISIP_CRCX_ACK, + S_ABISIP_MDCX_ACK, + S_ABISIP_DLCX_IND, +}; + +/* SS_NM signals */ +enum signal_nm { + S_NM_SW_ACTIV_REP, /* GSM 12.21 software activated report */ + S_NM_FAIL_REP, /* GSM 12.21 failure event report */ + S_NM_NACK, /* GSM 12.21 various NM_MT_*_NACK happened */ + S_NM_IPACC_NACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_NACK happened */ + S_NM_IPACC_ACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_ACK happened */ + S_NM_IPACC_RESTART_ACK, /* nanoBTS has send a restart ack */ + S_NM_IPACC_RESTART_NACK,/* nanoBTS has send a restart ack */ + S_NM_TEST_REP, /* GSM 12.21 Test Report */ + S_NM_STATECHG_OPER, /* Operational State changed*/ + S_NM_STATECHG_ADM, /* Administrative State changed */ + S_NM_OM2K_CONF_RES, /* OM2K Configuration Result */ +}; + +/* SS_LCHAN signals */ +enum signal_lchan { + /* + * The lchan got freed with an use_count != 0 and error + * recovery needs to be carried out from within the + * 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_CHALLOC signals */ +enum signal_challoc { + S_CHALLOC_ALLOC_FAIL, /* allocation of lchan has failed */ + S_CHALLOC_FREED, /* lchan has been successfully freed */ +}; + +/* SS_SUBSCR signals */ +enum signal_subscr { + S_SUBSCR_ATTACHED, + S_SUBSCR_DETACHED, + S_SUBSCR_IDENTITY, /* we've received some identity information */ +}; + +/* SS_SCALL signals */ +enum signal_scall { + S_SCALL_SUCCESS, + S_SCALL_EXPIRED, + S_SCALL_DETACHED, +}; + +/* SS_IPAC_NWL signals */ +enum signal_ipaccess { + S_IPAC_NWL_COMPLETE, +}; + +enum signal_global { + S_GLOBAL_BTS_CLOSE_OM, +}; + +/* SS_RF signals */ +enum signal_rf { + S_RF_OFF, + S_RF_ON, + S_RF_GRACE, +}; + +struct paging_signal_data { + struct vlr_subscr *vsub; + struct gsm_bts *bts; + + int paging_result; + + /* NULL in case the paging didn't work */ + struct gsm_subscriber_connection *conn; +}; + +struct scall_signal_data { + struct gsm_subscriber_connection *conn; + void *data; +}; + +struct ipacc_ack_signal_data { + struct gsm_bts_trx *trx; + uint8_t msg_type; +}; + +struct abis_om2k_mo; + +struct nm_statechg_signal_data { + struct gsm_bts *bts; + uint8_t obj_class; + void *obj; + struct gsm_nm_state *old_state; + struct gsm_nm_state *new_state; + + /* This pointer is vaold for TS 12.21 MO */ + struct abis_om_obj_inst *obj_inst; + /* This pointer is vaold for RBS2000 MO */ + struct abis_om2k_mo *om2k_mo; +}; + +struct nm_om2k_signal_data { + struct gsm_bts *bts; + void *obj; + struct abis_om2k_mo *om2k_mo; + + uint8_t accordance_ind; +}; + +struct nm_nack_signal_data { + struct msgb *msg; + struct gsm_bts *bts; + uint8_t mt; +}; + +struct challoc_signal_data { + struct gsm_bts *bts; + struct gsm_lchan *lchan; + enum gsm_chan_t type; +}; + +struct rf_signal_data { + struct gsm_network *net; +}; + +struct sms_signal_data { + /* The transaction where this occured */ + struct gsm_trans *trans; + /* Can be NULL for SMMA */ + struct gsm_sms *sms; + /* int paging result. Only the ones with > 0 */ + int paging_result; +}; + +struct lchan_signal_data { + /* The lchan the signal happened on */ + struct gsm_lchan *lchan; + /* Measurement reports on this lchan */ + struct gsm_meas_rep *mr; +}; + +/* MSC signals */ +enum signal_msc { + S_MSC_LOST, + S_MSC_CONNECTED, + S_MSC_AUTHENTICATED, +}; + +struct bsc_msc_data; +struct msc_signal_data { + struct bsc_msc_data *data; +}; + +/* SS_CCCH signals */ +enum signal_ccch { + S_CCCH_PAGING_LOAD, + S_CCCH_RACH_LOAD, +}; + +struct ccch_signal_data { + struct gsm_bts *bts; + uint16_t pg_buf_space; + uint16_t rach_slot_count; + uint16_t rach_busy_count; + uint16_t rach_access_count; +}; + +/* GPRS SGSN signals SS_SGSN */ +enum signal_sgsn { + S_SGSN_ATTACH, + S_SGSN_DETACH, + S_SGSN_UPDATE, + S_SGSN_PDP_ACT, + S_SGSN_PDP_DEACT, + S_SGSN_PDP_TERMINATE, + S_SGSN_PDP_FREE, + S_SGSN_MM_FREE, +}; + +struct sgsn_mm_ctx; +struct sgsn_signal_data { + struct sgsn_mm_ctx *mm; + struct sgsn_pdp_ctx *pdp; /* non-NULL for PDP_ACT, PDP_DEACT, PDP_FREE */ +}; + +#endif diff --git a/include/osmocom/bsc/silent_call.h b/include/osmocom/bsc/silent_call.h new file mode 100644 index 000000000..5fec77b73 --- /dev/null +++ b/include/osmocom/bsc/silent_call.h @@ -0,0 +1,15 @@ +#ifndef _SILENT_CALL_H +#define _SILENT_CALL_H + +struct gsm_subscriber_connection; + +extern int gsm_silent_call_start(struct vlr_subscr *vsub, + void *data, int type); +extern int gsm_silent_call_stop(struct vlr_subscr *vsub); + +#if 0 +extern int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg); +extern int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg); +#endif + +#endif /* _SILENT_CALL_H */ diff --git a/include/osmocom/bsc/smpp.h b/include/osmocom/bsc/smpp.h new file mode 100644 index 000000000..bcdac8f0b --- /dev/null +++ b/include/osmocom/bsc/smpp.h @@ -0,0 +1,4 @@ +#pragma once + +int smpp_openbsc_alloc_init(void *ctx); +int smpp_openbsc_start(struct gsm_network *net); diff --git a/include/osmocom/bsc/sms_queue.h b/include/osmocom/bsc/sms_queue.h new file mode 100644 index 000000000..2a8bd5850 --- /dev/null +++ b/include/osmocom/bsc/sms_queue.h @@ -0,0 +1,17 @@ +#ifndef SMS_QUEUE_H +#define SMS_QUEUE_H + +struct gsm_network; +struct gsm_sms_queue; +struct vty; + +int sms_queue_start(struct gsm_network *, int in_flight); +int sms_queue_trigger(struct gsm_sms_queue *); + +/* vty helper functions */ +int sms_queue_stats(struct gsm_sms_queue *, struct vty* vty); +int sms_queue_set_max_pending(struct gsm_sms_queue *, int max); +int sms_queue_set_max_failure(struct gsm_sms_queue *, int fail); +int sms_queue_clear(struct gsm_sms_queue *); + +#endif diff --git a/include/osmocom/bsc/socket.h b/include/osmocom/bsc/socket.h new file mode 100644 index 000000000..0fd85f104 --- /dev/null +++ b/include/osmocom/bsc/socket.h @@ -0,0 +1,14 @@ +#ifndef _BSC_SOCKET_H +#define _BSC_SOCKET_H + +#include + +#ifndef IPPROTO_GRE +#define IPPROTO_GRE 47 +#endif + +int make_sock(struct osmo_fd *bfd, int proto, + uint32_t ip, uint16_t port, int priv_nr, + int (*cb)(struct osmo_fd *fd, unsigned int what), void *data); + +#endif /* _BSC_SOCKET_H */ diff --git a/include/osmocom/bsc/system_information.h b/include/osmocom/bsc/system_information.h new file mode 100644 index 000000000..29f639dca --- /dev/null +++ b/include/osmocom/bsc/system_information.h @@ -0,0 +1,22 @@ +#ifndef _SYSTEM_INFO_H +#define _SYSTEM_INFO_H + +#include + +#include + +struct gsm_bts; + +int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type); +size_t si2q_earfcn_count(const struct osmo_earfcn_si2q *e); +unsigned range1024_p(unsigned n); +unsigned range512_q(unsigned m); +int range_encode(enum gsm48_range r, int *arfcns, int arfcns_used, int *w, + int f0, uint8_t *chan_list); +uint8_t si2q_num(struct gsm_bts *bts); +int bts_earfcn_add(struct gsm_bts *bts, uint16_t earfcn, uint8_t thresh_hi, uint8_t thresh_lo, uint8_t prio, + uint8_t qrx, uint8_t meas_bw); +int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble); +int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble, + bool diversity); +#endif diff --git a/include/osmocom/bsc/transaction.h b/include/osmocom/bsc/transaction.h new file mode 100644 index 000000000..5465548ea --- /dev/null +++ b/include/osmocom/bsc/transaction.h @@ -0,0 +1,102 @@ +#ifndef _TRANSACT_H +#define _TRANSACT_H + +#include +#include +#include +#include +#include +#include + +enum bridge_state { + BRIDGE_STATE_NONE, + BRIDGE_STATE_LOOPBACK_PENDING, + BRIDGE_STATE_LOOPBACK_ESTABLISHED, + BRIDGE_STATE_BRIDGE_PENDING, + BRIDGE_STATE_BRIDGE_ESTABLISHED, +}; + +/* One transaction */ +struct gsm_trans { + /* Entry in list of all transactions */ + struct llist_head entry; + + /* Back pointer to the network struct */ + struct gsm_network *net; + + /* The protocol within which we live */ + uint8_t protocol; + + /* The current transaction ID */ + uint8_t transaction_id; + + /* To whom we belong, unique identifier of remote MM entity */ + struct vlr_subscr *vsub; + + /* The associated connection we are using to transmit messages */ + struct gsm_subscriber_connection *conn; + + /* reference from MNCC or other application */ + uint32_t callref; + + /* if traffic channel receive was requested */ + int tch_recv; + + /* is thats one paging? */ + struct subscr_request *paging_request; + + /* bearer capabilities (rate and codec) */ + struct gsm_mncc_bearer_cap bearer_cap; + + /* status of the assignment, true when done */ + bool assignment_done; + + /* if true, TCH_RTP_CREATE is sent after the + * assignment is done */ + bool tch_rtp_create; + + union { + struct { + + /* current call state */ + int state; + + /* current timer and message queue */ + int Tcurrent; /* current CC timer */ + int T308_second; /* used to send release again */ + struct osmo_timer_list timer; + struct gsm_mncc msg; /* stores setup/disconnect/release message */ + } cc; + struct { + struct gsm411_smc_inst smc_inst; + struct gsm411_smr_inst smr_inst; + + struct gsm_sms *sms; + } sms; + }; + + struct { + struct gsm_trans *peer; + enum bridge_state state; + } bridge; +}; + + + +struct gsm_trans *trans_find_by_id(struct gsm_subscriber_connection *conn, + uint8_t proto, uint8_t trans_id); +struct gsm_trans *trans_find_by_callref(struct gsm_network *net, + uint32_t callref); + +struct gsm_trans *trans_alloc(struct gsm_network *net, + struct vlr_subscr *vsub, + uint8_t protocol, uint8_t trans_id, + uint32_t callref); +void trans_free(struct gsm_trans *trans); + +int trans_assign_trans_id(struct gsm_network *net, struct vlr_subscr *vsub, + uint8_t protocol, uint8_t ti_flag); +struct gsm_trans *trans_has_conn(const struct gsm_subscriber_connection *conn); +void trans_conn_closed(struct gsm_subscriber_connection *conn); + +#endif diff --git a/include/osmocom/bsc/trau_mux.h b/include/osmocom/bsc/trau_mux.h new file mode 100644 index 000000000..eeceff5cc --- /dev/null +++ b/include/osmocom/bsc/trau_mux.h @@ -0,0 +1,70 @@ +/* Simple TRAU frame reflector to route voice calls */ + +/* (C) 2009 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/* The "TRAU mux map" defines which particular 16kbit sub-slot (in which E1 + * timeslot on which E1 interface) should be directly muxed to which other + * sub-slot. Entries in the mux map are always bi-directional. + * + * The idea of all this is to directly switch voice channels in the BSC + * from one phone to another. We do this right now since we don't support + * any external interface for voice channels, and in the future as an + * optimization to routing them externally. + */ + +#include +#include +#include + +struct decoded_trau_frame; + +/* map a TRAU mux map entry */ +int trau_mux_map(const struct gsm_e1_subslot *src, + const struct gsm_e1_subslot *dst); +int trau_mux_map_lchan(const struct gsm_lchan *src, + const struct gsm_lchan *dst); + +/* unmap a TRAU mux map entry */ +int trau_mux_unmap(const struct gsm_e1_subslot *ss, uint32_t callref); + +/* we get called by subchan_demux */ +int trau_mux_input(struct gsm_e1_subslot *src_e1_ss, + const uint8_t *trau_bits, int num_bits); + +/* add a trau receiver */ +int trau_recv_lchan(struct gsm_lchan *lchan, uint32_t callref); + +/* send trau from application */ +int trau_send_frame(struct gsm_lchan *lchan, struct gsm_data_frame *frame); + +/* switch trau muxer to new lchan */ +int switch_trau_mux(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan); + +/* callback invoked if we receive TRAU frames */ +int subch_cb(struct subch_demux *dmx, int ch, uint8_t *data, int len, void *_priv); + +/* TRAU frame transcoding */ +struct msgb *trau_decode_fr(uint32_t callref, + const struct decoded_trau_frame *tf); +struct msgb *trau_decode_efr(uint32_t callref, + const struct decoded_trau_frame *tf); +void trau_encode_fr(struct decoded_trau_frame *tf, + const unsigned char *data); +void trau_encode_efr(struct decoded_trau_frame *tf, + const unsigned char *data); diff --git a/include/osmocom/bsc/trau_upqueue.h b/include/osmocom/bsc/trau_upqueue.h new file mode 100644 index 000000000..ecc765843 --- /dev/null +++ b/include/osmocom/bsc/trau_upqueue.h @@ -0,0 +1,7 @@ +#ifndef _TRAU_UPQUEUE_H +#define _TRAU_UPQUEUE_H + +void trau_tx_to_mncc(struct gsm_network *net, struct msgb *msg); + +#endif /* _TRAU_UPQUEUE_H */ + diff --git a/include/osmocom/bsc/ussd.h b/include/osmocom/bsc/ussd.h new file mode 100644 index 000000000..266546811 --- /dev/null +++ b/include/osmocom/bsc/ussd.h @@ -0,0 +1,10 @@ +#ifndef _USSD_H +#define _USSD_H + +/* Handler function for mobile-originated USSD messages */ + +#include + +int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg); + +#endif diff --git a/include/osmocom/bsc/vty.h b/include/osmocom/bsc/vty.h new file mode 100644 index 000000000..f7056016c --- /dev/null +++ b/include/osmocom/bsc/vty.h @@ -0,0 +1,54 @@ +#ifndef OPENBSC_VTY_H +#define OPENBSC_VTY_H + +#include +#include +#include + +struct gsm_network; +struct vty; + +void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *); + +struct buffer *vty_argv_to_buffer(int argc, const char *argv[], int base); + +extern struct cmd_element cfg_description_cmd; +extern struct cmd_element cfg_no_description_cmd; + +enum bsc_vty_node { + GSMNET_NODE = _LAST_OSMOVTY_NODE + 1, + BTS_NODE, + TRX_NODE, + TS_NODE, + SUBSCR_NODE, + MGCP_NODE, + GBPROXY_NODE, + SGSN_NODE, + OML_NODE, + NAT_NODE, + NAT_BSC_NODE, + MSC_NODE, + OM2K_NODE, + OM2K_CON_GROUP_NODE, + TRUNK_NODE, + PGROUP_NODE, + MNCC_INT_NODE, + NITB_NODE, + BSC_NODE, + SMPP_NODE, + SMPP_ESME_NODE, + GTPHUB_NODE, + HLR_NODE, +}; + +extern int bsc_vty_is_config_node(struct vty *vty, int node); + +struct log_info; +int bsc_vty_init(struct gsm_network *network); +int bsc_vty_init_extra(void); + +void msc_vty_init(struct gsm_network *msc_network); + +struct gsm_network *gsmnet_from_vty(struct vty *vty); + +#endif -- cgit v1.2.3