/* Osmocom Software Defined E1
 *
 * (C) 2018 by Harald Welte <laforge@gnumonks.org>
 *
 * Implements ITU-T Rec. G.704 Section 2.3
 */

#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include <osmocom/core/msgb.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/fsm.h>

#include "crc4itu.h"
#include "osmo_e1.h"

#define S(x)	(1 << (x))

/* Frame Alignment Signal (BIT1 may be overwritten with CRC-4) */
#define G704_E1_FAS	0x1B

static inline bool is_correct_fas(uint8_t bt) {
	if ((bt & 0x7F) == G704_E1_FAS)
		return true;
	else
		return false;
}

/* are we in SMF II (true) or I (false) */
static inline bool is_smf_II(const struct osmo_e1_tx_state *tx) {
	if (tx->frame_nr >= 8)
		return true;
	return false;
}

static struct osmo_fsm e1_align_fsm;
static void align_fsm_reset(struct osmo_e1_instance *e1i);

static void notify_user(struct osmo_e1_instance *e1i, enum osmo_e1_notify_event evt,
			bool present, void *priv)
{
	if (!e1i->notify_cb)
		return;
	e1i->notify_cb(e1i, evt, present, priv);
}

/*! Initialize a (caller-allocated) Osmocom E1 Instance
 *  \param[inout] e1i E1 Instance to be initialized
 *  \returns 0 on success, negative on error */
int osmo_e1_instance_init(struct osmo_e1_instance *e1i, const char *name, e1_notify_cb cb,
			  bool crc4_enabled, void *priv)
{
	int i;

	e1i->crc4_enabled = crc4_enabled;
	e1i->notify_cb = cb;
	e1i->tx.sa4_sa8 = 0x00;

	e1i->priv = priv;

	for (i = 1; i < ARRAY_SIZE(e1i->ts); i++) {
		struct osmo_e1_instance_ts *e1t = &e1i->ts[i];
		e1t->ts_nr = i;
		e1t->inst = e1i;
		INIT_LLIST_HEAD(&e1t->tx.queue);

		e1t->rx.granularity = 256;
	}

	e1i->rx.fi = osmo_fsm_inst_alloc(&e1_align_fsm, NULL, e1i, LOGL_DEBUG, name);
	if (!e1i->rx.fi)
		return -1;

	osmo_e1_instance_reset(e1i);

	return 0;
}

/*! stop E1 timeslot; release any pending rx/tx buffers
 *  \param[in] e1t Timeslot which we are to stop, disable and release buffers */
void osmo_e1_ts_reset(struct osmo_e1_instance_ts *e1t)
{
	e1t->tx.underruns = 0;
	msgb_queue_free(&e1t->tx.queue);

	e1t->rx.enabled = false;
	msgb_free(e1t->rx.msg);
	e1t->rx.msg = NULL;
}

/*! stop E1 instance; stops all timeslots and releases any pending rx/tx buffers
 *  \param[in] e1t E1 instance which we are to stop */
void osmo_e1_instance_reset(struct osmo_e1_instance *e1i)
{
	int i;

	align_fsm_reset(e1i);

	e1i->tx.remote_alarm = false;
	e1i->tx.crc4_error = false;
	e1i->tx.frame_nr = 0;
	e1i->tx.crc4_last_smf = 0;
	e1i->tx.crc4 = 0;

	e1i->rx.frame_nr = 0;
	memset(&e1i->rx.ts0_history, 0, sizeof(e1i->rx.ts0_history));
	e1i->rx.ts0_hist_len = 0;
	e1i->rx.remote_alarm = false;
	e1i->rx.remote_crc4_error = false;
	e1i->rx.num_ts0_in_mframe_search = 0;

	for (i = 1; i < ARRAY_SIZE(e1i->ts); i++) {
		struct osmo_e1_instance_ts *e1t = &e1i->ts[i];
		osmo_e1_ts_reset(e1t);
	}
}

/*! obtain pointer to TS given by instance + timeslot number
 *  \param[in] e1i E1 intance on which we work
 *  \param[in] ts_nr E1 timeslot number (1..31)
 *  \returns pointer to timeslot; NULL on error */
