/* BSSGP2 - second generation of BSSGP library */

/* (C) 2020 Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 */

#include <osmocom/core/utils.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/core/msgb.h>

#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/tlv.h>

#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp2.h>


/*! transmit BSSGP PDU over NS (PTP BVC)
 *  \param[in] nsi NS Instance through which to transmit
 *  \param[in] nsei NSEI of NSE through which to transmit
 *  \param[in] bvci BVCI through which to transmit
 *  \param[in] msg BSSGP PDU to transmit
 *  \returns 0 on success; negative on error */
int bssgp2_nsi_tx_ptp(struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci,
		      struct msgb *msg, uint32_t lsp)
{
	struct osmo_gprs_ns2_prim nsp = {};
	int rc;

	if (!msg)
		return 0;

	nsp.bvci = bvci;
	nsp.nsei = nsei;
	nsp.u.unitdata.link_selector = lsp;

	osmo_prim_init(&nsp.oph, SAP_NS, GPRS_NS2_PRIM_UNIT_DATA, PRIM_OP_REQUEST, msg);
	rc = gprs_ns2_recv_prim(nsi, &nsp.oph);

	return rc;
}

/*! transmit BSSGP PDU over NS (SIGNALING BVC)
 *  \param[in] nsi NS Instance through which to transmit
 *  \param[in] nsei NSEI of NSE through which to transmit
 *  \param[in] msg BSSGP PDU to transmit
 *  \returns 0 on success; negative on error */
int bssgp2_nsi_tx_sig(struct gprs_ns2_inst *nsi, uint16_t nsei, struct msgb *msg, uint32_t lsp)
{
	return bssgp2_nsi_tx_ptp(nsi, nsei, 0, msg, lsp);
}

/*! Encode BSSGP BVC-BLOCK PDU as per TS 48.018 Section 10.4.8. */
struct msgb *bssgp2_enc_bvc_block(uint16_t bvci, enum gprs_bssgp_cause cause)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	uint16_t _bvci = osmo_htons(bvci);

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_BVC_BLOCK;

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, (uint8_t *) &cause);

	return msg;
}

/*! Encode BSSGP BVC-BLOCK-ACK PDU as per TS 48.018 Section 10.4.9. */
struct msgb *bssgp2_enc_bvc_block_ack(uint16_t bvci)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	uint16_t _bvci = osmo_htons(bvci);

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_BVC_BLOCK_ACK;

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);

	return msg;
}

/*! Encode BSSGP BVC-UNBLOCK PDU as per TS 48.018 Section 10.4.10. */
struct msgb *bssgp2_enc_bvc_unblock(uint16_t bvci)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	uint16_t _bvci = osmo_htons(bvci);

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_BVC_UNBLOCK;

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);

	return msg;
}

/*! Encode BSSGP BVC-UNBLOCK-ACK PDU as per TS 48.018 Section 10.4.11. */
struct msgb *bssgp2_enc_bvc_unblock_ack(uint16_t bvci)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	uint16_t _bvci = osmo_htons(bvci);

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_BVC_UNBLOCK_ACK;

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);

	return msg;
}

/*! Encode BSSGP BVC-RESET PDU as per TS 48.018 Section 10.4.12.
 *  \param[in] bvci PTP BVCI to encode into the BVCI IE
 *  \param[in] cause BSSGP Cause value (reason for reset)
 *  \param[in] ra_id Routing Area ID to be encoded to CELL_ID IE (optional)
 *  \param[in] cell_id Cell ID to be encoded to CELL_ID IE (only if ra_id is non-NULL)
 *  \param[in] feat_bm Feature Bitmap (optional)
 *  \param[in] ext_feat_bm Extended Feature Bitmap (optional) */
