WIP: Software for E1 mux/demux
diff --git a/src/osmo_e1.h b/src/osmo_e1.h
new file mode 100644
index 0000000..f39a308
--- /dev/null
+++ b/src/osmo_e1.h
@@ -0,0 +1,110 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/fsm.h>
+
+struct osmo_e1_tx_state {
+ bool remote_alarm;
+ bool crc4_error;
+ /* lower 5 bits: Sa4..Sa8 */
+ uint8_t sa4_sa8;
+ /* frame number 0..15 */
+ uint8_t frame_nr;
+ uint8_t crc4_last_smf;
+ uint8_t crc4;
+};
+
+struct osmo_e1_rx_state {
+ uint8_t frame_nr;
+ /* history of rceived TS0 octets */
+ uint8_t ts0_history[16];
+ uint8_t ts0_hist_len;
+ /* was a remote alarm received? */
+ bool remote_alarm;
+ bool remote_crc4_error;
+ /* number of TS0 bytes received since entering CRC mframe search */
+ uint8_t num_ts0_in_mframe_search;
+ struct osmo_fsm_inst *fi;
+ /* computed CRC4 */
+ uint8_t crc4_last_smf;
+ uint8_t crc4;
+};
+
+enum osmo_e1_notify_event {
+ E1_NTFY_EVT_ALIGN_FRAME,
+ E1_NTFY_EVT_ALIGN_CRC_MFRAME,
+ E1_NTFY_EVT_CRC_ERROR,
+ E1_NTFY_EVT_REMOTE_CRC_ERROR,
+ E1_NTFY_EVT_REMOTE_ALARM,
+};
+
+struct osmo_e1_instance_ts;
+struct osmo_e1_instance;
+typedef void (*e1_data_cb)(struct osmo_e1_instance_ts *ts, struct msgb *msg);
+typedef void (*e1_notify_cb)(struct osmo_e1_instance *e1i, enum osmo_e1_notify_event evt,
+ bool present, void *data);
+
+struct osmo_e1_instance_ts {
+ /* timeslot number */
+ uint8_t ts_nr;
+ /* back-pointer to e1 instance */
+ struct osmo_e1_instance *inst;
+ struct {
+ /* queue of pending to-be-transmitted messages */
+ struct llist_head queue;
+ unsigned long underruns;
+ } tx;
+ struct {
+ bool enabled;
+ /* how many bytes to buffer before calling call-back */
+ unsigned int granularity;
+ /* current receive buffer */
+ struct msgb *msg;
+ e1_data_cb data_cb;
+ /* private data, relevant to user */
+ void *priv;
+ } rx;
+};
+
+struct osmo_e1_instance {
+ /* list; currently not used yet */
+ struct llist_head list;
+
+ /* is CRC4 generation + parsing enabled? */
+ bool crc4_enabled;
+ /* notification call-back function */
+ e1_notify_cb notify_cb;
+
+ /* Rx + Tx related state */
+ struct osmo_e1_tx_state tx;
+ struct osmo_e1_rx_state rx;
+
+ /* our 32 timeslots (only 1..32 are used) */
+ struct osmo_e1_instance_ts ts[32];
+
+ /* private data, relevant to user */
+ void *priv;
+};
+
+extern const struct value_string osmo_e1_notifv_evt_names[];
+
+static inline const char *osmo_e1_notify_event_name(enum osmo_e1_notify_event evt) {
+ return get_value_string(osmo_e1_notifv_evt_names, evt);
+}
+
+int osmo_e1_init(void);
+struct osmo_e1_instance_ts *osmo_e1_instance_ts(struct osmo_e1_instance *e1i, uint8_t ts_nr);
+int osmo_e1_instance_init(struct osmo_e1_instance *e1i, const char *name, e1_notify_cb cb,
+ bool crc4_enabled, void *priv);
+void osmo_e1_instance_reset(struct osmo_e1_instance *e1i);
+int osmo_e1_ts_config(struct osmo_e1_instance_ts *e1t, e1_data_cb cb, unsigned int granularity,
+ bool enable);
+void osmo_e1_ts_reset(struct osmo_e1_instance_ts *e1t);
+
+
+void osmo_e1_ts_enqueue(struct osmo_e1_instance_ts *e1t, struct msgb *msg);
+int osmo_e1_pull_tx_frame(struct osmo_e1_instance *e1i, uint8_t *out_frame);
+int osmo_e1_rx_frame(struct osmo_e1_instance *e1i, const uint8_t *in_frame);