struct osmo_e1_instance_ts *osmo_e1_instance_ts(struct osmo_e1_instance *e1i, uint8_t ts_nr)
{
	if (ts_nr == 0 || ts_nr >= ARRAY_SIZE(e1i->ts))
		return NULL;

	return &e1i->ts[ts_nr];
}

/*! configure an E1 timeslot
 *  \param[in] e1t Timeslot which we are to configure
 *  \param[in] granularity granularity (buffer size) to use on Rx
 *  \param[in] enable enable (true) or disalble (false) receiving on this TS
 *  \return 0 on success; negative on error */
int osmo_e1_ts_config(struct osmo_e1_instance_ts *e1t, e1_data_cb cb, unsigned int granularity,
		      bool enable)
{
	e1t->rx.data_cb = cb;
	e1t->rx.enabled = enable;
	e1t->rx.granularity = granularity;

	return 0;
}

const struct value_string osmo_e1_notifv_evt_names[] = {
	{ E1_NTFY_EVT_ALIGN_FRAME, "Aligned to Frame" },
	{ E1_NTFY_EVT_ALIGN_CRC_MFRAME, "Aligned to CRC4-Multiframe" },
	{ E1_NTFY_EVT_CRC_ERROR, "CRC Error detected (local)" },
	{ E1_NTFY_EVT_REMOTE_CRC_ERROR, "CRC Error reported (remote)" },
	{ E1_NTFY_EVT_REMOTE_ALARM, "Remote Alarm condition repoorted" },
	{ 0, NULL }
};

/***********************************************************************
 * Transmit Side
 ***********************************************************************/

/*! Enqueue a message buffer of to-be-transmitted data for a timeslot
 *  \param[in] e1i E1 instance for which to enqueue
 *  \param[in] ts_nr Timeslot number on which data is to be transmitted
 *  \param[in] msg Message buffer storing the to-be-transmitted data
 *  \returns 0 on success; negative in case of error.
 *
 *  Ownership of \a msg is transferred from caller into this function, but only
 *  in case of successful execution (return 0)!
 */
void osmo_e1_ts_enqueue(struct osmo_e1_instance_ts *e1t, struct msgb *msg)
{
	msgb_enqueue(&e1t->tx.queue, msg);
}

/* obtain a CRC4 bit for the current frame number */
static uint8_t e1_pull_crc4_bit(struct osmo_e1_instance *e1i)
{
	/* If CRC-4 is disabled, all CRC bits shall be '1' */
	if (e1i->crc4_enabled == 0) {
		return 0x01;
	} else {
		/* CRC is transmitted MSB first */
		switch (e1i->tx.frame_nr % 8) {
		case 0:
			return (e1i->tx.crc4_last_smf >> 3) & 1;
		case 2:
			return (e1i->tx.crc4_last_smf >> 2) & 1;
		case 4:
			return (e1i->tx.crc4_last_smf >> 1) & 1;
		case 6:
			return (e1i->tx.crc4_last_smf >> 0) & 1;
		default:
			OSMO_ASSERT(0);
		}
	}
}

/* pull a single to-be-transmitted byte for TS0 */
static uint8_t e1_pull_ts0(struct osmo_e1_instance *e1i)
{
	uint8_t ret;

	/* according to Table 5B/G.704 - CRC-4 multiframe structure */
	if ((e1i->tx.frame_nr % 2) == 0) {
		/* FAS */
		ret = G704_E1_FAS | (e1_pull_crc4_bit(e1i) << 7);
	} else {
		switch (e1i->tx.frame_nr) {
		case 1:
		case 3:
		case 7:
			ret = 0x40;
			break;
		case 5:
		case 9:
		case 11:
			ret = 0xC0;
			break;
		case 13:
		case 15:
			ret = 0x40;
			if (e1i->tx.crc4_error)
				ret |= 0x80;
			break;
		}
		ret |= e1i->tx.sa4_sa8;
		if (e1i->tx.remote_alarm)
			ret |= 0x20;
	}

	/* re-set CRC4 at start of sub-multiframe */
	if (e1i->tx.frame_nr == 0 || e1i->tx.frame_nr == 8) {
		e1i->tx.crc4_last_smf = e1i->tx.crc4;
		e1i->tx.crc4 = 0;
	}

	/* increment frame number modulo 16 */
	e1i->tx.frame_nr = (e1i->tx.frame_nr + 1) % 16;

	return ret;
}

