/* GPRS BSSGP protocol implementation as per 3GPP TS 08.18 */

/* (C) 2009-2017 by Harald Welte <laforge@gnumonks.org>
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 */

#include <errno.h>
#include <stdint.h>

#include <osmocom/core/msgb.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns.h>

#include "common_vty.h"

struct gprs_ns_inst *bssgp_nsi;

/* BSSGP Protocol specific, not implementation specific */
/* FIXME: This needs to go into libosmocore after finished */

/* Chapter 11.3.9 / Table 11.10: Cause coding */
static const struct value_string bssgp_cause_strings[] = {
	{ BSSGP_CAUSE_PROC_OVERLOAD,	"Processor overload" },
	{ BSSGP_CAUSE_EQUIP_FAIL,	"Equipment Failure" },
	{ BSSGP_CAUSE_TRASIT_NET_FAIL,	"Transit netowkr service failure" },
	{ BSSGP_CAUSE_CAPA_GREATER_0KPBS,"Transmission capacity modified" },
	{ BSSGP_CAUSE_UNKNOWN_MS,	"Unknown MS" },
	{ BSSGP_CAUSE_UNKNOWN_BVCI,	"Unknown BVCI" },
	{ BSSGP_CAUSE_CELL_TRAF_CONG,	"Cell traffic congestion" },
	{ BSSGP_CAUSE_SGSN_CONG,	"SGSN congestion" },
	{ BSSGP_CAUSE_OML_INTERV,	"O&M intervention" },
	{ BSSGP_CAUSE_BVCI_BLOCKED,	"BVCI blocked" },
	{ BSSGP_CAUSE_PFC_CREATE_FAIL,	"PFC create failure" },
	{ BSSGP_CAUSE_SEM_INCORR_PDU,	"Semantically incorrect PDU" },
	{ BSSGP_CAUSE_INV_MAND_INF,	"Invalid mandatory information" },
	{ BSSGP_CAUSE_MISSING_MAND_IE,	"Missing mandatory IE" },
	{ BSSGP_CAUSE_MISSING_COND_IE,	"Missing conditional IE" },
	{ BSSGP_CAUSE_UNEXP_COND_IE,	"Unexpected conditional IE" },
	{ BSSGP_CAUSE_COND_IE_ERR,	"Conditional IE error" },
	{ BSSGP_CAUSE_PDU_INCOMP_STATE,	"PDU incompatible with protocol state" },
	{ BSSGP_CAUSE_PROTO_ERR_UNSPEC,	"Protocol error - unspecified" },
	{ BSSGP_CAUSE_PDU_INCOMP_FEAT, 	"PDU not compatible with feature set" },
	{ 0, NULL },
};

static const struct value_string bssgp_pdu_strings[] = {
	{ BSSGP_PDUT_DL_UNITDATA,		"DL-UNITDATA" },
	{ BSSGP_PDUT_UL_UNITDATA,		"UL-UNITDATA" },
	{ BSSGP_PDUT_RA_CAPABILITY,		"RA-CAPABILITY" },
	{ BSSGP_PDUT_PTM_UNITDATA,		"PTM-UNITDATA" },
	{ BSSGP_PDUT_PAGING_PS,			"PAGING-PS" },
	{ BSSGP_PDUT_PAGING_CS,			"PAGING-CS" },
	{ BSSGP_PDUT_RA_CAPA_UDPATE,		"RA-CAPABILITY-UPDATE" },
	{ BSSGP_PDUT_RA_CAPA_UPDATE_ACK,	"RA-CAPABILITY-UPDATE-ACK" },
	{ BSSGP_PDUT_RADIO_STATUS,		"RADIO-STATUS" },
	{ BSSGP_PDUT_SUSPEND,			"SUSPEND" },
	{ BSSGP_PDUT_SUSPEND_ACK,		"SUSPEND-ACK" },
	{ BSSGP_PDUT_SUSPEND_NACK,		"SUSPEND-NACK" },
	{ BSSGP_PDUT_RESUME,			"RESUME" },
	{ BSSGP_PDUT_RESUME_ACK,		"RESUME-ACK" },
	{ BSSGP_PDUT_RESUME_NACK,		"RESUME-NACK" },
	{ BSSGP_PDUT_BVC_BLOCK,			"BVC-BLOCK" },
	{ BSSGP_PDUT_BVC_BLOCK_ACK,		"BVC-BLOCK-ACK" },
	{ BSSGP_PDUT_BVC_RESET,			"BVC-RESET" },
	{ BSSGP_PDUT_BVC_RESET_ACK,		"BVC-RESET-ACK" },
	{ BSSGP_PDUT_BVC_UNBLOCK,		"BVC-UNBLOCK" },
	{ BSSGP_PDUT_BVC_UNBLOCK_ACK,		"BVC-UNBLOCK-ACK" },
	{ BSSGP_PDUT_FLOW_CONTROL_BVC,		"FLOW-CONTROL-BVC" },
	{ BSSGP_PDUT_FLOW_CONTROL_BVC_ACK,	"FLOW-CONTROL-BVC-ACK" },
	{ BSSGP_PDUT_FLOW_CONTROL_MS,		"FLOW-CONTROL-MS" },
	{ BSSGP_PDUT_FLOW_CONTROL_MS_ACK,	"FLOW-CONTROL-MS-ACK" },
	{ BSSGP_PDUT_FLUSH_LL,			"FLUSH-LL" },
	{ BSSGP_PDUT_FLUSH_LL_ACK,		"FLUSH-LL-ACK" },
	{ BSSGP_PDUT_LLC_DISCARD,		"LLC DISCARDED" },
	{ BSSGP_PDUT_SGSN_INVOKE_TRACE,		"SGSN-INVOKE-TRACE" },
	{ BSSGP_PDUT_STATUS,			"STATUS" },
	{ BSSGP_PDUT_DOWNLOAD_BSS_PFC,		"DOWNLOAD-BSS-PFC" },
	{ BSSGP_PDUT_CREATE_BSS_PFC,		"CREATE-BSS-PFC" },
	{ BSSGP_PDUT_CREATE_BSS_PFC_ACK,	"CREATE-BSS-PFC-ACK" },
	{ BSSGP_PDUT_CREATE_BSS_PFC_NACK,	"CREATE-BSS-PFC-NACK" },
	{ BSSGP_PDUT_MODIFY_BSS_PFC,		"MODIFY-BSS-PFC" },
	{ BSSGP_PDUT_MODIFY_BSS_PFC_ACK,	"MODIFY-BSS-PFC-ACK" },
	{ BSSGP_PDUT_DELETE_BSS_PFC,		"DELETE-BSS-PFC" },
	{ BSSGP_PDUT_DELETE_BSS_PFC_ACK,	"DELETE-BSS-PFC-ACK" },
	{ 0, NULL },
};

