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.am1
-rw-r--r--src/host/layer23/include/osmocom/bb/common/Makefile.am2
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l1ctl.h48
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l1l2_interface.h8
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l23_app.h10
-rw-r--r--src/host/layer23/include/osmocom/bb/common/lapdm.h100
-rw-r--r--src/host/layer23/include/osmocom/bb/common/logging.h25
-rw-r--r--src/host/layer23/include/osmocom/bb/common/networks.h22
-rw-r--r--src/host/layer23/include/osmocom/bb/common/osmocom_data.h84
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/Makefile.am1
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/layer3.h14
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/rslms.h23
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/Makefile.am2
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm322.h202
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h18
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h228
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h179
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/mncc.h166
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/settings.h42
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/subscriber.h89
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/support.h94
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/sysinfo.h121
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/transaction.h71
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/vty.h19
24 files changed, 1569 insertions, 0 deletions
diff --git a/src/host/layer23/include/osmocom/bb/Makefile.am b/src/host/layer23/include/osmocom/bb/Makefile.am
new file mode 100644
index 00000000..58a5f7fb
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = common misc mobile
diff --git a/src/host/layer23/include/osmocom/bb/common/Makefile.am b/src/host/layer23/include/osmocom/bb/common/Makefile.am
new file mode 100644
index 00000000..fa467575
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/Makefile.am
@@ -0,0 +1,2 @@
+noinst_HEADERS = l1ctl.h l1l2_interface.h l23_app.h lapdm.h logging.h networks.h \
+ osmocom_data.h
diff --git a/src/host/layer23/include/osmocom/bb/common/l1ctl.h b/src/host/layer23/include/osmocom/bb/common/l1ctl.h
new file mode 100644
index 00000000..75551abe
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/l1ctl.h
@@ -0,0 +1,48 @@
+#ifndef osmocom_l1ctl_h
+#define osmocom_l1ctl_h
+
+#include <osmocore/msgb.h>
+#include <osmocom/bb/common/osmocom_data.h>
+
+struct osmocom_ms;
+
+/* Receive incoming data from L1 using L1CTL format */
+int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg);
+
+/* Transmit L1CTL_DATA_REQ */
+int tx_ph_data_req(struct osmocom_ms *ms, struct msgb *msg, uint8_t chan_nr,
+ uint8_t link_id);
+
+/* Transmit L1CTL_PARAM_REQ */
+int l1ctl_tx_ph_param_req(struct osmocom_ms *ms, uint8_t ta, uint8_t tx_power);
+
+/* Transmit L1CTL_RACH_REQ */
+int tx_ph_rach_req(struct osmocom_ms *ms, uint8_t ra, uint8_t fn51,
+ uint8_t mf_off);
+
+/* Transmit L1CTL_DM_EST_REQ */
+int tx_ph_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
+ uint8_t chan_nr, uint8_t tsc);
+int tx_ph_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);
+
+/* Transmit L1CTL_DM_REL_REQ */
+int tx_ph_dm_rel_req(struct osmocom_ms *ms);
+
+/* Transmit FBSB_REQ */
+int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn,
+ uint8_t flags, uint16_t timeout, uint8_t sync_info_idx,
+ uint8_t ccch_mode);
+
+int l1ctl_tx_ccch_mode_req(struct osmocom_ms *ms, uint8_t ccch_mode);
+
+int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len);
+
+/* Transmit L1CTL_RESET_REQ */
+int l1ctl_tx_reset_req(struct osmocom_ms *ms, uint8_t type);
+
+/* Transmit L1CTL_PM_REQ */
+int l1ctl_tx_pm_req_range(struct osmocom_ms *ms, uint16_t arfcn_from,
+ uint16_t arfcm_to);
+
+#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
new file mode 100644
index 00000000..41403d87
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h
@@ -0,0 +1,8 @@
+#ifndef _L1L2_INTERFACE_H
+#define _L1L2_INTERFACE_H
+
+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);
+
+#endif /* _L1L2_INTERFACE_H */
diff --git a/src/host/layer23/include/osmocom/bb/common/l23_app.h b/src/host/layer23/include/osmocom/bb/common/l23_app.h
new file mode 100644
index 00000000..1a228567
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/l23_app.h
@@ -0,0 +1,10 @@
+#ifndef _L23_APP_H
+#define _L23_APP_H
+
+/* 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);
+
+#endif /* _L23_APP_H */
diff --git a/src/host/layer23/include/osmocom/bb/common/lapdm.h b/src/host/layer23/include/osmocom/bb/common/lapdm.h
new file mode 100644
index 00000000..ab048b8a
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/lapdm.h
@@ -0,0 +1,100 @@
+#ifndef _OSMOCOM_LAPDM_H
+#define _OSMOCOM_LAPDM_H
+
+#include <stdint.h>
+
+#include <osmocore/timer.h>
+#include <osmocore/msgb.h>
+
+#include <l1a_l23_interface.h>
+
+enum lapdm_state {
+ LAPDm_STATE_NULL = 0,
+ LAPDm_STATE_IDLE,
+ LAPDm_STATE_SABM_SENT,
+ LAPDm_STATE_MF_EST,
+ LAPDm_STATE_TIMER_RECOV,
+ LAPDm_STATE_DISC_SENT,
+};
+
+struct lapdm_entity;
+struct osmocom_ms;
+
+struct lapdm_msg_ctx {
+ struct lapdm_datalink *dl;
+ int lapdm_fmt;
+ uint8_t n201;
+ uint8_t chan_nr;
+ uint8_t link_id;
+ uint8_t addr;
+ uint8_t ctrl;
+ uint8_t ta_ind;
+ uint8_t tx_power_ind;
+};
+
+/* TS 04.06 / Section 3.5.2 */
+struct lapdm_datalink {
+ uint8_t V_send; /* seq nr of next I frame to be transmitted */
+ uint8_t V_ack; /* last frame ACKed by peer */
+ uint8_t N_send; /* ? set to V_send at Tx time*/
+ uint8_t V_recv; /* seq nr of next I frame expected to be received */
+ uint8_t N_recv; /* expected send seq nr of the next received I frame */
+ uint32_t state;
+ int seq_err_cond; /* condition of sequence error */
+ uint8_t own_busy, peer_busy;
+ struct timer_list t200;
+ uint8_t retrans_ctr;
+ struct llist_head send_queue; /* frames from L3 */
+ struct msgb *send_buffer; /* current frame transmitting */
+ int send_out; /* how much was sent from send_buffer */
+ uint8_t tx_hist[8][200]; /* tx history buffer */
+ int tx_length[8]; /* length in history buffer */
+ struct llist_head tx_queue; /* frames to L1 */
+ struct lapdm_msg_ctx mctx; /* context of established connection */
+ struct msgb *rcv_buffer; /* buffer to assemble the received message */
+
+ struct lapdm_entity *entity;
+};
+
+enum lapdm_dl_sapi {
+ DL_SAPI0 = 0,
+ DL_SAPI3 = 1,
+ _NR_DL_SAPI
+};
+
+struct lapdm_entity {
+ struct lapdm_datalink datalink[_NR_DL_SAPI];
+ int last_tx_dequeue; /* last entity that was dequeued */
+ int tx_pending; /* currently a pending frame not confirmed by L1 */
+ struct osmocom_ms *ms;
+};
+
+const char *get_rsl_name(int value);
+extern const char *lapdm_state_names[];
+
+/* initialize a LAPDm entity */
+void lapdm_init(struct lapdm_entity *le, struct osmocom_ms *ms);
+
+/* deinitialize a LAPDm entity */
+void lapdm_exit(struct lapdm_entity *le);
+
+/* input into layer2 (from layer 1) */
+int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, struct l1ctl_info_dl *l1i);
+int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le);
+
+/* L1 confirms channel request */
+int l2_ph_chan_conf(struct msgb *msg, struct osmocom_ms *ms,
+ struct l1ctl_info_dl *dl);
+
+/* input into layer2 (from layer 3) */
+int rslms_recvmsg(struct msgb *msg, struct osmocom_ms *ms);
+
+/* sending messages up from L2 to L3 */
+int rslms_sendmsg(struct msgb *msg, struct osmocom_ms *ms);
+
+typedef int (*osmol2_cb_t)(struct msgb *msg, struct osmocom_ms *ms);
+
+/* register message handler for messages that are sent from L2->L3 */
+int osmol2_register_handler(struct osmocom_ms *ms, osmol2_cb_t cb);
+
+#endif /* _OSMOCOM_LAPDM_H */
diff --git a/src/host/layer23/include/osmocom/bb/common/logging.h b/src/host/layer23/include/osmocom/bb/common/logging.h
new file mode 100644
index 00000000..1a11cf9d
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/logging.h
@@ -0,0 +1,25 @@
+#ifndef _LOGGING_H
+#define _LOGGING_H
+
+#define DEBUG
+#include <osmocore/logging.h>
+
+enum {
+ DRSL,
+ DRR,
+ DPLMN,
+ DCS,
+ DMM,
+ DCC,
+ DSMS,
+ DMNCC,
+ DMEAS,
+ DPAG,
+ DLAPDM,
+ DL1C,
+ DSUM,
+};
+
+extern const struct log_info log_info;
+
+#endif /* _LOGGING_H */
diff --git a/src/host/layer23/include/osmocom/bb/common/networks.h b/src/host/layer23/include/osmocom/bb/common/networks.h
new file mode 100644
index 00000000..e8c1b18e
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/networks.h
@@ -0,0 +1,22 @@
+#ifndef _NETWORKS_H
+#define _NETWORKS_H
+
+struct gsm_networks {
+ uint16_t mcc;
+ int16_t mnc;
+ const char *name;
+};
+
+int gsm_match_mcc(uint16_t mcc, char *imsi);
+int gsm_match_mnc(uint16_t mcc, uint8_t mnc, char *imsi);
+const char *gsm_print_mcc(uint16_t mcc);
+const char *gsm_print_mnc(uint16_t mcc);
+const char *gsm_get_mcc(uint16_t mcc);
+const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc);
+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);
+
+#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
new file mode 100644
index 00000000..dc7ba11d
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
@@ -0,0 +1,84 @@
+#ifndef osmocom_data_h
+#define osmocom_data_h
+
+#include <osmocore/select.h>
+#include <osmocore/gsm_utils.h>
+#include <osmocore/write_queue.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/bb/common/lapdm.h>
+#include <osmocom/bb/mobile/gsm48_rr.h>
+#include <osmocom/bb/mobile/sysinfo.h>
+#include <osmocom/bb/mobile/gsm322.h>
+#include <osmocom/bb/mobile/gsm48_mm.h>
+#include <osmocom/bb/mobile/gsm48_cc.h>
+
+/* A layer2 entity */
+struct osmol2_entity {
+ struct lapdm_entity lapdm_dcch;
+ struct lapdm_entity lapdm_acch;
+ osmol2_cb_t msg_handler;
+};
+
+/* RX measurement statistics */
+struct rx_meas_stat {
+ uint32_t frames;
+ uint32_t berr;
+ uint32_t rxlev;
+};
+
+/* One Mobilestation for osmocom */
+struct osmocom_ms {
+ struct llist_head entity;
+ char name[32];
+ struct write_queue wq;
+ uint16_t test_arfcn;
+
+ struct gsm_support support;
+
+ struct gsm_settings settings;
+
+ struct gsm_subscriber subscr;
+
+ struct osmol2_entity l2_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 llist_head trans_list;
+};
+
+enum osmobb_sig_subsys {
+ SS_L1CTL,
+};
+
+enum osmobb_meas_sig {
+ S_L1CTL_FBSB_ERR,
+ S_L1CTL_FBSB_RESP,
+ S_L1CTL_RESET,
+ S_L1CTL_PM_RES,
+ S_L1CTL_PM_DONE,
+ S_L1CTL_CCCH_MODE_CONF,
+};
+
+struct osmobb_meas_res {
+ struct osmocom_ms *ms;
+ uint16_t band_arfcn;
+ uint8_t rx_lev;
+};
+
+struct osmobb_ccch_mode_conf {
+ struct osmocom_ms *ms;
+ uint8_t ccch_mode;
+};
+
+#endif
diff --git a/src/host/layer23/include/osmocom/bb/misc/Makefile.am b/src/host/layer23/include/osmocom/bb/misc/Makefile.am
new file mode 100644
index 00000000..71c9d389
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/misc/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS = layer3.h rslms.h
diff --git a/src/host/layer23/include/osmocom/bb/misc/layer3.h b/src/host/layer23/include/osmocom/bb/misc/layer3.h
new file mode 100644
index 00000000..dc7da87f
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/misc/layer3.h
@@ -0,0 +1,14 @@
+#ifndef _OSMOCOM_L3_H
+#define _OSMOCOM_L3_H
+
+#include <osmocore/msgb.h>
+#include <osmocom/bb/common/osmocom_data.h>
+
+int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms);
+int gsm48_rx_dcch(struct msgb *msg, struct osmocom_ms *ms);
+int gsm48_rx_bcch(struct msgb *msg, struct osmocom_ms *ms);
+
+/* Initialize layer3 for the MS, hook it to L2 */
+int layer3_init(struct osmocom_ms *ms);
+
+#endif
diff --git a/src/host/layer23/include/osmocom/bb/misc/rslms.h b/src/host/layer23/include/osmocom/bb/misc/rslms.h
new file mode 100644
index 00000000..8b62ba92
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/misc/rslms.h
@@ -0,0 +1,23 @@
+#ifndef _OSMOCOM_RSLMS_H
+#define _OSMOCOM_RSLMS_H
+
+#include <osmocore/msgb.h>
+#include <osmocom/bb/common/osmocom_data.h>
+
+/* From L3 into RSLMS (direction -> L2) */
+
+/* Send a 'simple' RLL request to L2 */
+int rslms_tx_rll_req(struct osmocom_ms *ms, uint8_t msg_type,
+ uint8_t chan_nr, uint8_t link_id);
+
+/* Send a RLL request (including L3 info) to L2 */
+int rslms_tx_rll_req_l3(struct osmocom_ms *ms, uint8_t msg_type,
+ uint8_t chan_nr, uint8_t link_id, struct msgb *msg);
+
+
+/* From L2 into RSLMS (direction -> L3) */
+
+/* input function that L2 calls when sending messages up to L3 */
+//int rslms_sendmsg(struct msgb *msg, struct osmocom_ms *ms);
+
+#endif /* _OSMOCOM_RSLMS_H */
diff --git a/src/host/layer23/include/osmocom/bb/mobile/Makefile.am b/src/host/layer23/include/osmocom/bb/mobile/Makefile.am
new file mode 100644
index 00000000..49c8378b
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/Makefile.am
@@ -0,0 +1,2 @@
+noinst_HEADERS = gsm322.h gsm48_cc.h gsm48_mm.h gsm48_rr.h mncc.h settings.h \
+ subscriber.h support.h sysinfo.h transaction.h
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm322.h b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h
new file mode 100644
index 00000000..78e380fe
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h
@@ -0,0 +1,202 @@
+#ifndef _GSM322_H
+#define _GSM322_H
+
+/* 4.3.1.1 List of states for PLMN slection process (automatic mode) */
+#define GSM322_A0_NULL 0
+#define GSM322_A1_TRYING_RPLMN 1
+#define GSM322_A2_ON_PLMN 2
+#define GSM322_A3_TRYING_PLMN 3
+#define GSM322_A4_WAIT_FOR_PLMN 4
+#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) */
+#define GSM322_M0_NULL 0
+#define GSM322_M1_TRYING_RPLMN 1
+#define GSM322_M2_ON_PLMN 2
+#define GSM322_M3_NOT_ON_PLMN 3
+#define GSM322_M4_TRYING_PLMN 4
+#define GSM322_M5_NO_SIM 5
+
+/* 4.3.2 List of states for cell selection process */
+#define GSM322_C0_NULL 0
+#define GSM322_C1_NORMAL_CELL_SEL 1
+#define GSM322_C2_STORED_CELL_SEL 2
+#define GSM322_C3_CAMPED_NORMALLY 3
+#define GSM322_C4_NORMAL_CELL_RESEL 4
+#define GSM322_C5_CHOOSE_CELL 5
+#define GSM322_C6_ANY_CELL_SEL 6
+#define GSM322_C7_CAMPED_ANY_CELL 7
+#define GSM322_C8_ANY_CELL_RESEL 8
+#define GSM322_C9_CHOOSE_ANY_CELL 9
+#define GSM322_PLMN_SEARCH 10
+#define GSM322_HPLMN_SEARCH 11
+
+/* GSM 03.22 events */
+#define GSM322_EVENT_SWITCH_ON 1
+#define GSM322_EVENT_SWITCH_OFF 2
+#define GSM322_EVENT_SIM_INSERT 3
+#define GSM322_EVENT_SIM_REMOVE 4
+#define GSM322_EVENT_REG_SUCCESS 5
+#define GSM322_EVENT_REG_FAILED 6
+#define GSM322_EVENT_ROAMING_NA 7
+#define GSM322_EVENT_INVALID_SIM 8
+#define GSM322_EVENT_NEW_PLMN 9
+#define GSM322_EVENT_ON_PLMN 10
+#define GSM322_EVENT_PLMN_SEARCH_START 11
+#define GSM322_EVENT_PLMN_SEARCH_END 12
+#define GSM322_EVENT_USER_RESEL 13
+#define GSM322_EVENT_PLMN_AVAIL 14
+#define GSM322_EVENT_CHOOSE_PLMN 15
+#define GSM322_EVENT_SEL_MANUAL 16
+#define GSM322_EVENT_SEL_AUTO 17
+#define GSM322_EVENT_CELL_FOUND 18
+#define GSM322_EVENT_NO_CELL_FOUND 19
+#define GSM322_EVENT_LEAVE_IDLE 20
+#define GSM322_EVENT_RET_IDLE 21
+#define GSM322_EVENT_CELL_RESEL 22
+#define GSM322_EVENT_SYSINFO 23
+#define GSM322_EVENT_HPLMN_SEARCH 24
+
+enum {
+ PLMN_MODE_MANUAL,
+ PLMN_MODE_AUTO
+};
+
+/* node for each PLMN */
+struct gsm322_plmn_list {
+ struct llist_head entry;
+ uint16_t mcc, mnc;
+ int8_t rxlev; /* rx level in range format */
+ uint8_t cause; /* cause value, if PLMN is not allowed */
+};
+
+/* node for each forbidden LA */
+struct gsm322_la_list {
+ struct llist_head entry;
+ uint16_t mcc, mnc, lac;
+ uint8_t cause;
+};
+
+/* node for each BA-List */
+struct gsm322_ba_list {
+ struct llist_head entry;
+ uint16_t mcc, mnc;
+ /* Band allocation for 1024 frequencies.
+ * First bit of first index is frequency 0.
+ */
+ uint8_t freq[128];
+};
+
+#define GSM322_CS_FLAG_SUPPORT 0x01 /* frequency is supported by radio */
+#define GSM322_CS_FLAG_BA 0x02 /* frequency is part of the current ba */
+#define GSM322_CS_FLAG_POWER 0x04 /* frequency was power scanned */
+#define GSM322_CS_FLAG_SIGNAL 0x08 /* valid signal detected */
+#define GSM322_CS_FLAG_SYSINFO 0x10 /* complete sysinfo received */
+#define GSM322_CS_FLAG_BARRED 0x20 /* cell is barred */
+#define GSM322_CS_FLAG_FORBIDD 0x40 /* cell in list of forbidden LAs */
+#define GSM322_CS_FLAG_TEMP_AA 0x80 /* if temporary available and allowable */
+
+/* Cell selection list */
+struct gsm322_cs_list {
+ uint8_t flags; /* see GSM322_CS_FLAG_* */
+ int8_t rxlev; /* rx level range format */
+ struct gsm48_sysinfo *sysinfo;
+#if 0
+ int8_t min_dbm; /* minimum level to enter cell */
+ int8_t max_pwr; /* maximum power to access cell */
+ uint16_t class_barr; /* barred classes */
+ uint16_t mcc, mnc, lac; /* received mcc, mnc, lac */
+#endif
+};
+
+/* PLMN search process */
+struct gsm322_plmn {
+ struct osmocom_ms *ms;
+ int state; /* GSM322_Ax_* or GSM322_Mx_* */
+
+ struct llist_head event_queue; /* event messages */
+ struct llist_head sorted_plmn; /* list of sorted PLMN */
+ struct llist_head forbidden_la; /* forbidden LAs */
+
+ struct timer_list timer;
+
+ int plmn_curr; /* current index in sorted_plmn */
+ uint16_t mcc, mnc; /* 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_SYNC 2 /* got sync */
+#define GSM322_CCCH_ST_DATA 3 /* receiveing data */
+
+struct gsm48_sysinfo;
+/* Cell selection process */
+struct gsm322_cellsel {
+ struct osmocom_ms *ms;
+ int state; /* GSM322_Cx_* */
+
+ struct llist_head event_queue; /* event messages */
+ struct llist_head ba_list; /* BCCH Allocation per PLMN */
+
+ struct timer_list timer;
+
+ uint16_t mcc, mnc; /* current network to search for */
+ struct gsm322_cs_list list[1024]; /* cell selection list per freq. */
+
+ uint8_t powerscan; /* currently scanning for power */
+ uint32_t scan_state; /* special state of current scan */
+ uint8_t ccch_state; /* special state of current ccch */
+ uint16_t arfcn; /* current tuned idle mode arfcn */
+ uint8_t ccch_mode; /* curren CCCH_MODE_* */
+ struct gsm48_sysinfo *si; /* current sysinfo */
+
+ uint8_t selected; /* if a cell is selected */
+ uint16_t sel_arfcn;
+ struct gsm48_sysinfo sel_si; /* copy of selected cell, will update */
+ uint16_t sel_mcc, sel_mnc, sel_lac, sel_id;
+};
+
+/* GSM 03.22 message */
+struct gsm322_msg {
+ int msg_type;
+ uint16_t mcc, mnc;
+ uint8_t sysinfo; /* system information type */
+ uint8_t same_cell; /* select same cell when RET_IDLE */
+ uint8_t reject; /* location update reject cause */
+};
+
+#define GSM322_ALLOC_SIZE sizeof(struct gsm322_msg)
+#define GSM322_ALLOC_HEADROOM 0
+
+int gsm322_init(struct osmocom_ms *ms);
+int gsm322_exit(struct osmocom_ms *ms);
+struct msgb *gsm322_msgb_alloc(int msg_type);
+int gsm322_plmn_sendmsg(struct osmocom_ms *ms, struct msgb *msg);
+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_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,
+ void (*print)(void *, const char *, ...), void *priv);
+void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro);
+void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro);
+extern const char *plmn_a_state_names[];
+extern const char *plmn_m_state_names[];
+extern const char *cs_state_names[];
+
+char *gsm_print_rxlev(uint8_t rxlev);
+
+#endif /* _GSM322_H */
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h
new file mode 100644
index 00000000..d6ea5756
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h
@@ -0,0 +1,18 @@
+#ifndef _GSM48_CC_H
+#define _GSM48_CC_H
+
+struct gsm48_cclayer {
+ struct osmocom_ms *ms;
+
+ struct llist_head mncc_upqueue;
+ int (*mncc_recv)(struct osmocom_ms *, int, void *);
+};
+
+int gsm48_cc_init(struct osmocom_ms *ms);
+int gsm48_cc_exit(struct osmocom_ms *ms);
+int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg);
+int mncc_dequeue(struct osmocom_ms *ms);
+int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg);
+
+#endif /* _GSM48_CC_H */
+
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
new file mode 100644
index 00000000..b988bd9a
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
@@ -0,0 +1,228 @@
+#ifndef _GSM48_MM_H
+#define _GSM48_MM_H
+
+/* 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_MMCC_EST_REQ 0x110
+#define GSM48_MMCC_EST_IND 0x112
+#define GSM48_MMCC_EST_CNF 0x111
+#define GSM48_MMCC_REL_REQ 0x120
+#define GSM48_MMCC_REL_IND 0x122
+#define GSM48_MMCC_DATA_REQ 0x130
+#define GSM48_MMCC_DATA_IND 0x132
+#define GSM48_MMCC_UNIT_DATA_REQ 0x140
+#define GSM48_MMCC_UNIT_DATA_IND 0x142
+#define GSM48_MMCC_SYNC_IND 0x152
+#define GSM48_MMCC_REEST_REQ 0x160
+#define GSM48_MMCC_REEST_CNF 0x161
+#define GSM48_MMCC_ERR_IND 0x172
+#define GSM48_MMCC_PROMPT_IND 0x182
+#define GSM48_MMCC_PROMPT_REJ 0x184
+#define GSM48_MMSS_EST_REQ 0x210
+#define GSM48_MMSS_EST_IND 0x212
+#define GSM48_MMSS_EST_CNF 0x211
+#define GSM48_MMSS_REL_REQ 0x220
+#define GSM48_MMSS_REL_IND 0x222
+#define GSM48_MMSS_DATA_REQ 0x230
+#define GSM48_MMSS_DATA_IND 0x232
+#define GSM48_MMSS_UNIT_DATA_REQ 0x240
+#define GSM48_MMSS_UNIT_DATA_IND 0x242
+#define GSM48_MMSS_REEST_REQ 0x260
+#define GSM48_MMSS_REEST_CNF 0x261
+#define GSM48_MMSS_ERR_IND 0x272
+#define GSM48_MMSS_PROMPT_IND 0x282
+#define GSM48_MMSS_PROMPT_REJ 0x284
+#define GSM48_MMSMS_EST_REQ 0x310
+#define GSM48_MMSMS_EST_IND 0x312
+#define GSM48_MMSMS_EST_CNF 0x311
+#define GSM48_MMSMS_REL_REQ 0x320
+#define GSM48_MMSMS_REL_IND 0x322
+#define GSM48_MMSMS_DATA_REQ 0x330
+#define GSM48_MMSMS_DATA_IND 0x332
+#define GSM48_MMSMS_UNIT_DATA_REQ 0x340
+#define GSM48_MMSMS_UNIT_DATA_IND 0x342
+#define GSM48_MMSMS_REEST_REQ 0x360
+#define GSM48_MMSMS_REEST_CNF 0x361
+#define GSM48_MMSMS_ERR_IND 0x372
+#define GSM48_MMSMS_PROMPT_IND 0x382
+#define GSM48_MMSMS_PROMPT_REJ 0x384
+
+#define MMXX_ALLOC_SIZE 256
+#define MMXX_ALLOC_HEADROOM 64
+
+/* 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 emergency; /* emergency type of call */
+ uint8_t cause; /* cause used for release */
+};
+
+/* GSM 6.1.2 */
+#define GSM48_MMR_REG_REQ 0x01
+#define GSM48_MMR_REG_CNF 0x02
+#define GSM48_MMR_NREG_REQ 0x03
+#define GSM48_MMR_NREG_IND 0x04
+
+/* MMR-SAP header */
+struct gsm48_mmr {
+ int msg_type;
+
+ uint8_t cause;
+};
+
+/* GSM 04.07 9.2.1 */
+#define GSM48_MMXX_ST_IDLE 0
+#define GSM48_MMXX_ST_CONN_PEND 1
+#define GSM48_MMXX_ST_DEDICATED 2
+#define GSM48_MMXX_ST_CONN_SUSP 3
+#define GSM48_MMXX_ST_REESTPEND 4
+
+/* GSM 04.08 4.1.2.1 */
+#define GSM48_MM_ST_NULL 0
+#define GSM48_MM_ST_LOC_UPD_INIT 3
+#define GSM48_MM_ST_WAIT_OUT_MM_CONN 5
+#define GSM48_MM_ST_MM_CONN_ACTIVE 6
+#define GSM48_MM_ST_IMSI_DETACH_INIT 7
+#define GSM48_MM_ST_PROCESS_CM_SERV_P 8
+#define GSM48_MM_ST_WAIT_NETWORK_CMD 9
+#define GSM48_MM_ST_LOC_UPD_REJ 10
+#define GSM48_MM_ST_WAIT_RR_CONN_LUPD 13
+#define GSM48_MM_ST_WAIT_RR_CONN_MM_CON 14
+#define GSM48_MM_ST_WAIT_RR_CONN_IMSI_D 15
+#define GSM48_MM_ST_WAIT_REEST 17
+#define GSM48_MM_ST_WAIT_RR_ACTIVE 18
+#define GSM48_MM_ST_MM_IDLE 19
+#define GSM48_MM_ST_WAIT_ADD_OUT_MM_CON 20
+#define GSM48_MM_ST_MM_CONN_ACTIVE_VGCS 21
+#define GSM48_MM_ST_WAIT_RR_CONN_VGCS 22
+#define GSM48_MM_ST_LOC_UPD_PEND 23
+#define GSM48_MM_ST_IMSI_DETACH_PEND 24
+#define GSM48_MM_ST_RR_CONN_RELEASE_NA 25
+
+/* GSM 04.08 4.1.2.1 */
+#define GSM48_MM_SST_NORMAL_SERVICE 1
+#define GSM48_MM_SST_ATTEMPT_UPDATE 2
+#define GSM48_MM_SST_LIMITED_SERVICE 3
+#define GSM48_MM_SST_NO_IMSI 4
+#define GSM48_MM_SST_NO_CELL_AVAIL 5
+#define GSM48_MM_SST_LOC_UPD_NEEDED 6
+#define GSM48_MM_SST_PLMN_SEARCH 7
+#define GSM48_MM_SST_PLMN_SEARCH_NORMAL 8
+#define GSM48_MM_SST_RX_VGCS_NORMAL 9
+#define GSM48_MM_SST_RX_VGCS_LIMITED 10
+
+/* MM events */
+#define GSM48_MM_EVENT_CELL_SELECTED 1
+#define GSM48_MM_EVENT_NO_CELL_FOUND 2
+#define GSM48_MM_EVENT_TIMEOUT_T3210 3
+#define GSM48_MM_EVENT_TIMEOUT_T3211 4
+#define GSM48_MM_EVENT_TIMEOUT_T3212 5
+#define GSM48_MM_EVENT_TIMEOUT_T3213 6
+#define GSM48_MM_EVENT_TIMEOUT_T3220 7
+#define GSM48_MM_EVENT_TIMEOUT_T3230 8
+#define GSM48_MM_EVENT_TIMEOUT_T3240 9
+#define GSM48_MM_EVENT_IMSI_DETACH 10
+#define GSM48_MM_EVENT_POWER_OFF 11
+#define GSM48_MM_EVENT_PAGING 12
+#define GSM48_MM_EVENT_AUTH_RESPONSE 13
+#define GSM48_MM_EVENT_SYSINFO 14
+#define GSM48_MM_EVENT_USER_PLMN_SEL 15
+
+/* message for MM events */
+struct gsm48_mm_event {
+ uint32_t msg_type;
+
+ uint8_t sres[4];
+};
+
+/* GSM 04.08 MM timers */
+#define GSM_T3210_MS 20, 0
+#define GSM_T3211_MS 15, 0
+/* T3212 is given by SYSTEM INFORMATION */
+#define GSM_T3213_MS 4, 0
+#define GSM_T3220_MS 5, 0
+#define GSM_T3230_MS 15, 0
+#define GSM_T3240_MS 10, 0
+#define GSM_T3241_MS 300, 0
+
+/* MM sublayer instance */
+struct gsm48_mmlayer {
+ struct osmocom_ms *ms;
+ int state;
+ int substate;
+
+ /* queue for RR-SAP, MMxx-SAP, MMR-SAP, events message upwards */
+ struct llist_head rr_upqueue;
+ struct llist_head mmxx_upqueue;
+ struct llist_head mmr_downqueue;
+ struct llist_head event_queue;
+
+ /* timers */
+ struct timer_list t3210, t3211, t3212, t3213;
+ struct timer_list t3220, t3230, t3240;
+ int t3212_value;
+ int start_t3211; /* remember to start timer */
+
+ /* list of MM connections */
+ struct llist_head mm_conn;
+
+ /* network name */
+ char name_short[32];
+ char name_long[32];
+
+ /* location update */
+ uint8_t lupd_pending; /* current pending loc. upd. */
+ uint8_t lupd_type; /* current coded type */
+ uint8_t lupd_attempt; /* attempt counter */
+ uint8_t lupd_ra_failure;/* random access failed */
+ 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;
+
+ /* imsi detach */
+ uint8_t delay_detach; /* do detach when possible */
+
+ /* other */
+ int mr_substate; /* rem most recent substate */
+ uint8_t power_off; /* set, if power off after detach */
+ uint8_t power_off_idle; /* waits for IDLE before po */
+};
+
+/* MM connection entry */
+struct gsm48_mm_conn {
+ struct llist_head list;
+ struct gsm48_mmlayer *mm;
+
+ /* ref and type form a unique tupple */
+ uint32_t ref; /* reference to trans */
+ uint8_t protocol;
+ uint8_t transaction_id;
+
+ int state;
+};
+
+int gsm48_mm_init(struct osmocom_ms *ms);
+int gsm48_mm_exit(struct osmocom_ms *ms);
+struct msgb *gsm48_mmr_msgb_alloc(int msg_type);
+struct msgb *gsm48_mmevent_msgb_alloc(int msg_type);
+int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg);
+int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
+int gsm48_rr_dequeue(struct osmocom_ms *ms);
+int gsm48_mmxx_dequeue(struct osmocom_ms *ms);
+int gsm48_mmr_dequeue(struct osmocom_ms *ms);
+int gsm48_mmevent_dequeue(struct osmocom_ms *ms);
+int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg);
+struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
+ uint8_t transaction_id);
+const char *get_mmr_name(int value);
+const char *get_mmxx_name(int value);
+extern const char *gsm48_mm_state_names[];
+extern const char *gsm48_mm_substate_names[];
+
+#endif /* _GSM48_MM_H */
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
new file mode 100644
index 00000000..f5d52206
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
@@ -0,0 +1,179 @@
+#ifndef _GSM48_RR_H
+#define _GSM48_RR_H
+
+#include "osmocore/protocol/gsm_04_08.h"
+
+#define GSM_TA_CM 55385
+
+/* GSM 04.07 9.1.2 */
+#define GSM48_RR_EST_REQ 0x10
+#define GSM48_RR_EST_IND 0x12
+#define GSM48_RR_EST_CNF 0x11
+#define GSM48_RR_REL_IND 0x22
+#define GSM48_RR_SYNC_IND 0x32
+#define GSM48_RR_DATA_REQ 0x40
+#define GSM48_RR_DATA_IND 0x42
+#define GSM48_RR_UNIT_DATA_IND 0x52
+#define GSM48_RR_ABORT_REQ 0x60
+#define GSM48_RR_ABORT_IND 0x62
+#define GSM48_RR_ACT_REQ 0x70
+
+#define RR_EST_CAUSE_EMERGENCY 1
+#define RR_EST_CAUSE_REESTAB_TCH_F 2
+#define RR_EST_CAUSE_REESTAB_TCH_H 3
+#define RR_EST_CAUSE_REESTAB_2_TCH_H 4
+#define RR_EST_CAUSE_ANS_PAG_ANY 5
+#define RR_EST_CAUSE_ANS_PAG_SDCCH 6
+#define RR_EST_CAUSE_ANS_PAG_TCH_F 7
+#define RR_EST_CAUSE_ANS_PAG_TCH_ANY 8
+#define RR_EST_CAUSE_ORIG_TCHF 9
+#define RR_EST_CAUSE_LOC_UPD 12
+#define RR_EST_CAUSE_OTHER_SDCCH 13
+
+#define RR_REL_CAUSE_UNDEFINED 0
+#define RR_REL_CAUSE_NORMAL 1
+#define RR_REL_CAUSE_NOT_AUTHORIZED 2
+#define RR_REL_CAUSE_RA_FAILURE 3
+#define RR_REL_CAUSE_T3122 4
+#define RR_REL_CAUSE_TRY_LATER 5
+#define RR_REL_CAUSE_EMERGENCY_ONLY 6
+#define RR_REL_CAUSE_LOST_SIGNAL 7
+
+#define L3_ALLOC_SIZE 256
+#define L3_ALLOC_HEADROOM 64
+
+#define RSL_ALLOC_SIZE 256
+#define RSL_ALLOC_HEADROOM 64
+
+#define RR_ALLOC_SIZE 256
+#define RR_ALLOC_HEADROOM 64
+
+/* GSM 04.08 RR-SAP header */
+struct gsm48_rr_hdr {
+ uint32_t msg_type; /* RR-* primitive */
+ uint8_t cause;
+};
+
+/* GSM 04.07 9.1.1 */
+#define GSM48_RR_ST_IDLE 0
+#define GSM48_RR_ST_CONN_PEND 1
+#define GSM48_RR_ST_DEDICATED 2
+#define GSM48_RR_ST_REL_PEND 3
+
+/* channel description */
+struct gsm48_rr_cd {
+ uint8_t tsc;
+ uint8_t h; /* using hopping */
+ uint16_t arfcn; /* dedicated mode */
+ uint8_t maio;
+ uint8_t hsn;
+ uint8_t chan_nr; /* type, slot, sub slot */
+ uint8_t link_id;
+ uint8_t ta; /* timing advance */
+ uint8_t mob_alloc_lv[9]; /* len + up to 64 bits */
+ uint8_t start_t1, start_t2, start_t3; /* start. time */
+};
+
+/* measurements */
+struct gsm48_rr_meas {
+ uint8_t rxlev_full;
+ uint8_t rxlev_sub;
+ uint8_t rxqual_full;
+ uint8_t rxqual_sub;
+ uint8_t dtx;
+ uint8_t ba;
+ uint8_t meas_valid;
+ uint8_t ncell_na;
+ uint8_t count;
+ uint8_t rxlev_nc[6];
+ uint8_t bsic_nc[6];
+ uint8_t bcch_f_nc[6];
+};
+
+struct gsm48_cr_hist {
+ uint8_t valid;
+ struct gsm48_req_ref ref;
+};
+
+/* RR sublayer instance */
+struct gsm48_rrlayer {
+ struct osmocom_ms *ms;
+ int state;
+
+ /* queue for RSL-SAP message upwards */
+ struct llist_head rsl_upqueue;
+
+ /* queue for messages while RR connection is built up */
+ struct llist_head downqueue;
+
+ /* timers */
+ struct timer_list t_rel_wait; /* wait for L2 to transmit UA */
+ struct timer_list t3110;
+ struct timer_list t3122;
+ struct timer_list t3124;
+ struct timer_list t3126;
+ int t3126_value;
+#ifndef TODO
+ struct timer_list temp_rach_ti; /* temporary timer */
+#endif
+
+ /* states if RR-EST-REQ was used */
+ uint8_t rr_est_req;
+ struct msgb *rr_est_msg;
+ uint8_t est_cause; /* cause used for establishment */
+
+ /* 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_mask; /* mask of random bits */
+
+ /* cr_hist */
+ uint8_t cr_ra; /* stores requested ra until confirmed */
+ struct gsm48_cr_hist cr_hist[3];
+
+ /* current channel descriptions */
+ struct gsm48_rr_cd cd_now;
+
+ /* current cipering */
+ uint8_t cipher_on;
+ uint8_t cipher_type; /* 10.5.2.9 */
+
+ /* special states when changing channel */
+ uint8_t hando_susp_state;
+ uint8_t assign_susp_state;
+ uint8_t resume_last_state;
+ struct gsm48_rr_cd cd_last;
+
+ /* measurements */
+ struct gsm48_rr_meas meas;
+ uint8_t ind_tx_power; /* last indicated power */
+ uint8_t ind_ta; /* last indicated ta */
+
+ /* BA range */
+ uint8_t ba_ranges;
+ uint32_t ba_range[16];
+
+ /* monitor */
+ uint8_t monitor;
+ struct timer_list t_monitor;
+};
+
+const char *get_rr_name(int value);
+extern int gsm48_rr_init(struct osmocom_ms *ms);
+extern int gsm48_rr_exit(struct osmocom_ms *ms);
+int gsm48_rsl_dequeue(struct osmocom_ms *ms);
+int gsm48_rr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
+struct msgb *gsm48_l3_msgb_alloc(void);
+struct msgb *gsm48_rr_msgb_alloc(int msg_type);
+int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
+ uint16_t *mnc, uint16_t *lac);
+int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm);
+int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg);
+int gsm48_rr_los(struct osmocom_ms *ms);
+int gsm48_rr_rach_conf(struct osmocom_ms *ms, uint32_t fn);
+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);
+
+#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
new file mode 100644
index 00000000..d1d4d38f
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/mncc.h
@@ -0,0 +1,166 @@
+/* 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>
+ * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _MNCC_H
+#define _MNCC_H
+
+#include <osmocore/linuxlist.h>
+#include <osmocore/mncc.h>
+
+struct gsm_call {
+ struct llist_head entry;
+
+ void *ms;
+
+ uint32_t callref;
+
+ uint8_t hold; /* call on hold */
+ uint8_t ring; /* call is ringing/knocking */
+};
+
+#define MNCC_SETUP_REQ 0x0101
+#define MNCC_SETUP_IND 0x0102
+#define MNCC_SETUP_RSP 0x0103
+#define MNCC_SETUP_CNF 0x0104
+#define MNCC_SETUP_COMPL_REQ 0x0105
+#define MNCC_SETUP_COMPL_IND 0x0106
+/* MNCC_REJ_* is perfomed via MNCC_REL_* */
+#define MNCC_CALL_CONF_IND 0x0107
+#define MNCC_CALL_PROC_REQ 0x0108
+#define MNCC_PROGRESS_REQ 0x0109
+#define MNCC_ALERT_REQ 0x010a
+#define MNCC_ALERT_IND 0x010b
+#define MNCC_NOTIFY_REQ 0x010c
+#define MNCC_NOTIFY_IND 0x010d
+#define MNCC_DISC_REQ 0x010e
+#define MNCC_DISC_IND 0x010f
+#define MNCC_REL_REQ 0x0110
+#define MNCC_REL_IND 0x0111
+#define MNCC_REL_CNF 0x0112
+#define MNCC_FACILITY_REQ 0x0113
+#define MNCC_FACILITY_IND 0x0114
+#define MNCC_START_DTMF_IND 0x0115
+#define MNCC_START_DTMF_RSP 0x0116
+#define MNCC_START_DTMF_REJ 0x0117
+#define MNCC_STOP_DTMF_IND 0x0118
+#define MNCC_STOP_DTMF_RSP 0x0119
+#define MNCC_MODIFY_REQ 0x011a
+#define MNCC_MODIFY_IND 0x011b
+#define MNCC_MODIFY_RSP 0x011c
+#define MNCC_MODIFY_CNF 0x011d
+#define MNCC_MODIFY_REJ 0x011e
+#define MNCC_HOLD_IND 0x011f
+#define MNCC_HOLD_CNF 0x0120
+#define MNCC_HOLD_REJ 0x0121
+#define MNCC_RETRIEVE_IND 0x0122
+#define MNCC_RETRIEVE_CNF 0x0123
+#define MNCC_RETRIEVE_REJ 0x0124
+#define MNCC_USERINFO_REQ 0x0125
+#define MNCC_USERINFO_IND 0x0126
+#define MNCC_REJ_REQ 0x0127
+#define MNCC_REJ_IND 0x0128
+#define MNCC_PROGRESS_IND 0x0129
+#define MNCC_CALL_PROC_IND 0x012a
+#define MNCC_CALL_CONF_REQ 0x012b
+#define MNCC_START_DTMF_REQ 0x012c
+#define MNCC_STOP_DTMF_REQ 0x012d
+#define MNCC_HOLD_REQ 0x012e
+#define MNCC_RETRIEVE_REQ 0x012f
+
+#define MNCC_BRIDGE 0x0200
+#define MNCC_FRAME_RECV 0x0201
+#define MNCC_FRAME_DROP 0x0202
+#define MNCC_LCHAN_MODIFY 0x0203
+
+#define GSM_TCHF_FRAME 0x0300
+#define GSM_TCHF_FRAME_EFR 0x0301
+
+#define GSM_MAX_FACILITY 128
+#define GSM_MAX_SSVERSION 128
+#define GSM_MAX_USERUSER 128
+
+#define MNCC_F_BEARER_CAP 0x0001
+#define MNCC_F_CALLED 0x0002
+#define MNCC_F_CALLING 0x0004
+#define MNCC_F_REDIRECTING 0x0008
+#define MNCC_F_CONNECTED 0x0010
+#define MNCC_F_CAUSE 0x0020
+#define MNCC_F_USERUSER 0x0040
+#define MNCC_F_PROGRESS 0x0080
+#define MNCC_F_EMERGENCY 0x0100
+#define MNCC_F_FACILITY 0x0200
+#define MNCC_F_SSVERSION 0x0400
+#define MNCC_F_CCCAP 0x0800
+#define MNCC_F_KEYPAD 0x1000
+#define MNCC_F_SIGNAL 0x2000
+
+struct gsm_mncc {
+ /* context based information */
+ u_int32_t msg_type;
+ u_int32_t callref;
+
+ /* which fields are present */
+ u_int32_t fields;
+
+ /* data derived informations (MNCC_F_ based) */
+ struct gsm_mncc_bearer_cap bearer_cap;
+ struct gsm_mncc_number called;
+ struct gsm_mncc_number calling;
+ struct gsm_mncc_number redirecting;
+ struct gsm_mncc_number connected;
+ struct gsm_mncc_cause cause;
+ struct gsm_mncc_progress progress;
+ struct gsm_mncc_useruser useruser;
+ struct gsm_mncc_facility facility;
+ struct gsm_mncc_cccap cccap;
+ struct gsm_mncc_ssversion ssversion;
+ struct {
+ int sup;
+ int inv;
+ } clir;
+ int signal;
+
+ /* data derived information, not MNCC_F based */
+ int keypad;
+ int more;
+ int notify; /* 0..127 */
+ int emergency;
+ char imsi[16];
+
+ unsigned char lchan_mode;
+};
+
+struct gsm_data_frame {
+ u_int32_t msg_type;
+ u_int32_t callref;
+ unsigned char data[0];
+};
+
+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/settings.h b/src/host/layer23/include/osmocom/bb/mobile/settings.h
new file mode 100644
index 00000000..be13d208
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/settings.h
@@ -0,0 +1,42 @@
+#ifndef _settings_h
+#define _settings_h
+
+struct gsm_settings {
+ /* IMEI */
+ char imei[16];
+ char imeisv[17];
+ char imei_random;
+
+ /* network search */
+ int plmn_mode; /* PLMN_MODE_* */
+
+ /* SIM */
+ int simtype; /* selects card on power on */
+ char emergency_imsi[20]; /* just in case... */
+
+ /* test card simulator settings */
+ char test_imsi[20]; /* just in case... */
+ uint8_t test_barr;
+ uint8_t test_rplmn_valid;
+ uint16_t test_rplmn_mcc, test_rplmn_mnc;
+ uint8_t test_always; /* ...search hplmn... */
+
+ /* call related settings */
+ uint8_t cw; /* set if call-waiting is allowed */
+ uint8_t clip, clir;
+
+ /* 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 no_lupd;
+};
+
+int gsm_settings_init(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/subscriber.h b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
new file mode 100644
index 00000000..34f45289
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
@@ -0,0 +1,89 @@
+#ifndef _SUBSCRIBER_H
+#define _SUBSCRIBER_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
+
+struct gsm_sub_plmn_list {
+ struct llist_head entry;
+ uint16_t mcc, mnc;
+};
+
+struct gsm_sub_plmn_na {
+ struct llist_head entry;
+ uint16_t mcc, mnc;
+ uint8_t cause;
+};
+
+#define GSM_IMSI_LENGTH 16
+
+enum {
+ GSM_SIM_TYPE_NONE = 0,
+ GSM_SIM_TYPE_SLOT,
+ GSM_SIM_TYPE_TEST
+};
+
+struct gsm_subscriber {
+ struct osmocom_ms *ms;
+
+ /* status */
+ uint8_t sim_valid; /* sim inserted and valid */
+ uint8_t ustate; /* update status */
+ uint8_t imsi_attached; /* attached state */
+
+ /* LAI */
+ uint8_t lai_valid;
+ uint16_t lai_mcc, lai_mnc, lai_lac;
+
+ /* IMSI */
+ char imsi[GSM_IMSI_LENGTH];
+
+ /* TMSI */
+ uint8_t tmsi_valid;
+ uint32_t tmsi;
+
+ /* key */
+ uint8_t key_seq; /* ciphering key sequence number */
+ uint8_t key[32]; /* up to 256 bit */
+
+ /* other */
+ struct llist_head plmn_list; /* PLMN Selector field */
+ struct llist_head plmn_na; /* not allowed PLMNs */
+ uint8_t t6m_hplmn; /* timer for hplmn search */
+
+ /* special things */
+ uint8_t always_search_hplmn;
+ /* search hplmn in other countries also (for test cards) */
+ char sim_name[32]; /* name to load/save sim */
+
+ /* PLMN last registered */
+ uint8_t plmn_valid;
+ uint16_t plmn_mcc, plmn_mnc;
+
+ /* our access */
+ uint8_t acc_barr; /* if we may access, if cell barred */
+ uint16_t acc_class; /* bitmask of what we may access */
+};
+
+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);
+int gsm_subscr_remove(struct osmocom_ms *ms);
+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_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);
+
+#endif /* _SUBSCRIBER_H */
+
diff --git a/src/host/layer23/include/osmocom/bb/mobile/support.h b/src/host/layer23/include/osmocom/bb/mobile/support.h
new file mode 100644
index 00000000..9af4d1b6
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/support.h
@@ -0,0 +1,94 @@
+#ifndef _SUPPORT_H
+#define _SUPPORT_H
+
+#define GSM_CIPHER_A5_1 0
+#define GSM_CIPHER_A5_2 1
+#define GSM_CIPHER_A5_3 2
+#define GSM_CIPHER_A5_4 3
+#define GSM_CIPHER_A5_5 4
+#define GSM_CIPHER_A5_6 5
+#define GSM_CIPHER_A5_7 6
+#define GSM_CIPHER_RESERVED 7
+
+struct gsm_support {
+ struct osmocom_ms *ms;
+
+ /* rf power capability */
+ uint8_t pwr_lev_900; /* and < 900 */
+ uint8_t pwr_lev_1800; /* DCS and PCS */
+ /* controlled early classmark sending */
+ uint8_t es_ind;
+ /* revision level */
+ uint8_t rev_lev;
+ /* support of VGCS */
+ uint8_t vgcs;
+ /* support of VBS */
+ uint8_t vbs;
+ /* support of SMS */
+ uint8_t sms_ptp;
+ /* screening indicator */
+ uint8_t ss_ind;
+ /* pseudo synchronised capability */
+ uint8_t ps_cap;
+ /* CM service prompt */
+ uint8_t cmsp;
+ /* solsa support */
+ uint8_t solsa;
+ /* location service support */
+ uint8_t lcsva;
+ /* codec supprot */
+ 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;
+ /* radio support */
+ uint8_t p_gsm;
+ uint8_t e_gsm;
+ uint8_t r_gsm;
+ uint8_t r_capa;
+ uint8_t low_capa;
+ uint8_t dcs_1800;
+ uint8_t dcs_capa;
+ uint8_t freq_map[128];
+ /* multi slot support */
+ uint8_t ms_sup;
+ /* ucs2 treatment */
+ uint8_t ucs2_treat;
+ /* support extended measurements */
+ uint8_t ext_meas;
+ /* support switched measurement capability */
+ uint8_t meas_cap;
+ uint8_t sms_val;
+ uint8_t sm_val;
+ /* positioning method capability */
+ uint8_t loc_serv;
+ uint8_t e_otd_ass;
+ uint8_t e_otd_based;
+ uint8_t gps_ass;
+ uint8_t gps_based;
+ uint8_t gps_conv;
+
+ /* radio */
+ int8_t min_rxlev_db;
+ uint8_t scan_to;
+ uint8_t sync_to;
+};
+
+struct gsm_support_scan_max {
+ uint16_t start;
+ uint16_t end;
+ uint16_t max;
+ uint16_t temp;
+};
+extern struct gsm_support_scan_max gsm_sup_smax[];
+
+void gsm_support_init(struct osmocom_ms *ms);
+int gsm_support_txpwr(uint8_t tx_power, uint16_t arfcn);
+void gsm_support_dump(struct gsm_support *sup,
+ void (*print)(void *, const char *, ...), void *priv);
+
+#endif /* _SUPPORT_H */
+
diff --git a/src/host/layer23/include/osmocom/bb/mobile/sysinfo.h b/src/host/layer23/include/osmocom/bb/mobile/sysinfo.h
new file mode 100644
index 00000000..6f57fcd5
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/sysinfo.h
@@ -0,0 +1,121 @@
+#ifndef _SYSINFO_H
+#define _SYSINFO_H
+
+/* collection of system information of the current cell */
+
+/* frequency mask flags of frequency type */
+#define FREQ_TYPE_SERV 0x01 /* frequency of the serving cell */
+#define FREQ_TYPE_HOPP 0x02 /* frequency used for channel hopping */
+#define FREQ_TYPE_NCELL 0x1c /* frequency of the neighbor cell */
+#define FREQ_TYPE_NCELL_2 0x04 /* sub channel of SI 2 */
+#define FREQ_TYPE_NCELL_2bis 0x08 /* sub channel of SI 2bis */
+#define FREQ_TYPE_NCELL_2ter 0x10 /* sub channel of SI 2ter */
+#define FREQ_TYPE_REP 0xe0 /* frequency to be reported */
+#define FREQ_TYPE_REP_5 0x20 /* sub channel of SI 5 */
+#define FREQ_TYPE_REP_5bis 0x40 /* sub channel of SI 5bis */
+#define FREQ_TYPE_REP_5ter 0x80 /* sub channel of SI 5ter */
+#define FREQ_TYPE_SI_2_5 0xfc /* both SI 2 and SI 5 */
+
+/* structure of one frequency */
+struct gsm_sysinfo_freq {
+ /* if the frequency included in the sysinfo */
+ uint8_t mask;
+};
+
+/* structure of all received system informations */
+struct gsm48_sysinfo {
+ /* flags of available information */
+ uint8_t si1, si2, si2bis, si2ter, si3,
+ si4, si5, si5bis, si5ter, si6;
+
+ /* memory maps to simply detect change in system info messages */
+ uint8_t si1_msg[23];
+ uint8_t si2_msg[23];
+ uint8_t si2b_msg[23];
+ uint8_t si2t_msg[23];
+ uint8_t si3_msg[23];
+ uint8_t si4_msg[23];
+ uint8_t si5_msg[18];
+ uint8_t si5b_msg[18];
+ uint8_t si5t_msg[18];
+ uint8_t si6_msg[18];
+
+ struct gsm_sysinfo_freq freq[1024]; /* all frequencies */
+ uint16_t hopping[64]; /* hopping arfcn */
+ uint8_t hopp_len;
+
+ /* serving cell */
+ uint16_t cell_id;
+ uint16_t mcc, mnc, lac; /* LAI */
+ uint8_t max_retrans; /* decoded */
+ uint8_t tx_integer; /* decoded */
+ uint8_t reest_denied; /* 1 = denied */
+ uint8_t cell_barr; /* 1 = barred */
+ uint16_t class_barr; /* bit 10 is emergency */
+
+ /* si3 rest */
+ uint8_t sp;
+ uint8_t sp_cbq;
+ uint8_t sp_cro;
+ uint8_t sp_to;
+ uint8_t sp_pt;
+ uint8_t po;
+ uint8_t po_value;
+ uint8_t si2ter_ind;
+ uint8_t ecsm;
+ uint8_t sched;
+ uint8_t sched_where;
+ uint8_t gi_ra_colour;
+ uint8_t gi_si13_pos;
+
+ /* cell selection */
+ int8_t ms_txpwr_max_cch;
+ int8_t cell_resel_hyst_db;
+ int8_t rxlev_acc_min_db;
+ uint8_t neci;
+ uint8_t acs;
+ /* bcch options */
+ uint8_t bcch_radio_link_timeout;
+ uint8_t bcch_dtx;
+ uint8_t bcch_pwrc;
+ /* sacch options */
+ uint8_t sacch_radio_link_timeout;
+ uint8_t sacch_dtx;
+ uint8_t sacch_pwrc;
+ /* control channel */
+ uint8_t ccch_conf;
+ uint8_t bs_ag_blks_res;
+ uint8_t att_allowed;
+ uint8_t pag_mf_periods;
+ int32_t t3212; /* real value in seconds */
+ /* channel description */
+ uint8_t tsc;
+ uint8_t h; /* using hopping */
+ uint16_t arfcn;
+ uint8_t maio;
+ uint8_t hsn;
+ uint8_t chan_nr; /* type, slot, sub slot */
+
+ /* neighbor cell */
+ uint8_t nb_ext_ind_si2;
+ uint8_t nb_ba_ind_si2;
+ uint8_t nb_ext_ind_si2bis;
+ uint8_t nb_ba_ind_si2bis;
+ uint8_t nb_multi_rep_si2ter; /* see GSM 05.08 8.4.3 */
+ uint8_t nb_ext_ind_si5;
+ uint8_t nb_ba_ind_si5;
+ uint8_t nb_ext_ind_si5bis;
+ uint8_t nb_ba_ind_si5bis;
+ uint8_t nb_multi_rep_si5ter;
+ uint8_t nb_ncc_permitted;
+ uint8_t nb_max_retrans; /* decoded */
+ uint8_t nb_tx_integer; /* decoded */
+ uint8_t nb_reest_denied; /* 1 = denied */
+ uint8_t nb_cell_barr; /* 1 = barred */
+ uint16_t nb_class_barr; /* bit 10 is emergency */
+};
+
+int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn,
+ void (*print)(void *, const char *, ...), void *priv);
+
+#endif /* _SYSINFO_H */
diff --git a/src/host/layer23/include/osmocom/bb/mobile/transaction.h b/src/host/layer23/include/osmocom/bb/mobile/transaction.h
new file mode 100644
index 00000000..4be82c19
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/transaction.h
@@ -0,0 +1,71 @@
+#ifndef _TRANSACT_H
+#define _TRANSACT_H
+
+#include <osmocore/linuxlist.h>
+
+/* One transaction */
+struct gsm_trans {
+ /* Entry in list of all transactions */
+ struct llist_head entry;
+
+ /* The protocol within which we live */
+ uint8_t protocol;
+
+ /* The current transaction ID */
+ uint8_t transaction_id;
+
+ /* To whom we belong */
+ struct osmocom_ms *ms;
+
+ /* reference from MNCC or other application */
+ uint32_t callref;
+
+ /* if traffic channel receive was requested */
+ int tch_recv;
+
+ union {
+ struct {
+
+ /* current call state */
+ int state;
+
+ /* most recent progress indicator */
+ uint8_t prog_ind;
+
+ /* current timer and message queue */
+ int Tcurrent; /* current CC timer */
+ int T308_second; /* used to send release again */
+ struct timer_list timer;
+ struct gsm_mncc msg; /* stores setup/disconnect/release message */
+ } cc;
+#if 0
+ struct {
+ uint8_t link_id; /* RSL Link ID to be used for this trans */
+ int is_mt; /* is this a MO (0) or MT (1) transfer */
+ enum gsm411_cp_state cp_state;
+ struct timer_list cp_timer;
+
+ enum gsm411_rp_state rp_state;
+
+ struct gsm_sms *sms;
+ } sms;
+#endif
+ };
+};
+
+
+
+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,
+ uint32_t callref);
+
+struct gsm_trans *trans_alloc(struct osmocom_ms *ms,
+ uint8_t protocol, uint8_t trans_id,
+ uint32_t callref);
+void trans_free(struct gsm_trans *trans);
+
+int trans_assign_trans_id(struct osmocom_ms *ms,
+ uint8_t protocol, uint8_t ti_flag);
+
+#endif
diff --git a/src/host/layer23/include/osmocom/bb/mobile/vty.h b/src/host/layer23/include/osmocom/bb/mobile/vty.h
new file mode 100644
index 00000000..70faef5b
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/vty.h
@@ -0,0 +1,19 @@
+#ifndef OSMOCOM_VTY_H
+#define OSMOCOM_VTY_H
+
+#include <osmocom/bb/common/osmocom_data.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/buffer.h>
+#include <osmocom/vty/command.h>
+
+enum ms_vty_node {
+ MS_NODE = _LAST_OSMOVTY_NODE + 1,
+ TESTSIM_NODE,
+};
+
+enum node_type 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
+