/* pull a single to-be-transmitted byte for TS1..31 */
static uint8_t e1_pull_tsN(struct osmo_e1_instance_ts *e1t)
{
	struct msgb *msg = llist_first_entry_or_null(&e1t->tx.queue, struct msgb, list);
	uint8_t *cur;

retry:
	/* if there's no message to transmit */
	if (!msg) {
		e1t->tx.underruns++;
		return 0xFF;
	}
	if (msgb_length(msg) <= 0) {
		llist_del(&msg->list);
		msgb_free(msg);
		msg = llist_first_entry_or_null(&e1t->tx.queue, struct msgb, list);
		goto retry;
	}
	cur = msgb_pull(msg, 1);
	return *cur;
}

/* update the current in-progress CRC4 value with data from \a out_frame */
static void e1_tx_update_crc4(struct osmo_e1_instance *e1i, const uint8_t *out_frame)
{
	uint8_t ts0;

	ts0 = out_frame[0];
	/* mask off the C bits */
	if (is_correct_fas(ts0))
		ts0 &= 0x7F;
	e1i->tx.crc4 = crc4itu(e1i->tx.crc4, &ts0, 1);
	/* add the remaining bytes/bits */
	e1i->tx.crc4 = crc4itu(e1i->tx.crc4, out_frame+1, ARRAY_SIZE(e1i->ts)-1);
}

/*! Pull one to-be-transmitted E1 frame (256bits) from the E1 instance
 *  \param e1i E1 instance for which the frame shall be generated
 *  \param[out] out_frame callee-allocated buffer to which function stores 32 bytes
 *  \returns 0 on success, negative on error */
int osmo_e1_pull_tx_frame(struct osmo_e1_instance *e1i, uint8_t *out_frame)
{
	int i;

	/* generate TS0 */
	out_frame[0] = e1_pull_ts0(e1i);

	/* generate TS1..31 */
	for (i = 1; i < ARRAY_SIZE(e1i->ts); i++) {
		struct osmo_e1_instance_ts *e1t = &e1i->ts[i];
		/* get next to-be-transmitted byte from the TS */
		out_frame[i] = e1_pull_tsN(e1t);
	}
	/* update our CRC4 computation */
	e1_tx_update_crc4(e1i, out_frame);

	return 0;
}

/***********************************************************************
 * Receiver Side
 ***********************************************************************/

/* According to Figure 2 / ITU-T G.706 */
enum e1_align_state {
	/* Frame Alignment Search */
	E1_AS_SEARCH_FRAME,
	/* CRC multiframe alignment search */
	E1_AS_SEARCH_CRC_MFRAME,
	/* monitoring for incorrect frame alignment and error performance using CRC */
	E1_AS_ALIGNED_CRC_MFRAME,
	/* no CRC: just frame alignment loss check */
	E1_AS_ALIGNED_BASIC,
};

enum e1_align_event {
	/* received a TS0 octet */
	E1_AE_RX_TS0,
	E1_AE_RESET
};

static const struct value_string e1_align_evt_names[] = {
	{ E1_AE_RX_TS0, "E1_AE_RX_TS0" },
	{ E1_AE_RESET, "E1_AE_RESET" },
	{ 0, NULL }
};

/* get a TS0 byte from the history. delta 0 == current, delte 1 == previous, ... */
static uint8_t get_ts0_hist(struct osmo_e1_instance *e1i, uint8_t delta)
{
	return e1i->rx.ts0_history[((e1i->rx.frame_nr + 16)-delta) % 16];
}

/* ITU-T G.706 Section 4.1.1 */
static bool frame_alignment_lost(struct osmo_e1_instance *e1i)
{
	if (e1i->rx.frame_nr % 2)
		return false;

	/* Frame alignment will be assumed to have been lost when three consecutive incorrect
	 * frame alignment signals have been received. */
	if (!is_correct_fas(get_ts0_hist(e1i, 0)) &&
	    !is_correct_fas(get_ts0_hist(e1i, 2)) &&
	    !is_correct_fas(get_ts0_hist(e1i, 4)))
		return true;
	else
		return false;
}

