diff options
Diffstat (limited to 'src/host/layer23/include/osmocom/bb')
46 files changed, 1593 insertions, 437 deletions
diff --git a/src/host/layer23/include/osmocom/bb/Makefile.am b/src/host/layer23/include/osmocom/bb/Makefile.am index 58a5f7fb..3b6a4d8b 100644 --- a/src/host/layer23/include/osmocom/bb/Makefile.am +++ b/src/host/layer23/include/osmocom/bb/Makefile.am @@ -1 +1 @@ -SUBDIRS = common misc mobile +SUBDIRS = common misc mobile modem diff --git a/src/host/layer23/include/osmocom/bb/common/Makefile.am b/src/host/layer23/include/osmocom/bb/common/Makefile.am index f9364cd9..7c0fa972 100644 --- a/src/host/layer23/include/osmocom/bb/common/Makefile.am +++ b/src/host/layer23/include/osmocom/bb/common/Makefile.am @@ -1,3 +1,22 @@ -noinst_HEADERS = l1ctl.h l1l2_interface.h l23_app.h logging.h \ - networks.h gps.h sysinfo.h osmocom_data.h utils.h \ - sap_proto.h sap_fsm.h sap_interface.h sim.h +noinst_HEADERS = \ + apn.h \ + apn_fsm.h \ + l1ctl.h \ + l1l2_interface.h \ + l23_app.h \ + logging.h \ + ms.h \ + networks.h \ + gps.h \ + sysinfo.h \ + osmocom_data.h \ + utils.h \ + sap_proto.h \ + sap_fsm.h \ + sap_interface.h \ + settings.h \ + sim.h \ + subscriber.h \ + support.h \ + vty.h \ + $(NULL) diff --git a/src/host/layer23/include/osmocom/bb/common/apn.h b/src/host/layer23/include/osmocom/bb/common/apn.h new file mode 100644 index 00000000..0adb8de7 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/common/apn.h @@ -0,0 +1,82 @@ +/* APN Context + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#pragma once + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/select.h> +#include <osmocom/core/tun.h> + +#include <osmocom/gprs/sm/sm.h> + +#include <osmocom/bb/common/apn_fsm.h> + +struct osmocom_ms; + +#define APN_TYPE_IPv4 0x01 /* v4-only */ +#define APN_TYPE_IPv6 0x02 /* v6-only */ +#define APN_TYPE_IPv4v6 0x04 /* v4v6 dual-stack */ + +struct osmobb_pdp_ctx { + uint8_t nsapi; + uint8_t llc_sapi; + uint8_t qos[OSMO_GPRS_SM_QOS_MAXLEN]; + uint8_t qos_len; + uint8_t pco[OSMO_GPRS_SM_PCO_MAXLEN]; + uint8_t pco_len; + enum osmo_gprs_sm_pdp_addr_ietf_type pdp_addr_ietf_type; + struct osmo_sockaddr pdp_addr_v4; + struct osmo_sockaddr pdp_addr_v6; +}; + +struct osmobb_apn { + /* list of APNs inside MS */ + struct llist_head list; + /* back-pointer to MS */ + struct osmocom_ms *ms; + + bool started; + + struct { + /* Primary name */ + char *name; + /* name of the network device */ + char *dev_name; + /* netns name of the network device, NULL = default netns */ + char *dev_netns_name; + /* types supported address types on this APN */ + uint32_t apn_type_mask; + /* administratively shutdown (true) or not (false) */ + bool shutdown; + /* transmit G-PDU sequence numbers (true) or not (false) */ + bool tx_gpdu_seq; + } cfg; + struct osmo_tundev *tun; + struct apn_fsm_ctx fsm; + struct osmobb_pdp_ctx pdp; +}; + +struct osmobb_apn *apn_alloc(struct osmocom_ms *ms, const char *name); +void apn_free(struct osmobb_apn *apn); +int apn_start(struct osmobb_apn *apn); +int apn_stop(struct osmobb_apn *apn); + +#define LOGPAPN(level, apn, fmt, args...) \ + LOGP(DTUN, level, "APN(%s): " fmt, (apn)->cfg.name, ## args) + +#define LOGTUN(level, tun, fmt, args...) \ + LOGP(DTUN, level, "TUN(%s): " fmt, osmo_tundev_get_name(tun), ## args) diff --git a/src/host/layer23/include/osmocom/bb/common/apn_fsm.h b/src/host/layer23/include/osmocom/bb/common/apn_fsm.h new file mode 100644 index 00000000..890267c9 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/common/apn_fsm.h @@ -0,0 +1,29 @@ +#pragma once + +#include <osmocom/core/fsm.h> + +struct osmobb_apn; + +enum apn_fsm_states { + APN_ST_DISABLED, + APN_ST_INACTIVE, + APN_ST_ACTIVATING, + APN_ST_ACTIVE, +}; + +enum apn_fsm_events { + APN_EV_GPRS_ALLOWED, /* data: bool *allowed */ + APN_EV_GMM_ATTACHED, + APN_EV_GMM_DETACHED, + APN_EV_RX_SM_ACT_PDP_CTX_REJ, /* data: enum gsm48_gsm_cause *cause */ + APN_EV_RX_SM_ACT_PDP_CTX_ACC, + APN_EV_RX_SM_DEACT_PDP_CTX_ACC, +}; + +struct apn_fsm_ctx { + struct osmo_fsm_inst *fi; + struct osmobb_apn *apn; +}; + +int apn_fsm_ctx_init(struct apn_fsm_ctx *ctx, struct osmobb_apn *apn); +void apn_fsm_ctx_release(struct apn_fsm_ctx *ctx); diff --git a/src/host/layer23/include/osmocom/bb/common/gps.h b/src/host/layer23/include/osmocom/bb/common/gps.h index 58c0c536..e7ce915c 100644 --- a/src/host/layer23/include/osmocom/bb/common/gps.h +++ b/src/host/layer23/include/osmocom/bb/common/gps.h @@ -13,10 +13,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ enum { diff --git a/src/host/layer23/include/osmocom/bb/common/l1ctl.h b/src/host/layer23/include/osmocom/bb/common/l1ctl.h index e4dbdedc..a74c9c37 100644 --- a/src/host/layer23/include/osmocom/bb/common/l1ctl.h +++ b/src/host/layer23/include/osmocom/bb/common/l1ctl.h @@ -2,6 +2,7 @@ #define osmocom_l1ctl_h #include <osmocom/core/msgb.h> +#include <osmocom/core/prim.h> #include <osmocom/bb/common/osmocom_data.h> struct osmocom_ms; @@ -20,15 +21,15 @@ int l1ctl_tx_crypto_req(struct osmocom_ms *ms, uint8_t chan_nr, uint8_t algo, uint8_t *key, uint8_t len); /* Transmit L1CTL_RACH_REQ */ -int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint16_t offset, - uint8_t combined); +int l1ctl_tx_rach_req(struct osmocom_ms *ms, + uint8_t chan_nr, uint8_t link_id, + uint8_t ra, uint16_t offset, uint8_t combined, uint8_t uic); /* Transmit L1CTL_DM_EST_REQ */ -int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, - uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, uint8_t audio_mode); -int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, - uint16_t *ma, uint8_t ma_len, uint8_t chan_nr, uint8_t tsc, - uint8_t tch_mode, uint8_t audio_mode); +int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr, uint8_t tsc, + uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags); +int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn, uint16_t *ma, uint8_t ma_len, + uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags); /* Transmit L1CTL_DM_FREQ_REQ */ int l1ctl_tx_dm_freq_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn, @@ -48,8 +49,8 @@ int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn, int l1ctl_tx_ccch_mode_req(struct osmocom_ms *ms, uint8_t ccch_mode); /* Transmit TCH_MODE_REQ */ -int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode, - uint8_t audio_mode); +int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode, uint8_t audio_mode, uint8_t tch_flags, + uint8_t tch_loop_mode); /* Transmit ECHO_REQ */ int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len); @@ -73,4 +74,17 @@ int l1ctl_ph_prim_cb(struct osmo_prim_hdr *oph, void *ctx); /* Transmit L1CTL_NEIGH_PM_REQ */ int l1ctl_tx_neigh_pm_req(struct osmocom_ms *ms, int num, uint16_t *arfcn); +/* Transmit L1CTL_GPRS_UL_BLOCK_REQ */ +int l1ctl_tx_gprs_ul_block_req(struct osmocom_ms *ms, uint32_t fn, uint8_t tn, + const uint8_t *data, size_t data_len); + +/* Transmit L1CTL_GPRS_UL_TBF_CFG_REQ */ +int l1ctl_tx_gprs_ul_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref, + uint8_t slotmask, uint32_t start_fn); + +/* Transmit L1CTL_GPRS_DL_TBF_CFG_REQ */ +int l1ctl_tx_gprs_dl_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref, + uint8_t slotmask, uint32_t start_fn, + uint8_t dl_tfi); + #endif diff --git a/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h b/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h index 41403d87..9cb993c8 100644 --- a/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h +++ b/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h @@ -1,6 +1,10 @@ #ifndef _L1L2_INTERFACE_H #define _L1L2_INTERFACE_H +#include <osmocom/core/msgb.h> + +#define L2_DEFAULT_SOCKET_PATH "/tmp/osmocom_l2" + int layer2_open(struct osmocom_ms *ms, const char *socket_path); int layer2_close(struct osmocom_ms *ms); int osmo_send_l1(struct osmocom_ms *ms, struct msgb *msg); diff --git a/src/host/layer23/include/osmocom/bb/common/l23_app.h b/src/host/layer23/include/osmocom/bb/common/l23_app.h index 0b9994c3..6cf0b7e9 100644 --- a/src/host/layer23/include/osmocom/bb/common/l23_app.h +++ b/src/host/layer23/include/osmocom/bb/common/l23_app.h @@ -1,36 +1,77 @@ #ifndef _L23_APP_H #define _L23_APP_H +#include <osmocom/core/tun.h> +#include <osmocom/core/gsmtap.h> + struct option; +struct vty_app_info; /* Options supported by the l23 app */ enum { - L23_OPT_SAP = 1, - L23_OPT_ARFCN = 2, - L23_OPT_TAP = 4, - L23_OPT_VTY = 8, - L23_OPT_DBG = 16, - L23_OPT_VTYIP = 32, + L23_OPT_SAP = 1 << 0, + L23_OPT_ARFCN = 1 << 1, + L23_OPT_TAP = 1 << 2, + L23_OPT_VTY = 1 << 3, + L23_OPT_DBG = 1 << 4, }; -/* initialization, called once when starting the app, before entering - * select loop */ -extern int l23_app_init(struct osmocom_ms *ms); -extern int (*l23_app_work) (struct osmocom_ms *ms); -extern int (*l23_app_exit) (struct osmocom_ms *ms); +/* see (struct l23_global_config)->gsmtap.categ_gprs_mask */ +enum l23_gsmtap_gprs_category { + L23_GSMTAP_GPRS_C_DL_UNKNOWN = 0, /* unknown or undecodable downlink blocks */ + L23_GSMTAP_GPRS_C_DL_DUMMY = 1, /* downlink dummy blocks */ + L23_GSMTAP_GPRS_C_DL_CTRL = 2, /* downlink control blocks */ + L23_GSMTAP_GPRS_C_DL_DATA_GPRS = 3, /* downlink GPRS data blocks */ + L23_GSMTAP_GPRS_C_DL_DATA_EGPRS = 4, /* downlink EGPRS data blocks */ + + L23_GSMTAP_GPRS_C_UL_UNKNOWN = 5, /* unknown or undecodable uplink blocks */ + L23_GSMTAP_GPRS_C_UL_DUMMY = 6, /* uplink dummy blocks */ + L23_GSMTAP_GPRS_C_UL_CTRL = 7, /* uplink control blocks */ + L23_GSMTAP_GPRS_C_UL_DATA_GPRS = 8, /* uplink GPRS data blocks */ + L23_GSMTAP_GPRS_C_UL_DATA_EGPRS = 9, /* uplink EGPRS data blocks */ +}; + +struct l23_global_config { + struct { + char *remote_host; + char *local_host; + uint32_t lchan_mask; /* see l23_gsmtap_gprs_category */ + uint32_t lchan_acch_mask; /* see l23_gsmtap_gprs_category */ + bool lchan_acch; + uint32_t categ_gprs_mask; + struct gsmtap_inst *inst; + } gsmtap; +}; +extern struct l23_global_config l23_cfg; + +extern void *l23_ctx; + +/* initialization, called once when starting the app, before reading VTY config */ +extern int l23_app_init(void); + +/* Start work after reading VTY config and starting layer23 components, + * immediately before entering main select loop */ +extern int (*l23_app_start)(void); + +extern int (*l23_app_work)(void); +extern int (*l23_app_exit)(void); /* configuration options */ struct l23_app_info { const char *copyright; const char *contribution; + struct vty_app_info *vty_info; /* L23_OPT_VTY */ char *getopt_string; - int (*cfg_supported)(); + uint32_t opt_supported; /* mask of L23_OPT_* */ int (*cfg_print_help)(); int (*cfg_getopt_opt)(struct option **options); int (*cfg_handle_opt)(int c,const char *optarg); + int (*vty_init)(void); + osmo_tundev_data_ind_cb_t tun_data_ind_cb; }; -extern struct l23_app_info *l23_app_info(); +/* all l23 apps must define this structure */ +extern const struct l23_app_info l23_app_info; #endif /* _L23_APP_H */ diff --git a/src/host/layer23/include/osmocom/bb/common/logging.h b/src/host/layer23/include/osmocom/bb/common/logging.h index bf6e6aa0..3920d2e0 100644 --- a/src/host/layer23/include/osmocom/bb/common/logging.h +++ b/src/host/layer23/include/osmocom/bb/common/logging.h @@ -12,6 +12,8 @@ enum { DNB, DMM, DCC, + DGCC, + DBCC, DSS, DSMS, DMNCC, @@ -25,6 +27,14 @@ enum { DMOB, DPRIM, DLUA, + DGAPK, + DCSD, + DTUN, + DRLCMAC, + DLLC, + DSNDCP, + DGMM, + DSM }; extern const struct log_info log_info; diff --git a/src/host/layer23/include/osmocom/bb/common/ms.h b/src/host/layer23/include/osmocom/bb/common/ms.h new file mode 100644 index 00000000..36d3e3ba --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/common/ms.h @@ -0,0 +1,116 @@ +/* Mobile Station */ +#pragma once + +#include <osmocom/core/select.h> +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/core/write_queue.h> + +#include <osmocom/gsm/lapdm.h> +#include <osmocom/bb/common/settings.h> +#include <osmocom/bb/common/subscriber.h> +#include <osmocom/bb/common/support.h> +#include <osmocom/bb/common/sap_interface.h> +#include <osmocom/bb/common/sap_proto.h> +#include <osmocom/bb/mobile/gsm48_rr.h> +#include <osmocom/bb/common/sysinfo.h> +#include <osmocom/bb/mobile/gsm322.h> +#include <osmocom/bb/mobile/gsm48_mm.h> +#include <osmocom/bb/mobile/gsm48_cc.h> +#include <osmocom/bb/mobile/mncc_sock.h> +#include <osmocom/bb/common/sim.h> +#include <osmocom/bb/common/l1ctl.h> + +struct osmobb_ms_gmm_layer { + uint8_t ac_ref_nr; + uint8_t key_seq; + uint8_t rand[16]; + uint32_t tlli; +}; + +struct osmosap_entity { + struct osmo_fsm_inst *fi; + uint16_t max_msg_size; + + /* Current state of remote SIM card */ + enum sap_card_status_type card_status; + + /* Optional SAP message call-back */ + sap_msg_cb_t sap_msg_cb; + /* Optional response call-back */ + sap_rsp_cb_t sap_rsp_cb; +}; + +struct osmol1_entity { + int (*l1_traffic_ind)(struct osmocom_ms *ms, struct msgb *msg); + int (*l1_gprs_ul_block_cnf)(struct osmocom_ms *ms, struct msgb *msg); + int (*l1_gprs_dl_block_ind)(struct osmocom_ms *ms, struct msgb *msg); + int (*l1_gprs_rts_ind)(struct osmocom_ms *ms, struct msgb *msg); +}; + +struct osmomncc_entity { + int (*mncc_recv)(struct osmocom_ms *ms, int msg_type, void *arg); + struct mncc_sock_state *sock_state; + uint32_t ref; +}; + +/* RX measurement statistics */ +struct rx_meas_stat { + uint32_t last_fn; + + /* cumulated values of current cell from SACCH dl */ + uint32_t frames; + uint32_t snr; + uint32_t berr; + uint32_t rxlev; + + /* counters loss criterion */ + int16_t dsc, ds_fail; + int16_t s, rl_fail; +}; + +enum osmobb_ms_shutdown_st { + MS_SHUTDOWN_NONE = 0, + MS_SHUTDOWN_IMSI_DETACH = 1, + MS_SHUTDOWN_WAIT_RESET = 2, + MS_SHUTDOWN_COMPL = 3, +}; + +struct osmocom_ms { + struct llist_head entity; + char *name; + struct osmo_wqueue l2_wq, sap_wq; + uint16_t test_arfcn; + struct osmol1_entity l1_entity; + + bool started, deleting; + enum osmobb_ms_shutdown_st shutdown; + struct gsm_support support; + struct gsm_settings settings; + struct gsm_subscriber subscr; + struct gsm_sim sim; + struct lapdm_channel lapdm_channel; + struct osmosap_entity sap_entity; + struct rx_meas_stat meas; + struct gsm48_rrlayer rrlayer; + struct gsm322_plmn plmn; + struct gsm322_cellsel cellsel; + struct gsm48_mmlayer mmlayer; + struct gsm48_cclayer cclayer; + struct osmomncc_entity mncc_entity; + struct llist_head trans_list; + + /* GPRS */ + struct gprs_settings gprs; + struct osmobb_ms_gmm_layer gmmlayer; + struct osmo_fsm_inst *grr_fi; + + struct tch_state *tch_state; + + void *lua_state; + int lua_cb_ref; + char *lua_script; +}; + +struct osmocom_ms *osmocom_ms_alloc(void *ctx, const char *name); + +extern uint16_t cfg_test_arfcn; diff --git a/src/host/layer23/include/osmocom/bb/common/networks.h b/src/host/layer23/include/osmocom/bb/common/networks.h index d34f3162..408e17d0 100644 --- a/src/host/layer23/include/osmocom/bb/common/networks.h +++ b/src/host/layer23/include/osmocom/bb/common/networks.h @@ -1,24 +1,27 @@ #ifndef _NETWORKS_H #define _NETWORKS_H +#include <osmocom/gsm/gsm23003.h> -#define GSM_INPUT_INVALID 0xffff - +/* Instead of handling numerical MCC and MNC, they stored and handled + * hexadecimal. This makes it possible + * to correctly handle 2 and 3 digits MNC. Internally 2 digit MNCs are stored + * as 0xXXf, and 3 digits MNC are stored as 0xXXX, where X is the digit 0..9. +*/ struct gsm_networks { - uint16_t mcc; - int16_t mnc; + uint16_t mcc_hex; + int16_t mnc_hex; const char *name; }; int gsm_match_mcc(uint16_t mcc, char *imsi); -int gsm_match_mnc(uint16_t mcc, uint16_t mnc, char *imsi); -const char *gsm_print_mcc(uint16_t mcc); -const char *gsm_print_mnc(uint16_t mcc); +int gsm_match_mnc(uint16_t mcc, uint16_t mnc, bool mnc_3_digits, char *imsi); const char *gsm_get_mcc(uint16_t mcc); -const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc); +const char *gsm_get_mnc(const struct osmo_plmn_id *plmn); const char *gsm_imsi_mcc(char *imsi); const char *gsm_imsi_mnc(char *imsi); -const uint16_t gsm_input_mcc(char *string); -const uint16_t gsm_input_mnc(char *string); + +uint16_t gsm_mcc_to_hex(uint16_t mcc); +uint16_t gsm_mnc_to_hex(uint16_t mnc, bool mnc_3_digits); #endif /* _NETWORKS_H */ diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h index 14e594cb..935c02b2 100644 --- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h +++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h @@ -1,107 +1,17 @@ -#ifndef osmocom_data_h -#define osmocom_data_h +#pragma once -#include <osmocom/core/select.h> -#include <osmocom/gsm/gsm_utils.h> -#include <osmocom/core/write_queue.h> +#include <stdint.h> +#include <stdbool.h> struct osmocom_ms; - - /* FIXME no 'mobile' specific stuff should be here */ -#include <osmocom/bb/mobile/support.h> -#include <osmocom/bb/mobile/settings.h> -#include <osmocom/bb/mobile/subscriber.h> -#include <osmocom/gsm/lapdm.h> -#include <osmocom/bb/common/sap_interface.h> -#include <osmocom/bb/common/sap_proto.h> -#include <osmocom/bb/mobile/gsm48_rr.h> -#include <osmocom/bb/common/sysinfo.h> -#include <osmocom/bb/mobile/gsm322.h> -#include <osmocom/bb/mobile/gsm48_mm.h> -#include <osmocom/bb/mobile/gsm48_cc.h> -#include <osmocom/bb/mobile/mncc_sock.h> -#include <osmocom/bb/common/sim.h> -#include <osmocom/bb/common/l1ctl.h> - -struct osmosap_entity { - struct osmo_fsm_inst *fi; - uint16_t max_msg_size; - - /* Current state of remote SIM card */ - enum sap_card_status_type card_status; - - /* Optional SAP message call-back */ - sap_msg_cb_t sap_msg_cb; - /* Optional response call-back */ - sap_rsp_cb_t sap_rsp_cb; -}; - -struct osmol1_entity { - int (*l1_traffic_ind)(struct osmocom_ms *ms, struct msgb *msg); -}; - -struct osmomncc_entity { - int (*mncc_recv)(struct osmocom_ms *ms, int msg_type, void *arg); - struct mncc_sock_state *sock_state; - uint32_t ref; -}; - - -/* RX measurement statistics */ -struct rx_meas_stat { - uint32_t last_fn; - - /* cumulated values of current cell from SACCH dl */ - uint32_t frames; - uint32_t snr; - uint32_t berr; - uint32_t rxlev; - - /* counters loss criterion */ - int16_t dsc, ds_fail; - int16_t s, rl_fail; -}; - -enum { - MS_SHUTDOWN_NONE = 0, - MS_SHUTDOWN_IMSI_DETACH = 1, - MS_SHUTDOWN_WAIT_RESET = 2, - MS_SHUTDOWN_COMPL = 3, -}; - -/* One Mobilestation for osmocom */ -struct osmocom_ms { - struct llist_head entity; - char *name; - struct osmo_wqueue l2_wq, sap_wq; - uint16_t test_arfcn; - struct osmol1_entity l1_entity; - - bool started, deleting; - uint8_t shutdown; - struct gsm_support support; - struct gsm_settings settings; - struct gsm_subscriber subscr; - struct gsm_sim sim; - struct lapdm_channel lapdm_channel; - struct osmosap_entity sap_entity; - struct rx_meas_stat meas; - struct gsm48_rrlayer rrlayer; - struct gsm322_plmn plmn; - struct gsm322_cellsel cellsel; - struct gsm48_mmlayer mmlayer; - struct gsm48_cclayer cclayer; - struct osmomncc_entity mncc_entity; - struct llist_head trans_list; - - void *lua_state; - int lua_cb_ref; - char *lua_script; -}; +struct vty; enum osmobb_sig_subsys { SS_L1CTL, SS_GLOBAL, + SS_L23_VTY, + SS_L23_SUBSCR, + SS_L23_TRANS, }; enum osmobb_l1ctl_sig { @@ -120,6 +30,43 @@ enum osmobb_global_sig { S_GLOBAL_SHUTDOWN, }; +enum osmobb_l23_vty_sig { + S_L23_VTY_MS_START, + S_L23_VTY_MS_STOP, +}; + +enum osmobb_l23_subscriber { + S_L23_SUBSCR_SIM_ATTACHED, + S_L23_SUBSCR_SIM_DETACHED, + S_L23_SUBSCR_SIM_AUTH_RESP, +}; + +enum osmobb_l23_trans_sig { + S_L23_CC_TRANS_ALLOC, /* new transaction has been allocated */ + S_L23_CC_TRANS_FREE, /* transaction is about to be free()d */ + S_L23_CC_TRANS_STATE_CHG, /* transaction state has been changed */ +}; + +struct osmobb_l23_vty_sig_data { + struct vty *vty; + union { + struct { + struct osmocom_ms *ms; + int rc; /* CMD_SUCCESS/CMD_WARNING */ + } ms_start; + struct { + struct osmocom_ms *ms; + bool force; + int rc; /* CMD_SUCCESS/CMD_WARNING */ + } ms_stop; + }; +}; + +struct osmobb_l23_subscr_sim_auth_resp_sig_data { + struct osmocom_ms *ms; + uint8_t sres[4]; +}; + struct osmobb_fbsb_res { struct osmocom_ms *ms; int8_t snr; @@ -142,6 +89,7 @@ struct osmobb_tch_mode_conf { struct osmocom_ms *ms; uint8_t tch_mode; uint8_t audio_mode; + uint8_t tch_flags; }; struct osmobb_neigh_pm_ind { @@ -149,5 +97,3 @@ struct osmobb_neigh_pm_ind { uint16_t band_arfcn; uint8_t rx_lev; }; - -#endif diff --git a/src/host/layer23/include/osmocom/bb/common/settings.h b/src/host/layer23/include/osmocom/bb/common/settings.h new file mode 100644 index 00000000..1d3e53df --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/common/settings.h @@ -0,0 +1,348 @@ +#ifndef _settings_h +#define _settings_h + +#include <stdbool.h> + +#include <osmocom/core/utils.h> +#include <osmocom/core/linuxlist.h> +#include <osmocom/gsm/protocol/gsm_23_003.h> +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/gsm/gsm23003.h> +#include <osmocom/gsm/gsm48.h> + +#include <osmocom/bb/common/sim.h> + +struct osmocom_ms; +struct osmobb_apn; + +#define MOB_C7_DEFLT_ANY_TIMEOUT 30 + +/* CC (Call Control) message handling entity */ +enum mncc_handler_t { + /* Built-in mobile's MNCC */ + MNCC_HANDLER_INTERNAL, + /* External MNCC application via UNIX-socket */ + MNCC_HANDLER_EXTERNAL, + /* No call support */ + MNCC_HANDLER_DUMMY, +}; + +/* TCH I/O handler for voice calls */ +enum tch_voice_io_handler { + /* No handler, drop frames */ + TCH_VOICE_IOH_NONE = 0, + /* libosmo-gapk based handler */ + TCH_VOICE_IOH_GAPK, + /* L1 PHY (e.g. Calypso DSP) */ + TCH_VOICE_IOH_L1PHY, + /* External MNCC app (via MNCC socket) */ + TCH_VOICE_IOH_MNCC_SOCK, + /* Return to sender */ + TCH_VOICE_IOH_LOOPBACK, +}; + +extern const struct value_string tch_voice_io_handler_names[]; +static inline const char *tch_voice_io_handler_name(enum tch_voice_io_handler val) +{ return get_value_string(tch_voice_io_handler_names, val); } + +/* TCH I/O handler for data calls */ +enum tch_data_io_handler { + /* No handler, drop frames */ + TCH_DATA_IOH_NONE = 0, + /* UNIX socket */ + TCH_DATA_IOH_UNIX_SOCK, + /* Return to sender */ + TCH_DATA_IOH_LOOPBACK, +}; + +extern const struct value_string tch_data_io_handler_names[]; +static inline const char *tch_data_io_handler_name(enum tch_data_io_handler val) +{ return get_value_string(tch_data_io_handler_names, val); } + +/* TCH I/O format for voice calls */ +enum tch_voice_io_format { + /* RFC3551 for FR/EFR, RFC5993 for HR, RFC4867 for AMR */ + TCH_VOICE_IOF_RTP, + /* Texas Instruments format, used by Calypso based phones (e.g. Motorola C1xx) */ + TCH_VOICE_IOF_TI, +}; + +extern const struct value_string tch_voice_io_format_names[]; +static inline const char *tch_voice_io_format_name(enum tch_voice_io_format val) +{ return get_value_string(tch_voice_io_format_names, val); } + +/* TCH I/O format for data calls */ +enum tch_data_io_format { + /* Osmocom format, used by trxcon and virtphy */ + TCH_DATA_IOF_OSMO, + /* Texas Instruments format, used by Calypso based phones (e.g. Motorola C1xx) */ + TCH_DATA_IOF_TI, +}; + +extern const struct value_string tch_data_io_format_names[]; +static inline const char *tch_data_io_format_name(enum tch_data_io_format val) +{ return get_value_string(tch_data_io_format_names, val); } + +struct tch_voice_settings { + enum tch_voice_io_handler io_handler; + enum tch_voice_io_format io_format; + char alsa_output_dev[128]; + char alsa_input_dev[128]; +}; + +struct tch_data_settings { + enum tch_data_io_handler io_handler; + enum tch_data_io_format io_format; + char unix_socket_path[128]; +}; + +struct test_sim_settings { + char imsi[OSMO_IMSI_BUF_SIZE]; + uint32_t tmsi; + uint8_t ki_type; + uint8_t ki[16]; /* 128 bit max */ + bool barr; + bool rplmn_valid; + struct osmo_plmn_id rplmn; + uint16_t lac; + bool imsi_attached; + bool always_search_hplmn; + struct { + bool valid; + uint32_t ptmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ + uint32_t ptmsi_sig; /* P-TMSI signature, 3 bytes */ + struct gprs_ra_id rai; + enum gsm1111_ef_locigprs_rau_status gu_state; /* GU, TS 24.008 */ + bool imsi_attached; + } locigprs; +}; + +/* Data (CSD) call type and rate, values like in the '<speed>' part of 'AT+CBST'. + * See 3GPP TS 27.007, section 6.7 "Select bearer service type +CBST". */ +enum data_call_type_rate { + DATA_CALL_TR_AUTO = 0, + DATA_CALL_TR_V21_300 = 1, + DATA_CALL_TR_V22_1200 = 2, + DATA_CALL_TR_V23_1200_75 = 3, + DATA_CALL_TR_V22bis_2400 = 4, + DATA_CALL_TR_V26ter_2400 = 5, + DATA_CALL_TR_V32_4800 = 6, + DATA_CALL_TR_V32_9600 = 7, + DATA_CALL_TR_V34_9600 = 12, + DATA_CALL_TR_V34_14400 = 14, + DATA_CALL_TR_V34_19200 = 15, + DATA_CALL_TR_V34_28800 = 16, + DATA_CALL_TR_V34_33600 = 17, + DATA_CALL_TR_V120_1200 = 34, + DATA_CALL_TR_V120_2400 = 36, + DATA_CALL_TR_V120_4800 = 38, + DATA_CALL_TR_V120_9600 = 39, + DATA_CALL_TR_V120_14400 = 43, + DATA_CALL_TR_V120_19200 = 47, + DATA_CALL_TR_V120_28800 = 48, + DATA_CALL_TR_V120_38400 = 49, + DATA_CALL_TR_V120_48000 = 50, + DATA_CALL_TR_V120_56000 = 51, + DATA_CALL_TR_V110_300 = 65, + DATA_CALL_TR_V110_1200 = 66, + DATA_CALL_TR_V110_2400 = 68, + DATA_CALL_TR_V110_4800 = 70, + DATA_CALL_TR_V110_9600 = 71, + DATA_CALL_TR_V110_14400 = 75, + DATA_CALL_TR_V110_19200 = 79, + DATA_CALL_TR_V110_28800 = 80, + DATA_CALL_TR_V110_38400 = 81, + DATA_CALL_TR_V110_48000 = 82, + DATA_CALL_TR_V110_56000 = 83, + DATA_CALL_TR_V110_64000 = 84, + DATA_CALL_TR_BTR_56000 = 115, + DATA_CALL_TR_BTR_64000 = 116, + DATA_CALL_TR_PIAFS32k_32000 = 120, + DATA_CALL_TR_PIAFS64k_64000 = 121, + DATA_CALL_TR_MMEDIA_28800 = 130, + DATA_CALL_TR_MMEDIA_32000 = 131, + DATA_CALL_TR_MMEDIA_33600 = 132, + DATA_CALL_TR_MMEDIA_56000 = 133, + DATA_CALL_TR_MMEDIA_64000 = 134, +}; + +/* Data (CSD) call parameters */ +struct data_call_params { + enum data_call_type_rate type_rate; + enum gsm48_bcap_transp transp; + + /* async call parameters */ + bool is_async; + unsigned int nr_stop_bits; + unsigned int nr_data_bits; + enum gsm48_bcap_parity parity; +}; + +struct gsm_settings { + char layer2_socket_path[128]; + char sap_socket_path[128]; + char mncc_socket_path[128]; + + /* MNCC handler */ + enum mncc_handler_t mncc_handler; + + /* TCH settings */ + struct tch_voice_settings tch_voice; + struct tch_data_settings tch_data; + + /* IMEI */ + char imei[GSM23003_IMEI_NUM_DIGITS + 1]; + char imeisv[GSM23003_IMEISV_NUM_DIGITS + 1]; + char imei_random; + + /* network search */ + int plmn_mode; /* PLMN_MODE_* */ + + /* SIM */ + int sim_type; /* enum gsm_subscriber_sim_type, + * selects card on power on */ + char emergency_imsi[OSMO_IMSI_BUF_SIZE]; + + /* SMS */ + char sms_sca[22]; + bool store_sms; + + /* test card simulator settings */ + struct test_sim_settings test_sim; + + /* call related settings */ + uint8_t cw; /* set if call-waiting is allowed */ + uint8_t auto_answer; + uint8_t clip, clir; + uint8_t half, half_prefer; + + /* changing default behavior */ + uint8_t alter_tx_power; + uint8_t alter_tx_power_value; + int8_t alter_delay; + uint8_t stick; + uint16_t stick_arfcn; + uint8_t skip_max_per_band; + uint8_t no_lupd; + uint8_t no_neighbour; + + /* supported by configuration */ + uint8_t cc_dtmf; + uint8_t sms_ptp; + uint8_t a5_1; + uint8_t a5_2; + uint8_t a5_3; + uint8_t a5_4; + uint8_t a5_5; + uint8_t a5_6; + uint8_t a5_7; + uint8_t p_gsm; + uint8_t e_gsm; + uint8_t r_gsm; + uint8_t dcs; + uint8_t gsm_850; + uint8_t pcs; + uint8_t gsm_480; + uint8_t gsm_450; + uint8_t class_900; + uint8_t class_dcs; + uint8_t class_850; + uint8_t class_pcs; + uint8_t class_400; + uint8_t freq_map[128+38]; + uint8_t full_v1; + uint8_t full_v2; + uint8_t full_v3; + uint8_t half_v1; + uint8_t half_v3; + uint8_t ch_cap; /* channel capability */ + int8_t min_rxlev_dbm; /* min dBm to access */ + + /* CSD modes */ + bool csd_tch_f144; + bool csd_tch_f96; + bool csd_tch_f48; + bool csd_tch_h48; + bool csd_tch_f24; + bool csd_tch_h24; + + /* support for ASCI */ + bool vgcs; /* support of VGCS */ + bool vbs; /* support of VBS */ + + /* radio */ + uint16_t dsc_max; + uint8_t force_rekey; + + /* dialing */ + struct llist_head abbrev; + + /* EDGE / UMTS / CDMA */ + uint8_t edge_ms_sup; + uint8_t edge_psk_sup; + uint8_t edge_psk_uplink; + uint8_t class_900_edge; + uint8_t class_dcs_pcs_edge; + uint8_t umts_fdd; + uint8_t umts_tdd; + uint8_t cdma_2000; + uint8_t dtm; + uint8_t class_dtm; + uint8_t dtm_mac; + uint8_t dtm_egprs; + + /* Timeout for GSM 03.22 C7 state */ + uint8_t any_timeout; + + /* ASCI settings */ + bool uplink_release_local; + bool asci_allow_any; + + /* call parameters */ + struct { + struct data_call_params data; + } call_params; +}; + +struct gsm_settings_abbrev { + struct llist_head list; + char abbrev[4]; + char number[32]; + char name[32]; +}; + +int gsm_settings_arfcn(struct osmocom_ms *ms); +int gsm_settings_init(struct osmocom_ms *ms); +int gsm_settings_exit(struct osmocom_ms *ms); +char *gsm_check_imei(const char *imei, const char *sv); +int gsm_random_imei(struct gsm_settings *set); + +struct gprs_settings { + struct llist_head apn_list; + + /* 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; +}; + +int gprs_settings_init(struct osmocom_ms *ms); +int gprs_settings_fi(struct osmocom_ms *ms); +struct osmobb_apn *ms_find_apn_by_name(struct osmocom_ms *ms, const char *apn_name); +int ms_dispatch_all_apn(struct osmocom_ms *ms, uint32_t event, void *data); + +extern char *layer2_socket_path; + +#endif /* _settings_h */ + diff --git a/src/host/layer23/include/osmocom/bb/common/sim.h b/src/host/layer23/include/osmocom/bb/common/sim.h index 8b1f830c..8aae1fc8 100644 --- a/src/host/layer23/include/osmocom/bb/common/sim.h +++ b/src/host/layer23/include/osmocom/bb/common/sim.h @@ -13,12 +13,14 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ +#pragma once + +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/core/endian.h> + +struct osmocom_ms; /* 9.2 commands */ #define GSM1111_CLASS_GSM 0xa0 @@ -212,6 +214,7 @@ struct gsm1111_response_mfdf { } __attribute__ ((packed)); struct gsm1111_response_mfdf_gsm { +#if OSMO_IS_LITTLE_ENDIAN uint8_t file_char; uint8_t num_df; uint8_t num_ef; @@ -230,10 +233,24 @@ struct gsm1111_response_mfdf_gsm { rfu5:3, unblk2_init:1; uint8_t more_data[0]; +#elif OSMO_IS_BIG_ENDIAN +/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */ + uint8_t file_char; + uint8_t num_df; + uint8_t num_ef; + uint8_t num_codes; + uint8_t rfu1; + uint8_t chv1_init:1, rfu2:3, chv1_remain:4; + uint8_t unblk1_init:1, rfu3:3, unblk1_remain:4; + uint8_t chv2_init:1, rfu4:3, chv2_remain:4; + uint8_t unblk2_init:1, rfu5:3, unblk2_remain:4; + uint8_t more_data[0]; +#endif } __attribute__ ((packed)); /* Section 9.2.1 (response to selecting EF) */ struct gsm1111_response_ef { +#if OSMO_IS_LITTLE_ENDIAN uint16_t rfu1; uint16_t file_size; uint16_t file_id; @@ -251,6 +268,20 @@ struct gsm1111_response_ef { rfu4:5; uint8_t length; uint8_t structure; +#elif OSMO_IS_BIG_ENDIAN +/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */ + uint16_t rfu1; + uint16_t file_size; + uint16_t file_id; + uint8_t tof; + uint8_t inc_allowed; + uint8_t acc_read:4, acc_update:4; + uint8_t acc_inc:4, rfu2:4; + uint8_t acc_reha:4, acc_inval:4; + uint8_t rfu4:5, ru_inval:1, rfu3:1, not_inval:1; + uint8_t length; + uint8_t structure; +#endif } __attribute__ ((packed)); /* Section 10.3.17 */ @@ -258,9 +289,34 @@ struct gsm1111_ef_loci { uint32_t tmsi; struct gsm48_loc_area_id lai; uint8_t tmsi_time; - uint8_t lupd_status; + uint8_t lupd_status; /* enum gsm1111_ef_loci_lupd_status */ } __attribute__ ((packed)); +enum gsm1111_ef_loci_lupd_status { + GSM1111_EF_LOCI_LUPD_ST_UPDATED = 0, + GSM1111_EF_LOCI_LUPD_ST_NOT_UPDATED = 1, + GSM1111_EF_LOCI_LUPD_ST_PLMN_NOT_ALLOWED = 2, + GSM1111_EF_LOCI_LUPD_ST_LA_NOT_ALLOWED = 3, + GSM1111_EF_LOCI_LUPD_ST_RESERVED = 7, +}; + +/* Section 10.3.33 */ +struct gsm1111_ef_locigprs { + uint32_t ptmsi; + uint16_t ptmsi_sig_hi; + uint8_t ptmsi_sig_lo; + struct gsm48_ra_id rai; + uint8_t rau_status; /* enum gsm1111_ef_locigprs_rau_status */ +} __attribute__ ((packed)); + +enum gsm1111_ef_locigprs_rau_status { + GSM1111_EF_LOCIGPRS_RAU_ST_UPDATED = 0, + GSM1111_EF_LOCIGPRS_RAU_ST_NOT_UPDATED = 1, + GSM1111_EF_LOCIGPRS_RAU_ST_PLMN_NOT_ALLOWED = 2, + GSM1111_EF_LOCIGPRS_RAU_ST_RA_NOT_ALLOWED = 3, + GSM1111_EF_LOCIGPRS_RAU_ST_RESERVED = 7, +}; + /* Section 10.5.1 */ struct gsm1111_ef_adn { uint8_t len_bcd; diff --git a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h b/src/host/layer23/include/osmocom/bb/common/subscriber.h index 698b0fdc..d36b4c6c 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h +++ b/src/host/layer23/include/osmocom/bb/common/subscriber.h @@ -1,29 +1,54 @@ #ifndef _SUBSCRIBER_H #define _SUBSCRIBER_H +#include <stdbool.h> + +#include <osmocom/core/utils.h> +#include <osmocom/gsm/protocol/gsm_23_003.h> +#include <osmocom/gsm/gsm23003.h> +#include <osmocom/gsm/gsm48.h> + /* GSM 04.08 4.1.2.2 SIM update status */ -#define GSM_SIM_U0_NULL 0 -#define GSM_SIM_U1_UPDATED 1 -#define GSM_SIM_U2_NOT_UPDATED 2 -#define GSM_SIM_U3_ROAMING_NA 3 +enum gsm_sub_sim_ustate { + GSM_SIM_U0_NULL, + GSM_SIM_U1_UPDATED, + GSM_SIM_U2_NOT_UPDATED, + GSM_SIM_U3_ROAMING_NA, +}; +extern const struct value_string gsm_sub_sim_ustate_names[]; +static inline const char *gsm_sub_sim_ustate_name(enum gsm_sub_sim_ustate val) +{ + return get_value_string(gsm_sub_sim_ustate_names, val); +} + +/* 3GPP TS 24.008 4.1.3.2 GPRS update status */ +enum gsm_sub_sim_gustate { + GSM_SIM_GU0_NULL, + GSM_SIM_GU1_UPDATED, + GSM_SIM_GU2_NOT_UPDATED, + GSM_SIM_GU3_ROAMING_NA, +}; +extern const struct value_string gsm_sub_sim_gustate_names[]; +static inline const char *gsm_sub_sim_gustate_name(enum gsm_sub_sim_gustate val) +{ + return get_value_string(gsm_sub_sim_gustate_names, val); +} struct gsm_sub_plmn_list { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; }; struct gsm_sub_plmn_na { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; uint8_t cause; }; -#define GSM_IMSI_LENGTH 16 - #define GSM_SIM_IS_READER(type) \ (type == GSM_SIM_TYPE_L1PHY || type == GSM_SIM_TYPE_SAP) -enum { +enum gsm_subscriber_sim_type { GSM_SIM_TYPE_NONE = 0, GSM_SIM_TYPE_L1PHY, GSM_SIM_TYPE_TEST, @@ -34,19 +59,19 @@ struct gsm_subscriber { struct osmocom_ms *ms; /* status */ - uint8_t sim_type; /* type of sim */ - uint8_t sim_valid; /* sim inserted and valid */ - uint8_t ustate; /* update status */ - uint8_t imsi_attached; /* attached state */ + enum gsm_subscriber_sim_type sim_type; /* type of sim */ + bool sim_valid; /* sim inserted and valid */ + enum gsm_sub_sim_ustate ustate; /* update status */ + bool imsi_attached; /* attached state */ /* IMSI & co */ - char imsi[GSM_IMSI_LENGTH]; + char imsi[OSMO_IMSI_BUF_SIZE]; char msisdn[31]; /* may include access codes */ char iccid[21]; /* 20 + termination */ /* TMSI / LAI */ - uint32_t tmsi; /* invalid tmsi: 0xffffffff */ - uint16_t mcc, mnc, lac; /* invalid lac: 0x0000 */ + uint32_t tmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ + struct osmo_location_area_id lai; /* invalid lac: 0x0000 */ /* key */ @@ -59,7 +84,7 @@ struct gsm_subscriber { uint8_t t6m_hplmn; /* timer for hplmn search */ /* special things */ - uint8_t always_search_hplmn; + bool always_search_hplmn; /* search hplmn in other countries also (for test cards) */ uint8_t any_timeout; /* timer to restart 'any cell selection' */ @@ -67,16 +92,16 @@ struct gsm_subscriber { char sim_spn[17]; /* name of service privider */ /* PLMN last registered */ - uint8_t plmn_valid; - uint16_t plmn_mcc, plmn_mnc; + bool plmn_valid; + struct osmo_plmn_id plmn; /* our access */ - uint8_t acc_barr; /* if we may access, if cell barred */ + bool acc_barr; /* if we may access, if cell barred */ uint16_t acc_class; /* bitmask of what we may access */ /* talk to SIM */ uint8_t sim_state; - uint8_t sim_pin_required; /* state: wait for PIN */ + bool sim_pin_required; /* state: wait for PIN */ uint8_t sim_file_index; uint32_t sim_handle_query; uint32_t sim_handle_update; @@ -84,35 +109,38 @@ struct gsm_subscriber { /* SMS */ char sms_sca[22]; + + struct { + uint8_t gu_state; /* GU, TS 24.008 */ + bool rai_valid; + struct gprs_ra_id rai; + uint32_t ptmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ + uint32_t ptmsi_sig; /* P-TMSI signature, 3 bytes */ + bool imsi_attached; + } gprs; }; int gsm_subscr_init(struct osmocom_ms *ms); int gsm_subscr_exit(struct osmocom_ms *ms); -int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc, - uint16_t lac, uint32_t tmsi, uint8_t imsi_attached); +int gsm_subscr_insert(struct osmocom_ms *ms); +int gsm_subscr_remove(struct osmocom_ms *ms); + int gsm_subscr_sap_rsp_cb(struct osmocom_ms *ms, int res_code, uint8_t res_type, uint16_t param_len, const uint8_t *param_val); -int gsm_subscr_sapcard(struct osmocom_ms *ms); -int gsm_subscr_remove_sapcard(struct osmocom_ms *ms); -int gsm_subscr_simcard(struct osmocom_ms *ms); -void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2, - int8_t mode); +int gsm_subscr_sim_pin(struct osmocom_ms *ms, const char *pin1, const char *pin2, + int8_t mode); int gsm_subscr_write_loci(struct osmocom_ms *ms); -int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq, - uint8_t *rand, uint8_t no_sim); -int gsm_subscr_remove(struct osmocom_ms *ms); +int gsm_subscr_write_locigprs(struct osmocom_ms *ms); +int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq, const uint8_t *rand, + bool no_sim); void new_sim_ustate(struct gsm_subscriber *subscr, int state); -int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc); -int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc, uint8_t cause); -int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc); +int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn); +int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn, uint8_t cause); +int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn); int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms, void (*print)(void *, const char *, ...), void *priv); void gsm_subscr_dump(struct gsm_subscriber *subscr, void (*print)(void *, const char *, ...), void *priv); -char *gsm_check_imsi(const char *imsi); int gsm_subscr_get_key_seq(struct osmocom_ms *ms, struct gsm_subscriber *subscr); #endif /* _SUBSCRIBER_H */ diff --git a/src/host/layer23/include/osmocom/bb/mobile/support.h b/src/host/layer23/include/osmocom/bb/common/support.h index c56c78e8..b0c71f5a 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/support.h +++ b/src/host/layer23/include/osmocom/bb/common/support.h @@ -91,6 +91,14 @@ struct gsm_support { uint8_t half_v1; uint8_t half_v3; + /* CSD modes */ + uint8_t csd_tch_f144; + uint8_t csd_tch_f96; + uint8_t csd_tch_f48; + uint8_t csd_tch_h48; + uint8_t csd_tch_f24; + uint8_t csd_tch_h24; + /* EDGE / UMTS / CDMA */ uint8_t edge_ms_sup; uint8_t edge_psk_sup; @@ -110,7 +118,7 @@ struct gsm_support_scan_max { uint16_t start; uint16_t end; uint16_t max; - uint16_t temp; + uint16_t temp; }; extern struct gsm_support_scan_max gsm_sup_smax[]; diff --git a/src/host/layer23/include/osmocom/bb/common/sysinfo.h b/src/host/layer23/include/osmocom/bb/common/sysinfo.h index f843f271..c31cf9d6 100644 --- a/src/host/layer23/include/osmocom/bb/common/sysinfo.h +++ b/src/host/layer23/include/osmocom/bb/common/sysinfo.h @@ -2,6 +2,7 @@ #define _SYSINFO_H #include <osmocom/gsm/gsm48_ie.h> +#include <osmocom/gsm/gsm23003.h> /* collection of system information of the current cell */ @@ -17,11 +18,27 @@ #define FREQ_TYPE_REP_5bis 0x40 /* sub channel of SI 5bis */ #define FREQ_TYPE_REP_5ter 0x80 /* sub channel of SI 5ter */ -/* structure of all received system informations */ +struct si10_cell_info { + uint8_t index; /* frequency index of the frequencies received in SI5* */ + int16_t arfcn; /* ARFCN or -1 (if not found in SI5*) */ + uint8_t bsic; + bool barred; /* Cell is barred, values below are invalid. */ + bool la_different; /* Location area is different, so CRH is valid. */ + uint8_t cell_resel_hyst_db; + uint8_t ms_txpwr_max_cch; + uint8_t rxlev_acc_min_db; + uint8_t cell_resel_offset; + uint8_t temp_offset; + uint8_t penalty_time; +}; + +/* structure of all received system information */ struct gsm48_sysinfo { /* flags of available information */ uint8_t si1, si2, si2bis, si2ter, si3, - si4, si5, si5bis, si5ter, si6; + si4, si5, si5bis, si5ter, si6, + si13; + bool si10; /* memory maps to simply detect change in system info messages */ uint8_t si1_msg[23]; @@ -34,6 +51,8 @@ struct gsm48_sysinfo { uint8_t si5b_msg[18]; uint8_t si5t_msg[18]; uint8_t si6_msg[18]; + uint8_t si10_msg[21]; + uint8_t si13_msg[23]; struct gsm_sysinfo_freq freq[1024]; /* all frequencies */ uint16_t hopping[64]; /* hopping arfcn */ @@ -42,7 +61,7 @@ struct gsm48_sysinfo { /* serving cell */ uint8_t bsic; uint16_t cell_id; - uint16_t mcc, mnc, lac; /* LAI */ + struct osmo_location_area_id lai; uint8_t max_retrans; /* decoded */ uint8_t tx_integer; /* decoded */ uint8_t reest_denied; /* 1 = denied */ @@ -52,7 +71,7 @@ struct gsm48_sysinfo { /* si1 rest */ uint8_t nch; uint8_t nch_position; - uint8_t band_ind; /* set for DCS */ + bool band_ind; /* set for DCS */ /* si3 rest */ uint8_t sp; @@ -66,9 +85,46 @@ struct gsm48_sysinfo { uint8_t ecsm; uint8_t sched; uint8_t sched_where; - uint8_t gprs; - uint8_t gprs_ra_colour; - uint8_t gprs_si13_pos; + + struct { + /* si3/si4 rest */ + uint8_t supported; + uint8_t ra_colour; + uint8_t si13_pos; + + /* si13 rest */ + uint8_t hopping; + uint8_t hsn; + uint8_t rfl_num_len; + uint8_t rfl_num[4]; + + uint8_t ma_bitlen; + uint8_t ma_bitmap[64 / 8]; + uint8_t arfcn_idx_len; + uint8_t arfcn_idx[16]; + + /* PBCCH is not present */ + uint8_t rac; + uint8_t prio_acc_thresh; + uint8_t nco; + + /* GPRS Cell Options */ + uint8_t nmo; + uint8_t T3168; + uint8_t T3192; + uint8_t ab_type; + uint8_t ctrl_ack_type_use_block; + uint8_t bs_cv_max; + uint8_t pan_params_present; + uint8_t pan_dec; + uint8_t pan_inc; + uint8_t pan_max; + + /* EGPRS Cell Options */ + uint8_t egprs_supported; + uint8_t egprs_pkt_chan_req; + uint8_t egprs_bep_period; + } gprs; /* cell selection */ int8_t ms_txpwr_max_cch; @@ -118,45 +174,52 @@ struct gsm48_sysinfo { uint8_t nb_reest_denied; /* 1 = denied */ uint8_t nb_cell_barr; /* 1 = barred */ uint16_t nb_class_barr; /* bit 10 is emergency */ + + /* SI 10 */ + uint8_t si10_cell_num; /* number neighbor cells found in SI 10 */ + struct si10_cell_info si10_cell[32]; /* 32 neighbor cell descriptions */ }; char *gsm_print_arfcn(uint16_t arfcn); -uint8_t gsm_refer_pcs(uint16_t arfcn, struct gsm48_sysinfo *s); -int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn, - void (*print)(void *, const char *, ...), void *priv, - uint8_t *freq_map); +bool gsm_refer_pcs(uint16_t cell_arfcn, const struct gsm48_sysinfo *cell_s); +uint16_t gsm_arfcn_refer_pcs(uint16_t cell_arfcn, const struct gsm48_sysinfo *cell_s, uint16_t arfcn); +int gsm48_sysinfo_dump(const struct gsm48_sysinfo *s, uint16_t arfcn, + void (*print)(void *, const char *, ...), + void *priv, uint8_t *freq_map); +int gsm48_si10_dump(const struct gsm48_sysinfo *s, void (*print)(void *, const char *, ...), void *priv); int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc, uint16_t *mnc, uint16_t *lac); -int gsm48_decode_chan_h0(struct gsm48_chan_desc *cd, uint8_t *tsc, - uint16_t *arfcn); -int gsm48_decode_chan_h1(struct gsm48_chan_desc *cd, uint8_t *tsc, - uint8_t *maio, uint8_t *hsn); +int gsm48_decode_chan_h0(const struct gsm48_chan_desc *cd, + uint8_t *tsc, uint16_t *arfcn); +int gsm48_decode_chan_h1(const struct gsm48_chan_desc *cd, + uint8_t *tsc, uint8_t *maio, uint8_t *hsn); int gsm48_decode_sysinfo1(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_1 *si, int len); + const struct gsm48_system_information_type_1 *si, int len); int gsm48_decode_sysinfo2(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_2 *si, int len); + const struct gsm48_system_information_type_2 *si, int len); int gsm48_decode_sysinfo2bis(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_2bis *si, int len); + const struct gsm48_system_information_type_2bis *si, int len); int gsm48_decode_sysinfo2ter(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_2ter *si, int len); + const struct gsm48_system_information_type_2ter *si, int len); int gsm48_decode_sysinfo3(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_3 *si, int len); + const struct gsm48_system_information_type_3 *si, int len); int gsm48_decode_sysinfo4(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_4 *si, int len); + const struct gsm48_system_information_type_4 *si, int len); int gsm48_decode_sysinfo5(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_5 *si, int len); + const struct gsm48_system_information_type_5 *si, int len); int gsm48_decode_sysinfo5bis(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_5bis *si, int len); + const struct gsm48_system_information_type_5bis *si, int len); int gsm48_decode_sysinfo5ter(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_5ter *si, int len); + const struct gsm48_system_information_type_5ter *si, int len); int gsm48_decode_sysinfo6(struct gsm48_sysinfo *s, - struct gsm48_system_information_type_6 *si, int len); + const struct gsm48_system_information_type_6 *si, int len); +int gsm48_decode_sysinfo10(struct gsm48_sysinfo *s, + const struct gsm48_system_information_type_10 *si, int len); +int gsm48_decode_sysinfo13(struct gsm48_sysinfo *s, + const struct gsm48_system_information_type_13 *si, int len); int gsm48_decode_mobile_alloc(struct gsm_sysinfo_freq *freq, - uint8_t *ma, uint8_t len, uint16_t *hopping, uint8_t *hopp_len, - int si4); -int gsm48_encode_lai_hex(struct gsm48_loc_area_id *lai, uint16_t mcc, - uint16_t mnc, uint16_t lac); -int gsm48_decode_lai_hex(struct gsm48_loc_area_id *lai, uint16_t *mcc, - uint16_t *mnc, uint16_t *lac); + const uint8_t *ma, uint8_t len, + uint16_t *hopping, uint8_t *hopp_len, int si4); +int16_t arfcn_from_freq_index(const struct gsm48_sysinfo *s, uint16_t index); #endif /* _SYSINFO_H */ diff --git a/src/host/layer23/include/osmocom/bb/common/vty.h b/src/host/layer23/include/osmocom/bb/common/vty.h new file mode 100644 index 00000000..b2a52c01 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/common/vty.h @@ -0,0 +1,35 @@ +#pragma once + +#include <osmocom/bb/common/osmocom_data.h> +#include <osmocom/vty/vty.h> +#include <osmocom/vty/buffer.h> +#include <osmocom/vty/command.h> +#include <osmocom/core/signal.h> + +struct osmocom_ms; + +enum l23_vty_node { + MS_NODE = _LAST_OSMOVTY_NODE + 1, + TESTSIM_NODE, + GSMTAP_NODE, + _LAST_L23VTY_NODE, +}; + +int l23_vty_init(int (*config_write_ms_node_cb)(struct vty *), osmo_signal_cbfn *l23_vty_signal_cb); + +struct osmocom_ms *l23_vty_get_ms(const char *name, struct vty *vty); +void l23_ms_dump(struct osmocom_ms *ms, struct vty *vty); +void l23_vty_config_write_ms_node(struct vty *vty, const struct osmocom_ms *ms, const char *prefix); +void l23_vty_config_write_ms_node_contents(struct vty *vty, const struct osmocom_ms *ms, const char *prefix); +void l23_vty_config_write_ms_node_contents_final(struct vty *vty, const struct osmocom_ms *ms, const char *prefix); + +void l23_vty_ms_notify(struct osmocom_ms *ms, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +void l23_vty_printf(void *priv, const char *fmt, ...); + +extern bool l23_vty_reading; +extern bool l23_vty_hide_default; + +extern struct llist_head ms_list; + +extern struct cmd_element l23_show_ms_cmd; +extern struct cmd_element l23_cfg_ms_cmd; diff --git a/src/host/layer23/include/osmocom/bb/misc/Makefile.am b/src/host/layer23/include/osmocom/bb/misc/Makefile.am index 59760906..14d3af95 100644 --- a/src/host/layer23/include/osmocom/bb/misc/Makefile.am +++ b/src/host/layer23/include/osmocom/bb/misc/Makefile.am @@ -1 +1,8 @@ -noinst_HEADERS = layer3.h rslms.h cell_log.h +noinst_HEADERS = \ + cell_log.h \ + geo.h \ + layer3.h \ + locate.h \ + log.h \ + rslms.h \ + $(NULL) diff --git a/src/host/layer23/include/osmocom/bb/misc/cell_log.h b/src/host/layer23/include/osmocom/bb/misc/cell_log.h index bce066eb..bef6e6ee 100644 --- a/src/host/layer23/include/osmocom/bb/misc/cell_log.h +++ b/src/host/layer23/include/osmocom/bb/misc/cell_log.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ int scan_init(struct osmocom_ms *_ms); diff --git a/src/host/layer23/include/osmocom/bb/misc/geo.h b/src/host/layer23/include/osmocom/bb/misc/geo.h new file mode 100644 index 00000000..25e26cba --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/misc/geo.h @@ -0,0 +1,12 @@ +/* WGS 84 */ +#define EQUATOR_RADIUS 6378137.0 +#define POLE_RADIUS 6356752.314 + +#define PI 3.1415926536 + +void geo2space(double *x, double *y, double *z, double lat, double lon); +void space2geo(double *lat, double *lon, double x, double y, double z); +double distinspace(double x1, double y1, double z1, double x2, double y2, + double z2); +double distonplane(double x1, double y1, double x2, double y2); + diff --git a/src/host/layer23/include/osmocom/bb/misc/locate.h b/src/host/layer23/include/osmocom/bb/misc/locate.h new file mode 100644 index 00000000..26133452 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/misc/locate.h @@ -0,0 +1,8 @@ + +struct probe { + struct probe *next; + double x, y, dist; +}; + +int locate_cell(struct probe *probe_first, double *min_x, double *min_y); + diff --git a/src/host/layer23/include/osmocom/bb/misc/log.h b/src/host/layer23/include/osmocom/bb/misc/log.h new file mode 100644 index 00000000..3183f876 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/misc/log.h @@ -0,0 +1,84 @@ +#pragma once + +#include <osmocom/bb/common/sysinfo.h> + +enum { + LOG_TYPE_NONE = 0, + LOG_TYPE_SYSINFO, + LOG_TYPE_POWER, +}; + +struct power { + uint8_t gps_valid; + double longitude, latitude; + time_t gmt; + int8_t rxlev[1024]; +}; + +struct node_power { + struct node_power *next; + struct power power; +}; + +struct node_mcc { + struct node_mcc *next; + uint16_t mcc; + struct node_mnc *mnc; +}; + +struct node_mnc { + struct node_mnc *next; + uint16_t mnc; + bool mnc_3_digits; + struct node_lac *lac; +}; + +struct node_lac { + struct node_lac *next; + uint16_t lac; + struct node_cell *cell; +}; + +struct sysinfo { + uint16_t arfcn; + int8_t rxlev; + uint8_t bsic; + uint8_t gps_valid; + double longitude, latitude; + time_t gmt; + uint8_t si1[23]; + uint8_t si2[23]; + uint8_t si2bis[23]; + uint8_t si2ter[23]; + uint8_t si3[23]; + uint8_t si4[23]; + uint8_t ta_valid; + uint8_t ta; +}; + +struct node_cell { + struct node_cell *next; + uint16_t cellid; + uint8_t content; /* indicates, if sysinfo is already applied */ + struct node_meas *meas, **meas_last_p; + struct sysinfo sysinfo; + struct gsm48_sysinfo s; +}; + +struct node_meas { + struct node_meas *next; + time_t gmt; + int8_t rxlev; + uint8_t gps_valid; + double longitude, latitude; + uint8_t ta_valid; + uint8_t ta; +}; + +struct node_mcc *get_node_mcc(uint16_t mcc); +struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc, bool mnc_3_digits); +struct node_lac *get_node_lac(struct node_mnc *mnc, uint16_t lac); +struct node_cell *get_node_cell(struct node_lac *lac, uint16_t cellid); +struct node_meas *add_node_meas(struct node_cell *cell); +int read_log(FILE *infp); + diff --git a/src/host/layer23/include/osmocom/bb/mobile/Makefile.am b/src/host/layer23/include/osmocom/bb/mobile/Makefile.am index 623964fd..5d2eeaf8 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/Makefile.am +++ b/src/host/layer23/include/osmocom/bb/mobile/Makefile.am @@ -1,4 +1,4 @@ noinst_HEADERS = gsm322.h gsm480_ss.h gsm411_sms.h gsm48_cc.h gsm48_mm.h \ - gsm48_rr.h mncc.h settings.h subscriber.h support.h \ - transaction.h vty.h mncc_sock.h mncc_ms.h primitives.h \ - app_mobile.h voice.h + gsm48_rr.h mncc.h gsm44068_gcc_bcc.h \ + tch.h transaction.h vty.h mncc_sock.h mncc_ms.h primitives.h \ + app_mobile.h gapk_io.h diff --git a/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h b/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h index 191f4baf..940dbce7 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h +++ b/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h @@ -8,10 +8,6 @@ extern char *config_dir; struct osmocom_ms; struct vty; -int l23_app_init(int (*mncc_recv)(struct osmocom_ms *ms, int, void *), - const char *config_file); -int l23_app_exit(void); -int l23_app_work(int *quit); int mobile_delete(struct osmocom_ms *ms, int force); struct osmocom_ms *mobile_new(char *name); int mobile_work(struct osmocom_ms *ms); diff --git a/src/host/layer23/include/osmocom/bb/mobile/gapk_io.h b/src/host/layer23/include/osmocom/bb/mobile/gapk_io.h new file mode 100644 index 00000000..ab8b6579 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/mobile/gapk_io.h @@ -0,0 +1,47 @@ +#pragma once + +#ifdef WITH_GAPK_IO + +#include <stdint.h> +#include <stdbool.h> + +#include <osmocom/gapk/procqueue.h> +#include <osmocom/gapk/codecs.h> + +#define GAPK_ULDL_QUEUE_LIMIT 8 + +/* Forward declarations */ +struct osmocom_ms; +struct msgb; + +struct gapk_io_state { + /* src/alsa -> proc/codec -> sink/tch_fb */ + struct osmo_gapk_pq *pq_source; + /* src/tch_fb -> proc/codec -> sink/alsa */ + struct osmo_gapk_pq *pq_sink; + + /* Description of currently used codec / format */ + const struct osmo_gapk_format_desc *phy_fmt_desc; + const struct osmo_gapk_codec_desc *codec_desc; + + /* DL TCH frame buffer (received, to be played) */ + struct llist_head tch_dl_fb; + unsigned int tch_dl_fb_len; + /* UL TCH frame buffer (captured, to be sent) */ + struct llist_head tch_ul_fb; + unsigned int tch_ul_fb_len; +}; + +struct gapk_io_state * +gapk_io_state_alloc(struct osmocom_ms *ms, + enum osmo_gapk_codec_type codec); +struct gapk_io_state * +gapk_io_state_alloc_mode_rate(struct osmocom_ms *ms, + enum gsm48_chan_mode ch_mode, + bool full_rate); +void gapk_io_state_free(struct gapk_io_state *state); + +void gapk_io_enqueue_dl(struct gapk_io_state *state, struct msgb *msg); +void gapk_io_dequeue_ul(struct osmocom_ms *ms, struct gapk_io_state *state); + +#endif /* WITH_GAPK_IO */ diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm322.h b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h index d4caac99..4b20a1a1 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gsm322.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h @@ -1,12 +1,13 @@ #ifndef _GSM322_H #define _GSM322_H -#include <osmocom/bb/common/sysinfo.h> - #include <osmocom/core/linuxlist.h> #include <osmocom/core/timer.h> +#include <osmocom/gsm/gsm23003.h> + +#include <osmocom/bb/common/sysinfo.h> -/* 4.3.1.1 List of states for PLMN slection process (automatic mode) */ +/* 4.3.1.1 List of states for PLMN selection process (automatic mode) */ #define GSM322_A0_NULL 0 #define GSM322_A1_TRYING_RPLMN 1 #define GSM322_A2_ON_PLMN 2 @@ -15,7 +16,7 @@ #define GSM322_A5_HPLMN_SEARCH 5 #define GSM322_A6_NO_SIM 6 -/* 4.3.1.2 List of states for PLMN slection process (manual mode) */ +/* 4.3.1.2 List of states for PLMN selection process (manual mode) */ #define GSM322_M0_NULL 0 #define GSM322_M1_TRYING_RPLMN 1 #define GSM322_M2_ON_PLMN 2 @@ -42,7 +43,7 @@ /* GSM 03.22 events */ #define GSM322_EVENT_SWITCH_ON 1 -#define GSM322_EVENT_SWITCH_OFF 2 +#define GSM322_EVENT_SWITCH_OFF 2 #define GSM322_EVENT_SIM_INSERT 3 #define GSM322_EVENT_SIM_REMOVE 4 #define GSM322_EVENT_REG_SUCCESS 5 @@ -74,7 +75,7 @@ enum { /* node for each PLMN */ struct gsm322_plmn_list { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; uint8_t rxlev; /* rx level in range format */ uint8_t cause; /* cause value, if PLMN is not allowed */ }; @@ -82,14 +83,14 @@ struct gsm322_plmn_list { /* node for each forbidden LA */ struct gsm322_la_list { struct llist_head entry; - uint16_t mcc, mnc, lac; + struct osmo_location_area_id lai; uint8_t cause; }; /* node for each BA-List */ struct gsm322_ba_list { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; /* Band allocation for 1024+299 frequencies. * First bit of first index is frequency 0. */ @@ -124,14 +125,14 @@ struct gsm322_plmn { struct osmo_timer_list timer; int plmn_curr; /* current index in sorted_plmn */ - uint16_t mcc, mnc; /* current network selected */ + struct osmo_plmn_id plmn; /* current network selected */ }; /* state of CCCH activation */ #define GSM322_CCCH_ST_IDLE 0 /* no connection */ -#define GSM322_CCCH_ST_INIT 1 /* initalized */ +#define GSM322_CCCH_ST_INIT 1 /* initialized */ #define GSM322_CCCH_ST_SYNC 2 /* got sync */ -#define GSM322_CCCH_ST_DATA 3 /* receiveing data */ +#define GSM322_CCCH_ST_DATA 3 /* receiving data */ /* neighbour cell info list entry */ struct gsm322_neighbour { @@ -144,7 +145,7 @@ struct gsm322_neighbour { time_t when; /* when did we sync / read */ int16_t rxlev_sum_dbm; /* sum of received levels */ uint8_t rxlev_count; /* number of received levels */ - int8_t rla_c_dbm; /* average of the reveive level */ + int8_t rla_c_dbm; /* average of the receive level */ uint8_t c12_valid; /* both C1 and C2 are calculated */ int16_t c1, c2, crh; uint8_t checked_for_resel; @@ -171,7 +172,7 @@ struct gsm322_cellsel { /* cell selection list per frequency. */ /* scan and tune state */ struct osmo_timer_list timer; /* cell selection timer */ - uint16_t mcc, mnc; /* current network to search for */ + struct osmo_plmn_id plmn; /* current network to search for */ uint8_t powerscan; /* currently scanning for power */ uint8_t ccch_state; /* special state of current ccch */ uint32_t scan_state; /* special state of current scan */ @@ -188,7 +189,7 @@ struct gsm322_cellsel { uint8_t selected; /* if a cell is selected */ uint16_t sel_arfcn; /* current selected serving cell! */ struct gsm48_sysinfo sel_si; /* copy of selected cell, will update */ - uint16_t sel_mcc, sel_mnc, sel_lac, sel_id; + struct osmo_cell_global_id sel_cgi; /* cell re-selection */ struct llist_head nb_list; /* list of neighbour cells */ @@ -209,7 +210,7 @@ struct gsm322_cellsel { /* GSM 03.22 message */ struct gsm322_msg { int msg_type; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; uint8_t sysinfo; /* system information type */ uint8_t same_cell; /* select same cell when RET_IDLE */ uint8_t reject; /* location update reject cause */ @@ -229,18 +230,15 @@ int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg); int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg); int gsm322_plmn_dequeue(struct osmocom_ms *ms); int gsm322_cs_dequeue(struct osmocom_ms *ms); -int gsm322_add_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, - uint16_t mnc, uint16_t lac, uint8_t cause); -int gsm322_del_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, - uint16_t mnc, uint16_t lac); -int gsm322_is_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc, - uint16_t lac); +int gsm322_add_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai, uint8_t cause); +int gsm322_del_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai); +int gsm322_is_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai); int gsm322_dump_sorted_plmn(struct osmocom_ms *ms); int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags, void (*print)(void *, const char *, ...), void *priv); int gsm322_dump_forbidden_la(struct osmocom_ms *ms, void (*print)(void *, const char *, ...), void *priv); -int gsm322_dump_ba_list(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc, +int gsm322_dump_ba_list(struct gsm322_cellsel *cs, const struct osmo_plmn_id *plmn, void (*print)(void *, const char *, ...), void *priv); int gsm322_dump_nb_list(struct gsm322_cellsel *cs, void (*print)(void *, const char *, ...), void *priv); diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm44068_gcc_bcc.h b/src/host/layer23/include/osmocom/bb/mobile/gsm44068_gcc_bcc.h new file mode 100644 index 00000000..e9889b32 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm44068_gcc_bcc.h @@ -0,0 +1,43 @@ +/* VGCS/VBS call control */ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Andreas Eversberg + * + * 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 <http://www.gnu.org/licenses/>. + */ +#pragma once + +#define GSM44068_ALLOC_SIZE 2048 +#define GSM44068_ALLOC_HEADROOM 256 + +static inline struct msgb *gsm44068_msgb_alloc_name(const char *name) +{ + return msgb_alloc_headroom(GSM44068_ALLOC_SIZE, GSM44068_ALLOC_HEADROOM, name); +} + +int gsm44068_gcc_init(struct osmocom_ms *ms); +int gsm44068_gcc_exit(struct osmocom_ms *ms); +int gsm44068_rcv_gcc_bcc(struct osmocom_ms *ms, struct msgb *msg); +int gsm44068_rcv_mm_idle(struct osmocom_ms *ms); +struct gsm_trans *trans_find_ongoing_gcc_bcc(struct osmocom_ms *ms); +int gcc_bcc_call(struct osmocom_ms *ms, uint8_t protocol, const char *number); +int gcc_leave(struct osmocom_ms *ms); +int gcc_bcc_hangup(struct osmocom_ms *ms); +int gcc_talk(struct osmocom_ms *ms); +int gcc_listen(struct osmocom_ms *ms); +int gsm44068_dump_calls(struct osmocom_ms *ms, void (*print)(void *, const char *, ...), void *priv); diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h index 6e9c197c..1f0db785 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h @@ -1,11 +1,16 @@ #ifndef _GSM48_MM_H #define _GSM48_MM_H +struct gsm_settings; + /* GSM 04.07 9.2.2 */ #define GSM48_MMXX_MASK 0xf00 #define GSM48_MMCC_CLASS 0x100 #define GSM48_MMSS_CLASS 0x200 #define GSM48_MMSMS_CLASS 0x300 +#define GSM48_MMGCC_CLASS 0x500 +#define GSM48_MMBCC_CLASS 0x600 +#define GSM48_MMXX_REL_IND 0x022 #define GSM48_MMCC_EST_REQ 0x110 #define GSM48_MMCC_EST_IND 0x112 #define GSM48_MMCC_EST_CNF 0x111 @@ -49,19 +54,67 @@ #define GSM48_MMSMS_ERR_IND 0x372 #define GSM48_MMSMS_PROMPT_IND 0x382 #define GSM48_MMSMS_PROMPT_REJ 0x384 +/* MM messages for Voice Group/Broadcast Calls */ +#define GSM48_MMGCC_EST_REQ 0x510 +#define GSM48_MMGCC_EST_CNF 0x511 +#define GSM48_MMGCC_REL_REQ 0x520 +#define GSM48_MMGCC_REL_IND 0x522 +#define GSM48_MMGCC_DATA_REQ 0x530 +#define GSM48_MMGCC_DATA_IND 0x532 +#define GSM48_MMGCC_UNIT_DATA_REQ 0x540 +#define GSM48_MMGCC_UNIT_DATA_IND 0x542 +#define GSM48_MMGCC_REEST_REQ 0x560 +#define GSM48_MMGCC_REEST_CNF 0x561 +#define GSM48_MMGCC_ERR_IND 0x572 +#define GSM48_MMGCC_NOTIF_IND 0x582 +#define GSM48_MMGCC_GROUP_REQ 0x590 +#define GSM48_MMGCC_GROUP_CNF 0x591 +#define GSM48_MMGCC_UPLINK_REQ 0x5a0 +#define GSM48_MMGCC_UPLINK_CNF 0x5a1 +#define GSM48_MMGCC_UPLINK_REL_REQ 0x5a8 +#define GSM48_MMGCC_UPLINK_REL_IND 0x5aa +#define GSM48_MMGCC_UPLINK_FREE_IND 0x5b2 +#define GSM48_MMGCC_UPLINK_BUSY_IND 0x5b6 +#define GSM48_MMBCC_EST_REQ 0x610 +#define GSM48_MMBCC_EST_CNF 0x611 +#define GSM48_MMBCC_REL_REQ 0x620 +#define GSM48_MMBCC_REL_IND 0x622 +#define GSM48_MMBCC_DATA_REQ 0x630 +#define GSM48_MMBCC_DATA_IND 0x632 +#define GSM48_MMBCC_UNIT_DATA_REQ 0x640 +#define GSM48_MMBCC_UNIT_DATA_IND 0x642 +#define GSM48_MMBCC_REEST_REQ 0x660 +#define GSM48_MMBCC_REEST_CNF 0x661 +#define GSM48_MMBCC_ERR_IND 0x672 +#define GSM48_MMBCC_NOTIF_IND 0x682 +#define GSM48_MMBCC_GROUP_REQ 0x690 +#define GSM48_MMBCC_GROUP_CNF 0x691 +#define GSM48_MMBCC_UPLINK_REQ 0x6a0 +#define GSM48_MMBCC_UPLINK_CNF 0x6a1 +#define GSM48_MMBCC_UPLINK_REL_REQ 0x6a8 +#define GSM48_MMBCC_UPLINK_REL_IND 0x6aa +#define GSM48_MMBCC_UPLINK_FREE_IND 0x6b2 +#define GSM48_MMBCC_UPLINK_BUSY_IND 0x6b6 + #define MMXX_ALLOC_SIZE 256 #define MMXX_ALLOC_HEADROOM 64 +#define MMXX_NOTIFY_SETUP 0 +#define MMXX_NOTIFY_RELEASE 1 + /* MMxx-SAP header */ struct gsm48_mmxx_hdr { - int msg_type; /* MMxx_* primitive */ - uint32_t ref; /* reference to transaction */ - uint32_t transaction_id; /* transaction identifier */ - uint8_t sapi; /* sapi */ - uint8_t emergency; /* emergency type of call */ - uint8_t cause; /* cause used for release */ -}; + uint16_t msg_type; /* MMxx_* primitive */ + uint32_t ref; /* reference to transaction */ + uint32_t transaction_id; /* transaction identifier */ + uint8_t sapi; /* sapi */ + uint8_t emergency; /* emergency type of call */ + uint8_t cause; /* cause used for release */ + uint8_t notify; /* notify ongoing ASCI call */ + bool ch_desc_present; /* notifies channel */ + struct gsm48_chan_desc ch_desc; /* group channel */ +} __attribute__((packed)); /* GSM 6.1.2 */ #define GSM48_MMR_REG_REQ 0x01 @@ -71,10 +124,9 @@ struct gsm48_mmxx_hdr { /* MMR-SAP header */ struct gsm48_mmr { - int msg_type; - + uint8_t msg_type; uint8_t cause; -}; +} __attribute__((packed)); /* GSM 04.07 9.2.1 */ #define GSM48_MMXX_ST_IDLE 0 @@ -134,13 +186,26 @@ struct gsm48_mmr { #define GSM48_MM_EVENT_SYSINFO 14 #define GSM48_MM_EVENT_USER_PLMN_SEL 15 #define GSM48_MM_EVENT_LOST_COVERAGE 16 +#define GSM48_MM_EVENT_NOTIFICATION 17 +#define GSM48_MM_EVENT_UPLINK_FREE 18 +#define GSM48_MM_EVENT_UPLINK_BUSY 19 /* message for MM events */ struct gsm48_mm_event { - uint32_t msg_type; + uint32_t msg_type; - uint8_t sres[4]; -}; + union { + /* GSM48_MM_EVENT_AUTH_RESPONSE */ + uint8_t sres[4]; + /* GSM48_MM_EVENT_NOTIFICATION */ + struct { + uint8_t gcr[5]; + bool ch_desc_present; + struct gsm48_chan_desc ch_desc; + bool gone; + } __attribute__((packed)) notification; + }; +} __attribute__((packed)); /* GSM 04.08 MM timers */ #define GSM_T3210_MS 20, 0 @@ -185,7 +250,7 @@ struct gsm48_mmlayer { uint8_t lupd_rej_cause; /* cause of last reject */ uint8_t lupd_periodic; /* periodic update pending */ uint8_t lupd_retry; /* pending T3211/T3213 to */ - uint16_t lupd_mcc, lupd_mnc, lupd_lac; + struct osmo_location_area_id lupd_lai; /* imsi detach */ uint8_t delay_detach; /* do detach when possible */ @@ -197,6 +262,14 @@ struct gsm48_mmlayer { /* sapi 3 */ int sapi3_link; + + /* VGCS additional states */ + struct { + bool enabled; /* We are in group/broadcast mode. */ + bool group_call; /* This is a group call, not a broadcast call. */ + uint32_t callref; /* Callref of this call. */ + bool normal_service; /* Service state before group transmit mode. */ + } vgcs; }; /* MM connection entry */ @@ -204,7 +277,7 @@ struct gsm48_mm_conn { struct llist_head list; struct gsm48_mmlayer *mm; - /* ref and type form a unique tupple */ + /* ref and protocol form a unique tuple */ uint32_t ref; /* reference to trans */ uint8_t protocol; uint8_t transaction_id; @@ -213,6 +286,8 @@ struct gsm48_mm_conn { int state; }; +int gsm48_encode_mi_lv(struct osmocom_ms *ms, struct msgb *msg, uint8_t mi_type, bool emergency_imsi); +int gsm48_encode_mi_tlv(struct osmocom_ms *ms, struct msgb *msg, uint8_t mi_type, bool emergency_imsi); uint8_t gsm48_current_pwr_lev(struct gsm_settings *set, uint16_t arfcn); int gsm48_mm_init(struct osmocom_ms *ms); int gsm48_mm_exit(struct osmocom_ms *ms); diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h index 6996ff35..112e85a3 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h @@ -1,6 +1,7 @@ #ifndef _GSM48_RR_H #define _GSM48_RR_H +#include <osmocom/core/timer.h> #include <osmocom/gsm/protocol/gsm_04_08.h> #define GSM_TA_CM 55385 @@ -9,6 +10,10 @@ #define T200_DCCH_SHARED 2 /* SDCCH shares SAPI 0 and 3 */ #define T200_ACCH 2 /* SACCH SAPI 3 */ +/* GSM 04.08 RR timers */ +#define GSM_T3128_MS 1, 0 /* Uplink investigation timer. */ +#define GSM_T3130_MS 5, 0 /* Uplink access timeout. */ + /* GSM 04.07 9.1.2 */ #define GSM48_RR_EST_REQ 0x10 @@ -22,6 +27,15 @@ #define GSM48_RR_ABORT_REQ 0x60 #define GSM48_RR_ABORT_IND 0x62 #define GSM48_RR_ACT_REQ 0x70 +/* These are non-stadard primitives, used for group receive/transmit modes. */ +#define GSM48_RR_GROUP_REQ 0x80 /* Join a group channel in group receive mode. */ +#define GSM48_RR_GROUP_CNF 0x81 /* Group channel has been joined. */ +#define GSM48_RR_GROUP_REL_REQ 0x84 /* Release group channel. */ +#define GSM48_RR_GROUP_REL_IND 0x86 /* Group channel has been released or failed. */ +#define GSM48_RR_UPLINK_REQ 0x90 /* Request uplink for group transmit mode. */ +#define GSM48_RR_UPLINK_CNF 0x91 /* Access granted. */ +#define GSM48_RR_UPLINK_REL_REQ 0x94 /* Release uplink for group receive mode. */ +#define GSM48_RR_UPLINK_REL_IND 0x96 /* Access denied or failed or uplink released. */ #define RR_EST_CAUSE_EMERGENCY 1 #define RR_EST_CAUSE_REESTAB_TCH_F 2 @@ -44,6 +58,8 @@ #define RR_REL_CAUSE_EMERGENCY_ONLY 6 #define RR_REL_CAUSE_LOST_SIGNAL 7 #define RR_REL_CAUSE_LINK_FAILURE 8 +#define RR_REL_CAUSE_UPLINK_BUSY 9 +#define RR_REL_CAUSE_UPLINK_REJECTED 10 #define RR_SYNC_CAUSE_CIPHERING 1 @@ -69,6 +85,13 @@ struct gsm48_rr_hdr { #define GSM48_RR_ST_DEDICATED 2 #define GSM48_RR_ST_REL_PEND 3 +/* group states (VGCS) */ +enum gsm48_rr_gstate { + GSM48_RR_GST_OFF = 0, + GSM48_RR_GST_RECEIVE, + GSM48_RR_GST_TRANSMIT, +}; + /* special states for SAPI 3 link */ #define GSM48_RR_SAPI3ST_IDLE 0 #define GSM48_RR_SAPI3ST_WAIT_EST 1 @@ -100,6 +123,7 @@ struct gsm48_rr_cd { uint8_t start; /* start time available */ struct gsm_time start_tm; /* start time */ uint8_t mode; /* mode of channel */ + uint8_t tch_flags; /* E.g. L1CTL_TCH_FLAG_RXONLY */ uint8_t cipher; /* ciphering of channel */ }; @@ -149,7 +173,7 @@ struct gsm48_rrlayer { /* channel request states */ uint8_t wait_assign; /* waiting for assignment state */ uint8_t n_chan_req; /* number left, incl. current */ - uint8_t chan_req_val; /* current request value */ + uint8_t chan_req_val; /* current request value */ uint8_t chan_req_mask; /* mask of random bits */ /* state of dedicated mdoe */ @@ -157,7 +181,7 @@ struct gsm48_rrlayer { /* cr_hist */ uint8_t cr_ra; /* stores requested ra until confirmed */ - struct gsm48_cr_hist cr_hist[3]; + struct gsm48_cr_hist cr_hist[5]; /* V(SD) sequence numbers */ uint16_t v_sd; /* 16 PD 1-bit sequence numbers packed */ @@ -188,9 +212,27 @@ struct gsm48_rrlayer { /* audio flow */ uint8_t audio_mode; + /* 3GPP TS 44.014 TCH test loop mode (L1CTL specific format) */ + uint8_t tch_loop_mode; + /* sapi 3 */ uint8_t sapi3_state; uint8_t sapi3_link_id; + + /* group call */ + struct { + struct llist_head notif_list; /* list of received call notifications */ + enum gsm48_rr_gstate group_state; /* extension to RR state for group transmit/receive modes */ + struct gsm48_rr_cd cd_group; /* channel description of group call channel */ + bool uplink_free; /* Is set, if uplink is currently free. */ + uint8_t uic; /* UIC to use for access burst (-1 for BSIC) */ + bool uplink_access; /* The network wants us to send listener access bursts. */ + struct osmo_timer_list t_ul_free; /* Uplink free timer. (480ms timer) */ + struct osmo_timer_list t3128; /* Uplink investigation timer. */ + struct osmo_timer_list t3130; /* Uplink access timer. */ + uint8_t uplink_tries; /* Counts number of tries to access the uplink. */ + uint8_t uplink_counter; /* Counts number of access bursts per 'try'. */ + } vgcs; }; const char *get_rr_name(int value); @@ -209,7 +251,7 @@ extern const char *gsm48_rr_state_names[]; int gsm48_rr_start_monitor(struct osmocom_ms *ms); int gsm48_rr_stop_monitor(struct osmocom_ms *ms); int gsm48_rr_alter_delay(struct osmocom_ms *ms); -int gsm48_rr_tx_voice(struct osmocom_ms *ms, struct msgb *msg); +int gsm48_rr_tx_traffic(struct osmocom_ms *ms, struct msgb *msg); int gsm48_rr_audio_mode(struct osmocom_ms *ms, uint8_t mode); #endif /* _GSM48_RR_H */ diff --git a/src/host/layer23/include/osmocom/bb/mobile/mncc.h b/src/host/layer23/include/osmocom/bb/mobile/mncc.h index 8ec9358d..d6facbbd 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/mncc.h +++ b/src/host/layer23/include/osmocom/bb/mobile/mncc.h @@ -1,4 +1,4 @@ -/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface +/* 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 <laforge@gnumonks.org> @@ -17,35 +17,12 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ -#ifndef _MNCC_H -#define _MNCC_H +#pragma once -#include <osmocom/core/linuxlist.h> #include <osmocom/gsm/mncc.h> -struct gsm_call { - struct llist_head entry; - - struct osmocom_ms *ms; - - uint32_t callref; - - bool init; /* call initiated, no response yet */ - bool hold; /* call on hold */ - bool ring; /* call ringing/knocking */ - - struct osmo_timer_list dtmf_timer; - uint8_t dtmf_state; - uint8_t dtmf_index; - char dtmf[32]; /* dtmf sequence */ -}; - #define DTMF_ST_IDLE 0 /* no DTMF active */ #define DTMF_ST_START 1 /* DTMF started, waiting for resp. */ #define DTMF_ST_MARK 2 /* wait tone duration */ @@ -58,7 +35,7 @@ struct gsm_call { #define MNCC_SETUP_CNF 0x0104 #define MNCC_SETUP_COMPL_REQ 0x0105 #define MNCC_SETUP_COMPL_IND 0x0106 -/* MNCC_REJ_* is perfomed via MNCC_REL_* */ +/* MNCC_REJ_* is performed via MNCC_REL_* */ #define MNCC_CALL_CONF_IND 0x0107 #define MNCC_CALL_PROC_REQ 0x0108 #define MNCC_PROGRESS_REQ 0x0109 @@ -108,6 +85,9 @@ struct gsm_call { #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 GSM_MAX_FACILITY 128 #define GSM_MAX_SSVERSION 128 @@ -128,6 +108,8 @@ struct gsm_call { #define MNCC_F_KEYPAD 0x1000 #define MNCC_F_SIGNAL 0x2000 +struct osmocom_ms; + struct gsm_mncc { /* context based information */ uint32_t msg_type; @@ -136,7 +118,7 @@ struct gsm_mncc { /* which fields are present */ uint32_t fields; - /* data derived informations (MNCC_F_ based) */ + /* data derived information (MNCC_F_ based) */ struct gsm_mncc_bearer_cap bearer_cap; struct gsm_mncc_number called; struct gsm_mncc_number calling; @@ -174,6 +156,3 @@ struct gsm_data_frame { const char *get_mncc_name(int value); int mncc_recv(struct osmocom_ms *ms, int msg_type, void *arg); void mncc_set_cause(struct gsm_mncc *data, int loc, int val); - -#endif - diff --git a/src/host/layer23/include/osmocom/bb/mobile/mncc_ms.h b/src/host/layer23/include/osmocom/bb/mobile/mncc_ms.h index 49ce1a42..05c539b0 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/mncc_ms.h +++ b/src/host/layer23/include/osmocom/bb/mobile/mncc_ms.h @@ -1,6 +1,39 @@ #pragma once -int mncc_call(struct osmocom_ms *ms, char *number); +#include <stdint.h> + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/timer.h> + +struct osmocom_ms; + +enum gsm_call_type { + GSM_CALL_T_UNKNOWN = 0, + GSM_CALL_T_VOICE, + GSM_CALL_T_DATA, /* UDI or 3.1 kHz audio */ + GSM_CALL_T_DATA_FAX, +}; + +struct gsm_call { + struct llist_head entry; + + struct osmocom_ms *ms; + + uint32_t callref; + enum gsm_call_type type; + + bool init; /* call initiated, no response yet */ + bool hold; /* call on hold */ + bool ring; /* call ringing/knocking */ + + struct osmo_timer_list dtmf_timer; + uint8_t dtmf_state; + uint8_t dtmf_index; + char dtmf[32]; /* dtmf sequence */ +}; + +int mncc_call(struct osmocom_ms *ms, const char *number, + enum gsm_call_type call_type); int mncc_hangup(struct osmocom_ms *ms); int mncc_answer(struct osmocom_ms *ms); int mncc_hold(struct osmocom_ms *ms); diff --git a/src/host/layer23/include/osmocom/bb/mobile/settings.h b/src/host/layer23/include/osmocom/bb/mobile/settings.h deleted file mode 100644 index 4e5d5a19..00000000 --- a/src/host/layer23/include/osmocom/bb/mobile/settings.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef _settings_h -#define _settings_h - -#define MOB_C7_DEFLT_ANY_TIMEOUT 30 - -struct gsm_settings { - char layer2_socket_path[128]; - char sap_socket_path[128]; - - /* IMEI */ - char imei[16]; - char imeisv[17]; - char imei_random; - - /* network search */ - int plmn_mode; /* PLMN_MODE_* */ - - /* SIM */ - int sim_type; /* selects card on power on */ - char emergency_imsi[16]; - - /* SMS */ - char sms_sca[22]; - bool store_sms; - - /* test card simulator settings */ - char test_imsi[16]; - uint32_t test_tmsi; - uint8_t test_ki_type; - uint8_t test_ki[16]; /* 128 bit max */ - uint8_t test_barr; - uint8_t test_rplmn_valid; - uint16_t test_rplmn_mcc, test_rplmn_mnc; - uint16_t test_lac; - uint8_t test_imsi_attached; - uint8_t test_always; /* ...search hplmn... */ - - /* call related settings */ - uint8_t cw; /* set if call-waiting is allowed */ - uint8_t auto_answer; - uint8_t clip, clir; - uint8_t half, half_prefer; - - /* changing default behavior */ - uint8_t alter_tx_power; - uint8_t alter_tx_power_value; - int8_t alter_delay; - uint8_t stick; - uint16_t stick_arfcn; - uint8_t skip_max_per_band; - uint8_t no_lupd; - uint8_t no_neighbour; - - /* supported by configuration */ - uint8_t cc_dtmf; - uint8_t sms_ptp; - uint8_t a5_1; - uint8_t a5_2; - uint8_t a5_3; - uint8_t a5_4; - uint8_t a5_5; - uint8_t a5_6; - uint8_t a5_7; - uint8_t p_gsm; - uint8_t e_gsm; - uint8_t r_gsm; - uint8_t dcs; - uint8_t gsm_850; - uint8_t pcs; - uint8_t gsm_480; - uint8_t gsm_450; - uint8_t class_900; - uint8_t class_dcs; - uint8_t class_850; - uint8_t class_pcs; - uint8_t class_400; - uint8_t freq_map[128+38]; - uint8_t full_v1; - uint8_t full_v2; - uint8_t full_v3; - uint8_t half_v1; - uint8_t half_v3; - uint8_t ch_cap; /* channel capability */ - int8_t min_rxlev_dbm; /* min dBm to access */ - - /* radio */ - uint16_t dsc_max; - uint8_t force_rekey; - - /* dialing */ - struct llist_head abbrev; - - /* EDGE / UMTS / CDMA */ - uint8_t edge_ms_sup; - uint8_t edge_psk_sup; - uint8_t edge_psk_uplink; - uint8_t class_900_edge; - uint8_t class_dcs_pcs_edge; - uint8_t umts_fdd; - uint8_t umts_tdd; - uint8_t cdma_2000; - uint8_t dtm; - uint8_t class_dtm; - uint8_t dtm_mac; - uint8_t dtm_egprs; - - /* Timeout for GSM 03.22 C7 state */ - uint8_t any_timeout; -}; - -struct gsm_settings_abbrev { - struct llist_head list; - char abbrev[4]; - char number[32]; - char name[32]; -}; - -int gsm_settings_arfcn(struct osmocom_ms *ms); -int gsm_settings_init(struct osmocom_ms *ms); -int gsm_settings_exit(struct osmocom_ms *ms); -char *gsm_check_imei(const char *imei, const char *sv); -int gsm_random_imei(struct gsm_settings *set); - -#endif /* _settings_h */ - diff --git a/src/host/layer23/include/osmocom/bb/mobile/tch.h b/src/host/layer23/include/osmocom/bb/mobile/tch.h new file mode 100644 index 00000000..b026bd5d --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/mobile/tch.h @@ -0,0 +1,28 @@ +#pragma once + +struct osmocom_ms; +struct gsm_data_frame; +struct msgb; + +struct tch_state { + bool rx_only; /* Rx TCH frames, but Tx nothing */ + bool is_voice; /* voice (true) or data (false) */ + union { + struct tch_voice_state { + enum tch_voice_io_handler handler; + struct gapk_io_state *gapk_io; + } voice; + struct tch_data_state { + enum tch_data_io_handler handler; + struct tch_csd_sock_state *sock; + struct osmo_v110_ta *v110_ta; + struct osmo_soft_uart *suart; + unsigned int num_tx; + uint8_t e1e2e3[3]; + } data; + }; +}; + +int tch_init(struct osmocom_ms *ms); +int tch_send_msg(struct osmocom_ms *ms, struct msgb *msg); +int tch_send_mncc_frame(struct osmocom_ms *ms, const struct gsm_data_frame *frame); diff --git a/src/host/layer23/include/osmocom/bb/mobile/transaction.h b/src/host/layer23/include/osmocom/bb/mobile/transaction.h index 8c06d5d9..c1e94298 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/transaction.h +++ b/src/host/layer23/include/osmocom/bb/mobile/transaction.h @@ -27,7 +27,6 @@ struct gsm_trans { union { struct { - /* current call state */ int state; @@ -39,6 +38,7 @@ struct gsm_trans { int T308_second; /* used to send release again */ struct osmo_timer_list timer; struct gsm_mncc msg; /* stores setup/disconnect/release message */ + struct gsm_mncc_bearer_cap *bcap; } cc; struct { /* current supp.serv. state */ @@ -55,6 +55,26 @@ struct gsm_trans { struct gsm_sms *sms; } sms; + struct { + /* VGCS/VBS state machine */ + struct osmo_fsm_inst *fi; + + /* Call State (See Table 9.3 of TS 144.068) */ + uint8_t call_state; + + /* State attributes (See Table 9.7 of TS 144.068) */ + uint8_t d_att, u_att, comm, orig; + + /* Channel description last received via notification */ + bool ch_desc_present; + struct gsm48_chan_desc ch_desc; + + /* Flag to store termination request from upper layer. */ + bool termination; + + /* Flag to tell the state machine that call changes from separate link to group receive mode. */ + bool receive_after_sl; + } gcc; }; }; @@ -62,7 +82,7 @@ struct gsm_trans { struct gsm_trans *trans_find_by_id(struct osmocom_ms *ms, uint8_t proto, uint8_t trans_id); -struct gsm_trans *trans_find_by_callref(struct osmocom_ms *ms, +struct gsm_trans *trans_find_by_callref(struct osmocom_ms *ms, uint8_t protocol, uint32_t callref); struct gsm_trans *trans_alloc(struct osmocom_ms *ms, diff --git a/src/host/layer23/include/osmocom/bb/mobile/voice.h b/src/host/layer23/include/osmocom/bb/mobile/voice.h deleted file mode 100644 index a0524183..00000000 --- a/src/host/layer23/include/osmocom/bb/mobile/voice.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _voice_h -#define _voice_h - -int gsm_voice_init(struct osmocom_ms *ms); -int gsm_send_voice(struct osmocom_ms *ms, struct gsm_data_frame *data); - -#endif /* _voice_h */ diff --git a/src/host/layer23/include/osmocom/bb/mobile/vty.h b/src/host/layer23/include/osmocom/bb/mobile/vty.h index 3bec1139..f03012e5 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/vty.h +++ b/src/host/layer23/include/osmocom/bb/mobile/vty.h @@ -6,15 +6,16 @@ #include <osmocom/vty/buffer.h> #include <osmocom/vty/command.h> +#include <osmocom/bb/common/vty.h> + enum ms_vty_node { - MS_NODE = _LAST_OSMOVTY_NODE + 1, - TESTSIM_NODE, - SUPPORT_NODE, + SUPPORT_NODE = _LAST_L23VTY_NODE + 1, + TCH_VOICE_NODE, + TCH_DATA_NODE, + VGCS_NODE, + VBS_NODE, }; -int ms_vty_go_parent(struct vty *vty); int ms_vty_init(void); -extern void vty_notify(struct osmocom_ms *ms, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); - #endif diff --git a/src/host/layer23/include/osmocom/bb/modem/Makefile.am b/src/host/layer23/include/osmocom/bb/modem/Makefile.am new file mode 100644 index 00000000..2f69d195 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/Makefile.am @@ -0,0 +1,10 @@ +noinst_HEADERS = \ + modem.h \ + gmm.h \ + grr.h \ + llc.h \ + rlcmac.h \ + sm.h \ + sndcp.h \ + vty.h \ + $(NULL) diff --git a/src/host/layer23/include/osmocom/bb/modem/gmm.h b/src/host/layer23/include/osmocom/bb/modem/gmm.h new file mode 100644 index 00000000..41e1e7e6 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/gmm.h @@ -0,0 +1,13 @@ +#pragma once + +#include <stdbool.h> +#include <stdint.h> + +struct osmocom_ms; + +int modem_gmm_init(struct osmocom_ms *ms); + +int modem_gmm_gmmreg_attach_req(const struct osmocom_ms *ms); +int modem_gmm_gmmreg_detach_req(const struct osmocom_ms *ms); +int modem_gmm_gmmreg_sim_auth_rsp(const struct osmocom_ms *ms, + uint8_t *sres, uint8_t *kc, uint8_t kc_len); diff --git a/src/host/layer23/include/osmocom/bb/modem/grr.h b/src/host/layer23/include/osmocom/bb/modem/grr.h new file mode 100644 index 00000000..a86a089b --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/grr.h @@ -0,0 +1,35 @@ +#pragma once + +#include <stdbool.h> +#include <stdint.h> + +struct msgb; +struct osmocom_ms; +struct lapdm_entity; +struct osmo_fsm; + +enum grr_fsm_state { + GRR_ST_PACKET_NOT_READY, + GRR_ST_PACKET_IDLE, + GRR_ST_PACKET_ACCESS, + GRR_ST_PACKET_TRANSFER, +}; + +enum grr_fsm_event { + GRR_EV_BCCH_BLOCK_IND, + GRR_EV_PCH_AGCH_BLOCK_IND, + GRR_EV_CHAN_ACCESS_REQ, + GRR_EV_CHAN_ACCESS_CNF, + GRR_EV_PDCH_ESTABLISH_REQ, + GRR_EV_PDCH_RELEASE_REQ, + GRR_EV_PDCH_UL_TBF_CFG_REQ, + GRR_EV_PDCH_DL_TBF_CFG_REQ, + GRR_EV_PDCH_BLOCK_REQ, + GRR_EV_PDCH_BLOCK_CNF, + GRR_EV_PDCH_BLOCK_IND, + GRR_EV_PDCH_RTS_IND, +}; + +extern struct osmo_fsm grr_fsm_def; + +int modem_grr_rslms_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx); diff --git a/src/host/layer23/include/osmocom/bb/modem/llc.h b/src/host/layer23/include/osmocom/bb/modem/llc.h new file mode 100644 index 00000000..5fe5d49f --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/llc.h @@ -0,0 +1,8 @@ +#pragma once + +#include <stdbool.h> + +struct osmocom_ms; + +int modem_llc_init(struct osmocom_ms *ms, const char *cipher_plugin_path); + diff --git a/src/host/layer23/include/osmocom/bb/modem/modem.h b/src/host/layer23/include/osmocom/bb/modem/modem.h new file mode 100644 index 00000000..7135bf71 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/modem.h @@ -0,0 +1,19 @@ +#pragma once + +#include <stdbool.h> + +int modem_start(void); +int modem_gprs_attach_if_needed(struct osmocom_ms *ms); +int modem_sync_to_cell(struct osmocom_ms *ms); + +enum modem_state { + MODEM_ST_IDLE, + MODEM_ST_ATTACHING, + MODEM_ST_ATTACHED +}; + +struct modem_app { + struct osmocom_ms *ms; + enum modem_state modem_state; +}; +extern struct modem_app app_data; diff --git a/src/host/layer23/include/osmocom/bb/modem/rlcmac.h b/src/host/layer23/include/osmocom/bb/modem/rlcmac.h new file mode 100644 index 00000000..d1b054f8 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/rlcmac.h @@ -0,0 +1,8 @@ +#pragma once + +#include <stdbool.h> + +struct osmocom_ms; + +int modem_rlcmac_init(struct osmocom_ms *ms); + diff --git a/src/host/layer23/include/osmocom/bb/modem/sm.h b/src/host/layer23/include/osmocom/bb/modem/sm.h new file mode 100644 index 00000000..b1a5df5a --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/sm.h @@ -0,0 +1,8 @@ +#pragma once + +#include <stdbool.h> + +struct osmocom_ms; + +int modem_sm_init(struct osmocom_ms *ms); +int modem_sm_smreg_pdp_act_req(const struct osmocom_ms *ms, const struct osmobb_apn *apn); diff --git a/src/host/layer23/include/osmocom/bb/modem/sndcp.h b/src/host/layer23/include/osmocom/bb/modem/sndcp.h new file mode 100644 index 00000000..b2e6f0fd --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/sndcp.h @@ -0,0 +1,10 @@ +#pragma once + +#include <stdbool.h> + +struct osmocom_ms; +struct osmobb_apn; + +int modem_sndcp_init(struct osmocom_ms *ms); +int modem_sndcp_sn_xid_req(struct osmobb_apn *apn); +int modem_sndcp_sn_unitdata_req(struct osmobb_apn *apn, uint8_t *npdu, size_t npdu_len); diff --git a/src/host/layer23/include/osmocom/bb/modem/vty.h b/src/host/layer23/include/osmocom/bb/modem/vty.h new file mode 100644 index 00000000..5b69af60 --- /dev/null +++ b/src/host/layer23/include/osmocom/bb/modem/vty.h @@ -0,0 +1,10 @@ +#pragma once + +#include <osmocom/bb/common/vty.h> + +enum modem_vty_node { + APN_NODE = _LAST_L23VTY_NODE + 1, +}; + +int modem_vty_init(void); +int modem_vty_go_parent(struct vty *vty); |