/* Test routines for the BSSGP implementation in libosmogb
 *
 * (C) 2014 by sysmocom s.f.m.c. GmbH
 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
 *
 * Skeleton based on bssgp_fc_test.c
 * (C) 2012 by Harald Welte <laforge@gnumonks.org>
 */

#undef _GNU_SOURCE
#define _GNU_SOURCE

#include <osmocom/core/application.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/prim.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <dlfcn.h>

#define BSS_NSEI 0x0b55

static struct osmo_prim_hdr last_oph = {0};

/* override */
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
		const struct sockaddr *dest_addr, socklen_t addrlen)
{
	typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
			const struct sockaddr *, socklen_t);
	static sendto_t real_sendto = NULL;
	uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);

	if (!real_sendto)
		real_sendto = dlsym(RTLD_NEXT, "sendto");

	fprintf(stderr, "MESSAGE to 0x%08x, msg length %d\n%s\n",
		dest_host, len, osmo_hexdump(buf, len));

	return len;
}

/* override */
int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
			 struct msgb *msg, uint16_t bvci)
{
	fprintf(stderr, "CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
			event, msgb_bssgp_len(msg), bvci,
			osmo_hexdump(msgb_bssgph(msg), msgb_bssgp_len(msg)));
	return 0;
}

struct msgb *last_ns_tx_msg = NULL;

/* override */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
{
	msgb_free(last_ns_tx_msg);
	last_ns_tx_msg = msg;

	return msgb_length(msg);
}

int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
	printf("BSSGP primitive, SAP %d, prim = %d, op = %d, msg = %s\n",
	       oph->sap, oph->primitive, oph->operation, msgb_hexdump(oph->msg));

	last_oph.sap = oph->sap;
	last_oph.primitive = oph->primitive;
	last_oph.operation = oph->operation;
	last_oph.msg = NULL;
	return -1;
}

static void msgb_bssgp_send_and_free(struct msgb *msg)
{
	msgb_nsei(msg) = BSS_NSEI;

	bssgp_rcvmsg(msg);

	msgb_free(msg);
}

static void send_bssgp_supend(enum bssgp_pdu_type pdu_type, uint32_t tlli)
{
	struct msgb *msg = bssgp_msgb_alloc();
	uint32_t tlli_be = htonl(tlli);
	uint8_t rai[] = {0x0f, 0xf1, 0x80, 0x20, 0x37, 0x00};

	msgb_v_put(msg, pdu_type);
	msgb_tvlv_put(msg, BSSGP_IE_TLLI, sizeof(tlli_be), (uint8_t *)&tlli_be);
	msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, sizeof(rai), &rai[0]);

	msgb_bssgp_send_and_free(msg);
}

static void send_bssgp_resume(enum bssgp_pdu_type pdu_type, uint32_t tlli)
{
	struct msgb *msg = bssgp_msgb_alloc();
	uint32_t tlli_be = htonl(tlli);
	uint8_t rai[] = {0x0f, 0xf1, 0x80, 0x20, 0x37, 0x00};
	uint8_t suspend_ref = 1;

	msgb_v_put(msg, pdu_type);
	msgb_tvlv_put(msg, BSSGP_IE_TLLI, sizeof(tlli_be), (uint8_t *)&tlli_be);
	msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, sizeof(rai), &rai[0]);
	msgb_tvlv_put(msg, BSSGP_IE_SUSPEND_REF_NR, 1, &suspend_ref);

	msgb_bssgp_send_and_free(msg);
}

static void test_bssgp_suspend_resume(void)
{
	const uint32_t tlli = 0xf0123456;

	printf("----- %s START\n", __func__);
	memset(&last_oph, 0, sizeof(last_oph));

	send_bssgp_supend(BSSGP_PDUT_SUSPEND, tlli);
	OSMO_ASSERT(last_oph.primitive == PRIM_BSSGP_GMM_SUSPEND);

	send_bssgp_resume(BSSGP_PDUT_RESUME, tlli);
	OSMO_ASSERT(last_oph.primitive == PRIM_BSSGP_GMM_RESUME);

	printf("----- %s END\n", __func__);
}

static void send_bssgp_status(enum gprs_bssgp_cause cause, uint16_t *bvci)
{
	struct msgb *msg = bssgp_msgb_alloc();
	uint8_t cause_ = cause;

	msgb_v_put(msg, BSSGP_PDUT_STATUS);
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, &cause_);
	if (bvci) {
		uint16_t bvci_ = htons(*bvci);
		msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &bvci_);
	}

	msgb_bssgp_send_and_free(msg);
}