struct msgb *bssgp2_enc_bvc_reset(uint16_t bvci, enum gprs_bssgp_cause cause,
				  const struct gprs_ra_id *ra_id, uint16_t cell_id,
				  const uint8_t *feat_bm, const uint8_t *ext_feat_bm)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	uint16_t _bvci = osmo_htons(bvci);

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_BVC_RESET;

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, (uint8_t *) &cause);
	if (ra_id) {
		uint8_t bssgp_cid[8];
		bssgp_create_cell_id(bssgp_cid, ra_id, cell_id);
		msgb_tvlv_put(msg, BSSGP_IE_CELL_ID, sizeof(bssgp_cid), bssgp_cid);
	}

	if (feat_bm)
		msgb_tvlv_put(msg, BSSGP_IE_FEATURE_BITMAP, 1, feat_bm);

	if (ext_feat_bm)
		msgb_tvlv_put(msg, BSSGP_IE_EXT_FEATURE_BITMAP, 1, feat_bm);

	return msg;
}

/*! Encode BSSGP BVC-RESET-ACK PDU as per TS 48.018 Section 10.4.13.
 *  \param[in] bvci PTP BVCI to encode into the BVCI IE
 *  \param[in] ra_id Routing Area ID to be encoded to CELL_ID IE (optional)
 *  \param[in] cell_id Cell ID to be encoded to CELL_ID IE (only if ra_id is non-NULL)
 *  \param[in] feat_bm Feature Bitmap (optional)
 *  \param[in] ext_feat_bm Extended Feature Bitmap (optional) */
struct msgb *bssgp2_enc_bvc_reset_ack(uint16_t bvci, const struct gprs_ra_id *ra_id, uint16_t cell_id,
				      const uint8_t *feat_bm, const uint8_t *ext_feat_bm)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	uint16_t _bvci = osmo_htons(bvci);

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_BVC_RESET_ACK;

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
	if (ra_id) {
		uint8_t bssgp_cid[8];
		bssgp_create_cell_id(bssgp_cid, ra_id, cell_id);
		msgb_tvlv_put(msg, BSSGP_IE_CELL_ID, sizeof(bssgp_cid), bssgp_cid);
	}

	if (feat_bm)
		msgb_tvlv_put(msg, BSSGP_IE_FEATURE_BITMAP, 1, feat_bm);

	if (ext_feat_bm)
		msgb_tvlv_put(msg, BSSGP_IE_EXT_FEATURE_BITMAP, 1, feat_bm);

	return msg;
}

/*! Encode BSSGP STATUS PDU as per TS 48.018 Section 10.4.14.
 *  \param[in] cause BSSGP Cause value
 *  \param[in] bvci optional BVCI - only encoded if non-NULL
 *  \param[in] msg optional message buffer containing PDU in error - only encoded if non-NULL
 *  \param[in] max_pdu_len Maximum BSSGP PDU size the NS layer accepts */
struct msgb *bssgp2_enc_status(uint8_t cause, const uint16_t *bvci, const struct msgb *orig_msg, uint16_t max_pdu_len)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_STATUS;
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, &cause);
	/* FIXME: Require/encode BVCI only if cause is BVCI unknown/blocked
	 * See 3GPP TS 48.018 Ch. 10.4.14 */
	if (bvci) {
		uint16_t _bvci = osmo_htons(*bvci);
		msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
	}
	if (orig_msg) {
		uint32_t orig_len, max_orig_len;
		/* Calculate how big the reply would be: the BSSGP msg so far + size of the PDU IN ERROR including tvl */
		orig_len = msgb_bssgp_len(orig_msg);
		max_orig_len = msgb_length(msg) + TVLV_GROSS_LEN(orig_len);
		/* Truncate the difference between max_orig_len and mtu */
		if (max_orig_len > max_pdu_len)
			orig_len -= max_orig_len - max_pdu_len;
		msgb_tvlv_put(msg, BSSGP_IE_PDU_IN_ERROR, orig_len, msgb_bssgph(orig_msg));
	}

	return msg;
}

static const unsigned int bssgp_fc_gran_tbl[] = {
	[BSSGP_FC_GRAN_100]	= 100,
	[BSSGP_FC_GRAN_1000]	= 1000,
	[BSSGP_FC_GRAN_10000]	= 10000,
	[BSSGP_FC_GRAN_100000]	= 100000,
};

/*! Decode a FLOW-CONTROL-BVC PDU as per TS 48.018 Section 10.4.4.
 *  \param[out] fc caller-allocated memory for parsed output
 *  \param[in] tp pre-parsed TLVs; caller must ensure mandatory IE presence/length
 *  \returns 0 on success; negative in case of error */