/* ITU-T G.706 Section 4.1.2 */
static bool frame_alignment_recovered(struct osmo_e1_instance *e1i)
{
	/* two consecutive FAS with one non-FAS interspersed */
	if (is_correct_fas(get_ts0_hist(e1i, 0)) &&
	    !is_correct_fas(get_ts0_hist(e1i, 1)) &&
	    is_correct_fas(get_ts0_hist(e1i, 2)))
		return true;
	else
		return false;
}

/* ITU-T G.706 Section 4.2 */
static bool crc_mframe_alignment_achieved(struct osmo_e1_instance *e1i)
{
	/* if current TS0 byte is FAS, we cannot detect alignment */
	if (is_correct_fas(get_ts0_hist(e1i, 0)))
		return false;
	if ((get_ts0_hist(e1i, 0) >> 7) == 1 &&
	    (get_ts0_hist(e1i, 2) >> 7) == 1 &&
	    (get_ts0_hist(e1i, 4) >> 7) == 0 &&
	    (get_ts0_hist(e1i, 6) >> 7) == 1 &&
	    (get_ts0_hist(e1i, 8) >> 7) == 0 &&
	    (get_ts0_hist(e1i, 10) >> 7) == 0)
		return true;
	else
		return false;
}

/* Get the CRC4 that was received from our Rx TS0 history */
static uint8_t crc4_from_ts0_hist(struct osmo_e1_instance *e1i, bool smf2)
{
	uint8_t crc = 0;
	uint8_t offset = 0;

	if (smf2)
		offset = 8;

	crc |= (e1i->rx.ts0_history[0+offset] >> 7) << 0;
	crc |= (e1i->rx.ts0_history[2+offset] >> 7) << 1;
	crc |= (e1i->rx.ts0_history[4+offset] >> 7) << 2;
	crc |= (e1i->rx.ts0_history[6+offset] >> 7) << 3;

	return crc;
}

/* update the current in-progress CRC4 value with data from \a rx_frame */
static void e1_rx_update_crc4(struct osmo_e1_instance *e1i, const uint8_t *rx_frame)
{
	uint8_t ts0;

	ts0 = rx_frame[0];
	/* mask off the C bits */
	if (is_correct_fas(ts0))
		ts0 &= 0x7F;
	e1i->rx.crc4 = crc4itu(e1i->rx.crc4, &ts0, 1);
	/* add the remaining bytes/bits */
	e1i->rx.crc4 = crc4itu(e1i->rx.crc4, rx_frame+1, ARRAY_SIZE(e1i->ts)-1);
}

/* FSM State handler */
static void e1_align_search_frame(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct osmo_e1_instance *e1i = (struct osmo_e1_instance *) fi->priv;

	if (frame_alignment_recovered(e1i)) {
		/* if we detected the 2nd FAS, we must be in FN 2 (or at least FN%2=0 */
		e1i->rx.frame_nr = 2;
		notify_user(e1i, E1_NTFY_EVT_ALIGN_FRAME, true, NULL);
		osmo_fsm_inst_state_chg(fi, E1_AS_SEARCH_CRC_MFRAME, 0, 0);
	}
}

/* FSM State handler */
static void e1_align_search_crc_mframe(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct osmo_e1_instance *e1i = (struct osmo_e1_instance *) fi->priv;

	if (crc_mframe_alignment_achieved(e1i)) {
		/* if we detected the 6-bit CRC multiframe signal, we must be in FN 11 */
		e1i->rx.frame_nr = 11;
		/* FIXME: "at least two valid CRC multiframe alignment signals can be located within
		 * 8 ms, the time separating two CRC multiframe alignment signals being 2 ms or a
		 * multiple of 2 ms" */
		notify_user(e1i, E1_NTFY_EVT_ALIGN_CRC_MFRAME, true, NULL);
		osmo_fsm_inst_state_chg(fi, E1_AS_ALIGNED_CRC_MFRAME, 0, 0);
	} else {
		/* if no mframe alignment is established within 8ms (64 frames), fall back */
		if (e1i->rx.num_ts0_in_mframe_search >= 64) {
			e1i->rx.num_ts0_in_mframe_search = 0;
			osmo_fsm_inst_state_chg(fi, E1_AS_SEARCH_FRAME, 0, 0);
		}
		e1i->rx.num_ts0_in_mframe_search++;
	}
}

