aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/bsc/lchan_fsm.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/osmocom/bsc/lchan_fsm.h')
-rw-r--r--include/osmocom/bsc/lchan_fsm.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/include/osmocom/bsc/lchan_fsm.h b/include/osmocom/bsc/lchan_fsm.h
new file mode 100644
index 0000000..8734e57
--- /dev/null
+++ b/include/osmocom/bsc/lchan_fsm.h
@@ -0,0 +1,88 @@
+/* osmo-bsc API to manage lchans, logical channels in GSM cells. */
+#pragma once
+
+#include <osmocom/bsc/gsm_data.h>
+
+#define LOG_ADD_NEWLINE(fmt) ((!fmt || !*fmt || fmt[strlen(fmt)-1] != '\n') ? "\n" : "")
+
+/* This macro automatically includes a final \n, if omitted. */
+#define LOG_LCHAN(lchan, level, fmt, args...) do { \
+ if (lchan->fi) \
+ LOGPFSML(lchan->fi, level, "(type=%s) " fmt "%s", gsm_lchant_name(lchan->type), \
+ ## args, LOG_ADD_NEWLINE(fmt)); \
+ else \
+ LOGP(DRSL, level, "%s (not initialized) " fmt "%s", gsm_lchan_name(lchan), \
+ ## args, LOG_ADD_NEWLINE(fmt)); \
+ } while(0)
+
+enum lchan_fsm_state {
+ LCHAN_ST_UNUSED,
+ LCHAN_ST_WAIT_TS_READY,
+ LCHAN_ST_WAIT_ACTIV_ACK,
+ LCHAN_ST_WAIT_RLL_ESTABLISH,
+ LCHAN_ST_WAIT_MGW_ENDPOINT_AVAILABLE,
+ LCHAN_ST_WAIT_IPACC_CRCX_ACK,
+ LCHAN_ST_WAIT_IPACC_MDCX_ACK,
+ LCHAN_ST_WAIT_MGW_ENDPOINT_CONFIGURED,
+ LCHAN_ST_ACTIVE,
+ LCHAN_ST_WAIT_SAPIS_RELEASED,
+ LCHAN_ST_WAIT_BEFORE_RF_RELEASE,
+ LCHAN_ST_WAIT_RF_RELEASE_ACK,
+ LCHAN_ST_WAIT_AFTER_ERROR,
+ LCHAN_ST_BORKEN,
+};
+
+enum lchan_fsm_event {
+ LCHAN_EV_ACTIVATE,
+ LCHAN_EV_TS_READY,
+ LCHAN_EV_TS_ERROR,
+ LCHAN_EV_RSL_CHAN_ACTIV_ACK,
+ LCHAN_EV_RSL_CHAN_ACTIV_NACK,
+ LCHAN_EV_RLL_ESTABLISH_IND,
+ LCHAN_EV_MGW_ENDPOINT_AVAILABLE,
+ LCHAN_EV_MGW_ENDPOINT_CONFIGURED,
+ LCHAN_EV_MGW_ENDPOINT_ERROR,
+ LCHAN_EV_IPACC_CRCX_ACK,
+ LCHAN_EV_IPACC_CRCX_NACK,
+ LCHAN_EV_IPACC_MDCX_ACK,
+ LCHAN_EV_IPACC_MDCX_NACK,
+ LCHAN_EV_RLL_REL_IND,
+ LCHAN_EV_RLL_REL_CONF,
+ LCHAN_EV_RSL_RF_CHAN_REL_ACK,
+ LCHAN_EV_RLL_ERR_IND,
+
+ /* FIXME: not yet implemented: Chan Mode Modify */
+ LCHAN_EV_CHAN_MODE_MODIF_ACK,
+ LCHAN_EV_CHAN_MODE_MODIF_ERROR,
+};
+
+void lchan_fsm_alloc(struct gsm_lchan *lchan);
+void lchan_release(struct gsm_lchan *lchan, bool sacch_deact,
+ bool err, enum gsm48_rr_cause cause_rr);
+
+struct lchan_activate_info {
+ enum lchan_activate_mode activ_for;
+ struct gsm_subscriber_connection *for_conn;
+ /* This always is for a specific lchan, so its lchan->type indicates full or half rate.
+ * When a dyn TS was selected, the lchan->type has been set to the desired rate. */
+ enum gsm48_chan_mode chan_mode;
+ bool requires_voice_stream;
+ struct gsm_lchan *old_lchan;
+};
+
+void lchan_activate(struct gsm_lchan *lchan, struct lchan_activate_info *info);
+
+static inline const char *lchan_state_name(struct gsm_lchan *lchan)
+{
+ return lchan->fi ? osmo_fsm_inst_state_name(lchan->fi) : "NULL";
+}
+
+static inline bool lchan_state_is(struct gsm_lchan *lchan, uint32_t state)
+{
+ return lchan->fi && lchan->fi->state == state;
+}
+
+bool lchan_may_receive_data(struct gsm_lchan *lchan);
+
+void lchan_forgetx_conn(struct gsm_lchan *lchan);
+void lchan_forgetx_mgw_endpoint(struct gsm_lchan *lchan);