static void test_bssgp_status(void)
{
	uint16_t bvci;

	printf("----- %s START\n", __func__);

	send_bssgp_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL);
	OSMO_ASSERT(last_oph.primitive == PRIM_NM_STATUS);

	/* Enforce prim != PRIM_NM_STATUS */
	last_oph.primitive = PRIM_NM_LLC_DISCARDED;

	bvci = 1234;
	send_bssgp_status(BSSGP_CAUSE_UNKNOWN_BVCI, &bvci);
	OSMO_ASSERT(last_oph.primitive == PRIM_NM_STATUS);

	printf("----- %s END\n", __func__);
}

static void test_bssgp_bad_reset()
{
	struct msgb *msg = bssgp_msgb_alloc();
	uint16_t bvci_be = htons(2);
	uint8_t cause = BSSGP_CAUSE_OML_INTERV;

	msgb_v_put(msg, BSSGP_PDUT_BVC_RESET);
	msgb_tvlv_put(msg, BSSGP_IE_BVCI, sizeof(bvci_be), (uint8_t *)&bvci_be);
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, sizeof(cause), &cause);

	msgb_bvci(msg) = 0xbad;

	msgb_bssgp_send_and_free(msg);
}

static void test_bssgp_flow_control_bvc(void)
{
	struct bssgp_bvc_ctx bctx = {
		.nsei = 0x1234,
		.bvci = 0x5678,
	};
	const uint8_t  tag = 42;
	const uint32_t bmax = 0x1022 * 100;
	const uint32_t rate = 0xc040 / 8 * 100;
	const uint32_t bmax_ms = bmax / 2;
	const uint32_t rate_ms = rate / 2;
	uint8_t  ratio = 0x78;
	uint32_t qdelay = 0x1144 * 10;
	int rc;

	static uint8_t expected_simple_msg[] = {
		0x26,
		0x1e, 0x81, 0x2a,		/* tag */
		0x05, 0x82, 0x10, 0x22,		/* Bmax */
		0x03, 0x82, 0xc0, 0x40,		/* R */
		0x01, 0x82, 0x08, 0x11,		/* Bmax_MS */
		0x1c, 0x82, 0x60, 0x20,		/* R_MS */
	};

	static uint8_t expected_ext_msg[] = {
		0x26,
		0x1e, 0x81, 0x2a,		/* tag */
		0x05, 0x82, 0x10, 0x22,		/* Bmax */
		0x03, 0x82, 0xc0, 0x40,		/* R */
		0x01, 0x82, 0x08, 0x11,		/* Bmax_MS */
		0x1c, 0x82, 0x60, 0x20,		/* R_MS */
		0x3c, 0x81, 0x78,		/* ratio */
		0x06, 0x82, 0x11, 0x44,		/* Qdelay */
	};

	printf("----- %s START\n", __func__);

	rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms,
		NULL, NULL);

	OSMO_ASSERT(rc >= 0);
	OSMO_ASSERT(last_ns_tx_msg != NULL);
	printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg));
	OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_simple_msg));
	OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg),
			expected_simple_msg, sizeof(expected_simple_msg)));

	rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms,
		&ratio, &qdelay);

	OSMO_ASSERT(rc >= 0);
	OSMO_ASSERT(last_ns_tx_msg != NULL);
	printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg));
	OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_ext_msg));
	OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg),
			expected_ext_msg, sizeof(expected_ext_msg)));

	msgb_free(last_ns_tx_msg);
	last_ns_tx_msg = NULL;

	printf("----- %s END\n", __func__);
}

static struct log_info info = {};

int main(int argc, char **argv)
{
	struct sockaddr_in bss_peer= {0};

	osmo_init_logging(&info);
	log_set_use_color(osmo_stderr_target, 0);
	log_set_print_filename(osmo_stderr_target, 0);

	bssgp_nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);

	bss_peer.sin_family = AF_INET;
	bss_peer.sin_port = htons(32000);
	bss_peer.sin_addr.s_addr = htonl(0x7f0000ff);

	gprs_ns_nsip_connect(bssgp_nsi, &bss_peer, BSS_NSEI, BSS_NSEI+1);


	printf("===== BSSGP test START\n");
	test_bssgp_suspend_resume();
	test_bssgp_status();
	test_bssgp_bad_reset();
	test_bssgp_flow_control_bvc();
	printf("===== BSSGP test END\n\n");

	exit(EXIT_SUCCESS);
}