static void e1_aligned_common(struct osmo_e1_instance *e1i)
{
	uint8_t inb = get_ts0_hist(e1i, 0);

	/* All non-FAS frames contain "A" bit in TS0 */
	if (!is_correct_fas(inb & 0x7F)) {
		bool old_alarm = e1i->rx.remote_alarm;
		/* frame not containing the frame alignment signal */
		if (inb & 0x20)
			e1i->rx.remote_alarm = true;
		else
			e1i->rx.remote_alarm = false;
		if (old_alarm != e1i->rx.remote_alarm)
			notify_user(e1i, E1_NTFY_EVT_REMOTE_ALARM, e1i->rx.remote_alarm, NULL);
	}
}

/* FSM State handler */
static void e1_aligned_crc_mframe(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct osmo_e1_instance *e1i = (struct osmo_e1_instance *) fi->priv;

	if (frame_alignment_lost(e1i)) {
		osmo_fsm_inst_state_chg(fi, E1_AS_SEARCH_FRAME, 0, 0);
		return;
	}

	if (e1i->crc4_enabled) {
		uint8_t crc_rx;
		bool crc4_error;

		/* check if we just received a complete CRC4 */
		switch (e1i->rx.frame_nr) {
		case 7:
		case 15:
			crc_rx = crc4_from_ts0_hist(e1i, e1i->rx.frame_nr == 15 ? true : false);
			if (crc_rx != e1i->rx.crc4_last_smf)
				crc4_error = true;
			else
				crc4_error = false;
			if (crc4_error != e1i->tx.crc4_error) {
				notify_user(e1i, E1_NTFY_EVT_CRC_ERROR, crc4_error, NULL);
				e1i->tx.crc4_error = crc4_error;
			}
			/* rotate computed CRC4 one further */
			e1i->rx.crc4_last_smf = e1i->rx.crc4;
			e1i->rx.crc4 = 0;
			break;
		default:
			break;
		}

		/* check if the remote side reports any CRC errors */
		switch (e1i->rx.frame_nr) {
		case 13:
		case 15:
			crc4_error = false;
			if ((get_ts0_hist(e1i, 0) >> 7) == 0)
				crc4_error = true;
			if (crc4_error != e1i->rx.remote_crc4_error) {
				notify_user(e1i, E1_NTFY_EVT_REMOTE_CRC_ERROR, crc4_error, NULL);
				e1i->rx.remote_crc4_error = crc4_error;
			}
			break;
		}
	}

	e1_aligned_common(e1i);
}

/* FSM State handler */
static void e1_aligned_basic(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct osmo_e1_instance *e1i = (struct osmo_e1_instance *) fi->priv;

	if (frame_alignment_lost(e1i)) {
		osmo_fsm_inst_state_chg(fi, E1_AS_SEARCH_FRAME, 0, 0);
		return;
	}

	e1_aligned_common(e1i);
}

static const struct osmo_fsm_state e1_align_states[] = {
	[E1_AS_SEARCH_FRAME] = {
		.name = "SEARCH_FRAME",
		.in_event_mask = S(E1_AE_RX_TS0),
		.out_state_mask = S(E1_AS_SEARCH_FRAME) |
				  S(E1_AS_SEARCH_CRC_MFRAME) |
				  S(E1_AS_ALIGNED_BASIC),
		.action = e1_align_search_frame,
	},
	[E1_AS_SEARCH_CRC_MFRAME] = {
		.name = "SEARCH_CRC_MFRAME",
		.in_event_mask = S(E1_AE_RX_TS0),
		.out_state_mask = S(E1_AS_SEARCH_FRAME) |
				  S(E1_AS_SEARCH_CRC_MFRAME) |
				  S(E1_AS_ALIGNED_CRC_MFRAME),
		.action = e1_align_search_crc_mframe,
	},
	[E1_AS_ALIGNED_CRC_MFRAME] = {
		.name = "ALIGNED_CRC_MFRAME",
		.in_event_mask = S(E1_AE_RX_TS0),
		.out_state_mask = S(E1_AS_SEARCH_FRAME) |
				  S(E1_AS_SEARCH_CRC_MFRAME) |
				  S(E1_AS_ALIGNED_CRC_MFRAME),
		.action = e1_aligned_crc_mframe,
	},
	[E1_AS_ALIGNED_BASIC] = {
		.name = "ALIGNED_BASIC",
		.in_event_mask = S(E1_AE_RX_TS0),
		.out_state_mask = S(E1_AS_SEARCH_FRAME),
		.action = e1_aligned_basic,
	},
};

