
#include <stdio.h>

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

#include <osmocom/core/msgb.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/vty/logging.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_rim.h>
#include <osmocom/sgsn/sgsn_rim.h>
#include <osmocom/sgsn/gtp_mme.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/sgsn.h>

static int sgsn_bssgp_fwd_rim_to_geran(const struct bssgp_ran_information_pdu *pdu)
{
	struct bssgp_bvc_ctx *bvc_ctx;
	OSMO_ASSERT(pdu->routing_info_dest.discr == BSSGP_RIM_ROUTING_INFO_GERAN);

	bvc_ctx = btsctx_by_raid_cid(&pdu->routing_info_dest.geran.raid, pdu->routing_info_dest.geran.cid);
	if (!bvc_ctx) {
		LOGP(DRIM, LOGL_ERROR, "Unable to find NSEI for destination cell %s\n",
		       bssgp_rim_ri_name(&pdu->routing_info_dest));
		return -EINVAL;
	}

	/* Forward PDU as it is to the correct interface */
	return bssgp_tx_rim(pdu, bvc_ctx->nsei);
}

static int sgsn_bssgp_fwd_rim_to_eutran(const struct bssgp_ran_information_pdu *pdu)
{
	struct sgsn_mme_ctx *mme;
	OSMO_ASSERT(pdu->routing_info_dest.discr == BSSGP_RIM_ROUTING_INFO_EUTRAN);

	mme = sgsn_mme_ctx_by_route(sgsn, &pdu->routing_info_dest.eutran.tai);
	if (!mme) { /* See if we have a default route configured */
		mme = sgsn_mme_ctx_by_default_route(sgsn);
		if (!mme) {
			LOGP(DRIM, LOGL_ERROR, "Unable to find MME for destination cell %s\n",
			       bssgp_rim_ri_name(&pdu->routing_info_dest));
			return -EINVAL;
		}
	}

	return sgsn_mme_ran_info_req(mme, pdu);
}

/* Receive a RIM PDU from BSSGP (GERAN) */
int sgsn_rim_rx_from_gb(struct osmo_bssgp_prim *bp, struct msgb *msg)
{
	uint16_t nsei = msgb_nsei(msg);
	struct bssgp_ran_information_pdu *pdu = &bp->u.rim_pdu;

	if (pdu->routing_info_src.discr != BSSGP_RIM_ROUTING_INFO_GERAN) {
		LOGP(DRIM, LOGL_ERROR,
		     "Rx BSSGP RIM (NSEI=%u): Expected src %s, got %s\n", nsei,
		     bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_GERAN),
		     bssgp_rim_routing_info_discr_str(pdu->routing_info_src.discr));
		goto err;
	}

	switch (pdu->routing_info_dest.discr) {
	case BSSGP_RIM_ROUTING_INFO_GERAN:
		return sgsn_bssgp_fwd_rim_to_geran(pdu);
	case BSSGP_RIM_ROUTING_INFO_EUTRAN:
		return sgsn_bssgp_fwd_rim_to_eutran(pdu);
	default:
		/* At the moment we can only handle GERAN/EUTRAN addresses, any
		 * other type of address will be considered as an invalid
		 * address. see also: 3GPP TS 48.018, section 8c.3.1.3
		 */
		LOGP(DRIM, LOGL_ERROR,
		     "Rx BSSGP RIM (NSEI=%u): Unsupported dst %s\n", nsei,
		     bssgp_rim_routing_info_discr_str(pdu->routing_info_dest.discr));
	}

	LOGP(DRIM, LOGL_INFO, "Rx BSSGP RIM (NSEI=%u): for dest cell %s\n", nsei,
	     bssgp_rim_ri_name(&pdu->routing_info_dest));

err:
	/* In case of an invalid destination address we respond with
	 * a BSSGP STATUS PDU, see also: 3GPP TS 48.018, section 8c.3.1.3 */
	bssgp_tx_status(BSSGP_CAUSE_UNKN_RIM_AI, NULL, msg);
	return -1;
}

/* Receive a RIM PDU from GTPvC1 (EUTRAN) */
int sgsn_rim_rx_from_gtp(struct bssgp_ran_information_pdu *pdu, struct sgsn_mme_ctx *mme)
{
	struct sgsn_mme_ctx *mme_tmp;
	if (pdu->routing_info_src.discr != BSSGP_RIM_ROUTING_INFO_EUTRAN) {
		LOGMME(mme, DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: Expected src %s, got %s\n",
		       bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_EUTRAN),
		       bssgp_rim_routing_info_discr_str(pdu->routing_info_src.discr));
		return -EINVAL;
	}

	if (pdu->routing_info_dest.discr != BSSGP_RIM_ROUTING_INFO_GERAN) {
		LOGMME(mme, DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: Expected dst %s, got %s\n",
		       bssgp_rim_routing_info_discr_str(BSSGP_RIM_ROUTING_INFO_GERAN),
		       bssgp_rim_routing_info_discr_str(pdu->routing_info_dest.discr));
		return -EINVAL;
	}

	mme_tmp = sgsn_mme_ctx_by_route(sgsn, &pdu->routing_info_src.eutran.tai);
	if (!mme_tmp)/* See if we have a default route configured */
		mme_tmp = sgsn_mme_ctx_by_default_route(sgsn);
	if (mme != mme_tmp) {
		LOGP(DRIM, LOGL_ERROR, "Rx GTP RAN Information Relay: "
		     "Source MME doesn't have RIM routing configured for TAI: %s\n",
		     bssgp_rim_ri_name(&pdu->routing_info_src));
		return -EINVAL;
	}

	LOGMME(mme, DRIM, LOGL_INFO, "Rx GTP RAN Information Relay for dest cell %s\n",
	       bssgp_rim_ri_name(&pdu->routing_info_dest));

	return sgsn_bssgp_fwd_rim_to_geran(pdu);
}