int bssgp2_dec_fc_bvc(struct bssgp2_flow_ctrl *fc, const struct tlv_parsed *tp)
{
	unsigned int granularity = 100;

	/* optional "Flow Control Granularity IE" (11.3.102); applies to
	 * bucket_size_max, bucket_leak_rate and PFC FC params IE */
	if (TLVP_PRESENT(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY)) {
		uint8_t gran = *TLVP_VAL(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY);
		granularity = bssgp_fc_gran_tbl[gran & 3];
	}

	/* mandatory IEs */
	fc->tag = *TLVP_VAL(tp, BSSGP_IE_TAG);
	fc->bucket_size_max = granularity * tlvp_val16be(tp, BSSGP_IE_BVC_BUCKET_SIZE);
	fc->bucket_leak_rate = (granularity * tlvp_val16be(tp, BSSGP_IE_BUCKET_LEAK_RATE)) / 8;
	fc->u.bvc.bmax_default_ms = granularity * tlvp_val16be(tp, BSSGP_IE_BMAX_DEFAULT_MS);
	fc->u.bvc.r_default_ms = (granularity * tlvp_val16be(tp, BSSGP_IE_R_DEFAULT_MS)) / 8;

	/* optional / conditional */
	if (TLVP_PRESENT(tp, BSSGP_IE_BUCKET_FULL_RATIO)) {
		fc->bucket_full_ratio_present = true;
		fc->bucket_full_ratio = *TLVP_VAL(tp, BSSGP_IE_BUCKET_FULL_RATIO);
	} else {
		fc->bucket_full_ratio_present = false;
	}

	if (TLVP_PRESENT(tp, BSSGP_IE_BVC_MEASUREMENT)) {
		uint16_t val = tlvp_val16be(tp, BSSGP_IE_BVC_MEASUREMENT);
		fc->u.bvc.measurement_present = true;
		/* convert from centi-seconds to milli-seconds */
		if (val == 0xffff)
			fc->u.bvc.measurement = 0xffffffff;
		else
			fc->u.bvc.measurement = val * 10;
	} else {
		fc->u.bvc.measurement_present = false;
	}

	return 0;

}

/*! Encode a FLOW-CONTROL-BVC PDU as per TS 48.018 Section 10.4.4.
 *  \param[in] fc structure describing to-be-encoded FC parameters
 *  \param[in] gran if non-NULL: Encode using specified unit granularity
 *  \returns encoded PDU or NULL in case of error */
struct msgb *bssgp2_enc_fc_bvc(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	unsigned int granularity = 100;

	if (gran)
		granularity = bssgp_fc_gran_tbl[*gran & 3];

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC;

	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &fc->tag);
	msgb_tvlv_put_16be(msg, BSSGP_IE_BVC_BUCKET_SIZE, fc->bucket_size_max / granularity);
	msgb_tvlv_put_16be(msg, BSSGP_IE_BUCKET_LEAK_RATE, fc->bucket_leak_rate * 8 / granularity);
	msgb_tvlv_put_16be(msg, BSSGP_IE_BMAX_DEFAULT_MS, fc->u.bvc.bmax_default_ms / granularity);
	msgb_tvlv_put_16be(msg, BSSGP_IE_R_DEFAULT_MS, fc->u.bvc.r_default_ms * 8 / granularity);

	if (fc->bucket_full_ratio_present)
		msgb_tvlv_put(msg, BSSGP_IE_BUCKET_FULL_RATIO, 1, &fc->bucket_full_ratio);

	if (fc->u.bvc.measurement_present) {
		uint16_t val;
		/* convert from ms to cs */
		if (fc->u.bvc.measurement == 0xffffffff)
			val = 0xffff;
		else
			val = fc->u.bvc.measurement / 10;
		msgb_tvlv_put_16be(msg, BSSGP_IE_BVC_MEASUREMENT, val);
	}

	if (gran) {
		uint8_t val = *gran & 3;
		msgb_tvlv_put(msg, BSSGP_IE_FLOW_CTRL_GRANULARITY, 1, &val);
	}

	return msg;
}