static void e1_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct osmo_e1_instance *e1i = (struct osmo_e1_instance *) fi->priv;

	switch (event) {
	case E1_AE_RESET:
		e1i->rx.num_ts0_in_mframe_search = 0;
		osmo_fsm_inst_state_chg(fi, E1_AS_SEARCH_FRAME, 0, 0);
		break;
	}
}

static struct osmo_fsm e1_align_fsm = {
	.name = "e1-align",
	.states = e1_align_states,
	.num_states = ARRAY_SIZE(e1_align_states),
	.allstate_event_mask = S(E1_AE_RESET),
	.allstate_action = e1_allstate,
	.log_subsys = DLGLOBAL,
	.event_names = e1_align_evt_names,
};

static void align_fsm_reset(struct osmo_e1_instance *e1i)
{
	osmo_fsm_inst_dispatch(e1i->rx.fi, E1_AE_RESET, NULL);
}

static void e1_rx_hist_add(struct osmo_e1_instance *e1i, uint8_t inb)
{
	e1i->rx.ts0_history[e1i->rx.frame_nr] = inb;
	if (e1i->rx.ts0_hist_len < 16)
		e1i->rx.ts0_hist_len++;
}

static void e1_rx_ts0(struct osmo_e1_instance *e1i, uint8_t inb)
{
	/* append just-received byte to the TS0 receive history buffer */
	e1_rx_hist_add(e1i, inb);

	/* notify the FSM that a new TS0 byte was received */
	osmo_fsm_inst_dispatch(e1i->rx.fi, E1_AE_RX_TS0, NULL);

	e1i->rx.frame_nr = (e1i->rx.frame_nr + 1) % 16;
}

static void e1_rx_tsN(struct osmo_e1_instance_ts *e1t, uint8_t inb)
{
	struct msgb *msg;

	if (!e1t->rx.enabled)
		return;

	if (!e1t->rx.msg)
		e1t->rx.msg = msgb_alloc(e1t->rx.granularity, "E1 Rx");
	msg = e1t->rx.msg;
	OSMO_ASSERT(msg);

	msgb_put_u8(msg, inb);
	if (msgb_tailroom(msg) <= 0) {
		if (!e1t->rx.data_cb)
			msgb_free(msg);
		else
			e1t->rx.data_cb(e1t, msg);
		e1t->rx.msg = NULL;
	}
}

/*! Receive a single E1 frame of 32x8 (=256) bits
 *  \param e1i E1 instance for which the frame was received
 *  \param[in] in_frame caller-provided buffer of 32 octets
 *
 *  The idea is that whoever calls us will already have done the bit-alignment,
 *  i.e. the first bit of TS0 of the frame will be octet-aligned and hence the
 *  entire 256bit buffer is provided as octet-aligned 32bytes in \a in_frame.
 */
int osmo_e1_rx_frame(struct osmo_e1_instance *e1i, const uint8_t *in_frame)
{
	int i;

	e1_rx_update_crc4(e1i, in_frame);

	e1_rx_ts0(e1i, in_frame[0]);

	for (i = 1; i < ARRAY_SIZE(e1i->ts); i++) {
		struct osmo_e1_instance_ts *e1t = &e1i->ts[i];
		e1_rx_tsN(e1t, in_frame[i]);
	}

	return 0;
}

int osmo_e1_init(void)
{
	return osmo_fsm_register(&e1_align_fsm);
}
