summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/include/osmocom/bb
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/layer23/include/osmocom/bb')
-rw-r--r--src/host/layer23/include/osmocom/bb/Makefile.am2
-rw-r--r--src/host/layer23/include/osmocom/bb/common/Makefile.am25
-rw-r--r--src/host/layer23/include/osmocom/bb/common/apn.h82
-rw-r--r--src/host/layer23/include/osmocom/bb/common/apn_fsm.h29
-rw-r--r--src/host/layer23/include/osmocom/bb/common/gps.h4
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l1ctl.h32
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l1l2_interface.h4
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l23_app.h67
-rw-r--r--src/host/layer23/include/osmocom/bb/common/logging.h10
-rw-r--r--src/host/layer23/include/osmocom/bb/common/ms.h116
-rw-r--r--src/host/layer23/include/osmocom/bb/common/networks.h23
-rw-r--r--src/host/layer23/include/osmocom/bb/common/osmocom_data.h144
-rw-r--r--src/host/layer23/include/osmocom/bb/common/settings.h348
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sim.h66
-rw-r--r--src/host/layer23/include/osmocom/bb/common/subscriber.h (renamed from src/host/layer23/include/osmocom/bb/mobile/subscriber.h)104
-rw-r--r--src/host/layer23/include/osmocom/bb/common/support.h (renamed from src/host/layer23/include/osmocom/bb/mobile/support.h)10
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sysinfo.h125
-rw-r--r--src/host/layer23/include/osmocom/bb/common/vty.h35
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/Makefile.am9
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/cell_log.h4
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/geo.h12
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/locate.h8
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/log.h84
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/Makefile.am6
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/app_mobile.h4
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gapk_io.h47
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm322.h42
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm44068_gcc_bcc.h43
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h105
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h48
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/mncc.h39
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/mncc_ms.h35
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/settings.h125
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/tch.h28
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/transaction.h24
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/voice.h7
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/vty.h13
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/Makefile.am10
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/gmm.h13
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/grr.h35
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/llc.h8
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/modem.h19
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/rlcmac.h8
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/sm.h8
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/sndcp.h10
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/vty.h10
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);