/*! Encode a FLOW-CONTROL-BVC-ACK PDU as per TS 48.018 Section 10.4.4.
 *  \param[in] tag the tag IE value to encode
 *  \returns encoded PDU or NULL in case of error */
struct msgb *bssgp2_enc_fc_bvc_ack(uint8_t tag)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC_ACK;

	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);

	return msg;
}

/*! Decode a FLOW-CONTROL-MS PDU as per TS 48.018 Section 10.4.6.
 *  \param[out] fc caller-allocated memory for parsed output
 *  \param[in] tp pre-parsed TLVs; caller must ensure mandatory IE presence/length
 *  \returns 0 on success; negative in case of error */
int bssgp2_dec_fc_ms(struct bssgp2_flow_ctrl *fc, struct tlv_parsed *tp)
{
	unsigned int granularity = 100;

	/* optional "Flow Control Granularity IE" (11.3.102); applies to
	 * bucket_size_max, bucket_leak_rate and PFC FC params IE */
	if (TLVP_PRESENT(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY)) {
		uint8_t gran = *TLVP_VAL(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY);
		granularity = bssgp_fc_gran_tbl[gran & 3];
	}

	/* mandatory IEs */
	fc->u.ms.tlli = tlvp_val32be(tp, BSSGP_IE_TLLI);
	fc->tag = *TLVP_VAL(tp, BSSGP_IE_TAG);
	fc->bucket_size_max = granularity * tlvp_val16be(tp, BSSGP_IE_MS_BUCKET_SIZE);
	fc->bucket_leak_rate = (granularity * tlvp_val16be(tp, BSSGP_IE_BUCKET_LEAK_RATE)) / 8;

	/* optional / conditional */
	if (TLVP_PRESENT(tp, BSSGP_IE_BUCKET_FULL_RATIO)) {
		fc->bucket_full_ratio_present = true;
		fc->bucket_full_ratio = *TLVP_VAL(tp, BSSGP_IE_BUCKET_FULL_RATIO);
	} else {
		fc->bucket_full_ratio_present = false;
	}

	return 0;
}

/*! Encode a FLOW-CONTROL-MS PDU as per TS 48.018 Section 10.4.6.
 *  \param[in] fc structure describing to-be-encoded FC parameters
 *  \param[in] gran if non-NULL: Encode using specified unit granularity
 *  \returns encoded PDU or NULL in case of error */
struct msgb *bssgp2_enc_fc_ms(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;
	unsigned int granularity = 100;

	if (gran)
		granularity = bssgp_fc_gran_tbl[*gran & 3];

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_MS;

	msgb_tvlv_put_32be(msg, BSSGP_IE_TLLI, fc->u.ms.tlli);
	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &fc->tag);
	msgb_tvlv_put_16be(msg, BSSGP_IE_MS_BUCKET_SIZE, fc->bucket_size_max / granularity);
	msgb_tvlv_put_16be(msg, BSSGP_IE_BUCKET_LEAK_RATE, fc->bucket_leak_rate * 8 / granularity);

	if (fc->bucket_full_ratio_present)
		msgb_tvlv_put(msg, BSSGP_IE_BUCKET_FULL_RATIO, 1, &fc->bucket_full_ratio);

	if (gran) {
		uint8_t val = *gran & 3;
		msgb_tvlv_put(msg, BSSGP_IE_FLOW_CTRL_GRANULARITY, 1, &val);
	}

	return msg;
}

/*! Encode a FLOW-CONTROL-BVC-ACK PDU as per TS 48.018 Section 10.4.7.
 *  \param[in] tlli the TLLI IE value to encode
 *  \param[in] tag the tag IE value to encode
 *  \returns encoded PDU or NULL in case of error */
struct msgb *bssgp2_enc_fc_ms_ack(uint32_t tlli, uint8_t tag)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph;

	if (!msg)
		return NULL;

	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_MS_ACK;

	msgb_tvlv_put_32be(msg, BSSGP_IE_TLLI, tlli);
	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);

	return msg;
}