const char *bssgp_cause_str(enum gprs_bssgp_cause cause)
{
	return get_value_string(bssgp_cause_strings, cause);
}

const char *bssgp_pdu_str(enum bssgp_pdu_type pdu)
{
	return get_value_string(bssgp_pdu_strings, pdu);
}

struct msgb *bssgp_msgb_alloc(void)
{
	struct msgb *msg = msgb_alloc_headroom(4096, 128, "BSSGP");

	/* TODO: Add handling of msg == NULL to this function and to all callers */
	OSMO_ASSERT(msg != NULL);

	msgb_bssgph(msg) = msg->data;
	return msg;
}

struct msgb *bssgp_msgb_copy(const struct msgb *msg, const char *name)
{
	struct libgb_msgb_cb *old_cb, *new_cb;
	struct msgb *new_msg;

	new_msg = msgb_copy(msg, name);
	if (!new_msg)
		return NULL;

	/* copy GB specific data */
	old_cb = LIBGB_MSGB_CB(msg);
	new_cb = LIBGB_MSGB_CB(new_msg);

	if (old_cb->bssgph)
		new_cb->bssgph = new_msg->_data + (old_cb->bssgph - msg->_data);
	if (old_cb->llch)
		new_cb->llch = new_msg->_data + (old_cb->llch - msg->_data);

	/* bssgp_cell_id is a pointer into the old msgb, so we need to make
	 * it a pointer into the new msgb */
	if (old_cb->bssgp_cell_id)
		new_cb->bssgp_cell_id = new_msg->_data +
			(old_cb->bssgp_cell_id - msg->_data);
	new_cb->nsei = old_cb->nsei;
	new_cb->bvci = old_cb->bvci;
	new_cb->tlli = old_cb->tlli;

	return new_msg;
}

/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
			 uint16_t bvci, uint16_t ns_bvci)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	uint16_t _bvci;

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = ns_bvci;

	bgph->pdu_type = pdu_type;
	_bvci = osmo_htons(bvci);
	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);

	return gprs_ns_sendmsg(bssgp_nsi, msg);
}

/* Chapter 10.4.14: Status */
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	/* GSM 08.18, 10.4.14.1: The BVCI must be included if (and only if) the
	   cause is either "BVCI blocked" or "BVCI unknown" */
	if (cause == BSSGP_CAUSE_UNKNOWN_BVCI || cause == BSSGP_CAUSE_BVCI_BLOCKED) {
		if (bvci == NULL)
			LOGP(DBSSGP, LOGL_ERROR, "BSSGP Tx STATUS, cause=%s: "
			     "missing conditional BVCI\n",
			     bssgp_cause_str(cause));
	} else {
		if (bvci != NULL)
			LOGP(DBSSGP, LOGL_ERROR, "BSSGP Tx STATUS, cause=%s: "
			     "unexpected conditional BVCI\n",
			     bssgp_cause_str(cause));
	}

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP BVCI=%u Tx STATUS, cause=%s\n",
		bvci ? *bvci : 0, bssgp_cause_str(cause));
	msgb_nsei(msg) = msgb_nsei(orig_msg);
	msgb_bvci(msg) = 0;

	bgph->pdu_type = BSSGP_PDUT_STATUS;
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, &cause);
	if (bvci) {
		uint16_t _bvci = osmo_htons(*bvci);
		msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
	}
	msgb_tvlv_put(msg, BSSGP_IE_PDU_IN_ERROR,
		      msgb_bssgp_len(orig_msg), msgb_bssgph(orig_msg));

	return gprs_ns_sendmsg(bssgp_nsi, msg);
}
