/* Relay UDT/all SCCP messages */
/*
 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010-2011 by On-Waves
 * 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <mtp_data.h>
#include <mtp_level3.h>
#include <mtp_pcap.h>
#include <thread.h>
#include <bsc_data.h>
#include <snmp_mtp.h>
#include <cellmgr_debug.h>
#include <sctp_m2ua.h>
#include <ss7_application.h>

#include <osmocom/m2ua/m2ua_msg.h>

#include <osmocom/core/talloc.h>

#include <osmocom/sccp/sccp.h>

#include <osmocom/vty/vty.h>
#include <osmocom/vty/telnet_interface.h>

#include <sys/stat.h>
#include <sys/types.h>

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <getopt.h>

#undef PACKAGE_NAME
#undef PACKAGE_VERSION
#undef PACKAGE_BUGREPORT
#undef PACKAGE_TARNAME
#undef PACKAGE_STRING
#include <cellmgr_config.h>

static struct log_target *stderr_target;

char *config = "osmo_stp.cfg";

struct bsc_data *bsc;
extern void cell_vty_init(void);
extern void handle_options(int argc, char **argv);

static struct mtp_link_set *find_link_set(struct bsc_data *bsc,
					  int len, const char *buf)
{
	struct mtp_link_set *set;

	llist_for_each_entry(set, &bsc->linksets, entry)
		if (strncmp(buf, set->name, len) == 0)
			return set;

	return NULL;
}

static int inject_read_cb(struct osmo_fd *fd, unsigned int what)
{
	struct msgb *msg;
	struct m2ua_msg_part *data, *link;
	struct bsc_data *bsc;
	struct m2ua_msg *m2ua;
	struct mtp_link_set *out_set;
	uint8_t buf[4096];

	bsc = fd->data;

	int rc = read(fd->fd, buf, sizeof(buf));
	if (rc <= 0) {
		LOGP(DINP, LOGL_ERROR, "Failed to read from the console.\n");
		return -1;
	}

	if (!bsc->allow_inject) {
		LOGP(DINP, LOGL_ERROR, "Injecting messages is not allowed.\n");
		return -1;
	}

	m2ua = m2ua_from_msg(rc, buf);
	if (!m2ua) {
		LOGP(DINP, LOGL_ERROR, "Failed to parse M2UA.\n");
		return -1;
	}

	if (m2ua->hdr.msg_class == M2UA_CLS_MAUP && m2ua->hdr.msg_type == M2UA_MAUP_DATA) {
		data = m2ua_msg_find_tag(m2ua, M2UA_TAG_DATA);
		if (!data) {
			LOGP(DINP, LOGL_ERROR, "MAUP Data without data.\n");
			goto exit;
		}

		if (data->len > 2048) {
			LOGP(DINP, LOGL_ERROR, "Data is too big for this configuration.\n");
			goto exit;
		}

		link = m2ua_msg_find_tag(m2ua, MUA_TAG_IDENT_TEXT);
		if (!link) {
			LOGP(DINP, LOGL_ERROR, "Interface Identifier Text is mandantory.\n");
			goto exit;
		}

		if (link->len > 255) {
			LOGP(DINP, LOGL_ERROR, "Spec violation. Ident text should be shorter than 255.\n");
			goto exit;
		}

		out_set = find_link_set(bsc, link->len, (const char *) link->dat);
		if (!out_set) {
			LOGP(DINP, LOGL_ERROR, "Identified linkset does not exist.\n");
			goto exit;
		}

		msg = msgb_alloc(2048, "inject-data");
		if (!msg) {
			LOGP(DINP, LOGL_ERROR, "Failed to allocate storage.\n");
			goto exit;
		}

		msg->l2h = msgb_put(msg, data->len);
		memcpy(msg->l2h, data->dat, data->len);

		/* we are diretcly going to the output. no checking of anything  */
		if (mtp_link_set_send(out_set, msg) != 0) {
			LOGP(DINP, LOGL_ERROR, "Failed to send message.\n");
			msgb_free(msg);
		}
	}

exit:
	m2ua_msg_free(m2ua);
	return 0;
}

static int inject_init(struct bsc_data *bsc)
{
	int fd;
	struct sockaddr_in addr;

	fd = socket(PF_INET, SOCK_DGRAM, 0);
	if (fd < 0)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(5001);

	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) {
		LOGP(DINP, LOGL_ERROR, "Failed to bind to port 5001.\n");
		close(fd);
		return -1;
	}

	bsc->inject_fd.fd = fd;
	bsc->inject_fd.when = BSC_FD_READ;
	bsc->inject_fd.cb = inject_read_cb;
	bsc->inject_fd.data = bsc;

	if (osmo_fd_register(&bsc->inject_fd) != 0) {
		LOGP(DINP, LOGL_ERROR, "Failed to register.\n");
		close(fd);
		return -1;
	}

	return 0;
}

int main(int argc, char **argv)
{
	int rc;
	struct ss7_application *app;

	thread_init();

	log_init(&log_info);
	stderr_target = log_target_create_stderr();
	log_add_target(stderr_target);

	/* enable filters */
	log_set_all_filter(stderr_target, 1);
	log_set_category_filter(stderr_target, DINP, 1, LOGL_INFO);
	log_set_category_filter(stderr_target, DSCCP, 1, LOGL_INFO);
	log_set_category_filter(stderr_target, DMSC, 1, LOGL_INFO);
	log_set_category_filter(stderr_target, DMGCP, 1, LOGL_INFO);
	log_set_print_timestamp(stderr_target, 1);
	log_set_use_color(stderr_target, 0);

	sccp_set_log_area(DSCCP);
	m2ua_set_log_area(DM2UA);

	bsc = bsc_data_create();
	if (!bsc)
		return -1;

	handle_options(argc, argv);

	srand(time(NULL));

	cell_vty_init();
	rc = telnet_init(NULL, NULL, 4242);
	if (rc < 0)
		return rc;

	if (inject_init(bsc) != 0) {
		LOGP(DINP, LOGL_NOTICE, "Failed to initialize inject interface.\n");
		return -1;
	}

	/* now bind the the UDP and SCTP port */
	if (link_global_init(&bsc->udp_data) != 0) {
		LOGP(DINP, LOGL_ERROR, "Global UDP input init failed.\n");
		return -1;
	}

	bsc->m2ua_trans = sctp_m2ua_transp_create(bsc);
	if (!bsc->m2ua_trans) {
		LOGP(DINP, LOGL_ERROR, "Failed to create SCTP transport.\n");
		return -1;
	}

	if (vty_read_config_file(config, NULL) < 0) {
		fprintf(stderr, "Failed to read the VTY config.\n");
		return -1;
	}

	if (link_global_bind(&bsc->udp_data, bsc->udp_src_port) != 0) {
		LOGP(DINP, LOGL_ERROR, "Global UDP bind failed.\n");
		return -1;
	}

	if (sctp_m2ua_transport_bind(bsc->m2ua_trans, "0.0.0.0", bsc->m2ua_src_port) != 0) {
		LOGP(DINP, LOGL_ERROR,
		     "Failed to bind on port %d\n", bsc->m2ua_src_port);
		return -1;
	}

	/* start all apps */
	llist_for_each_entry(app, &bsc->apps, entry) {
		LOGP(DINP, LOGL_NOTICE,
		     "Going to start app %d/%s.\n", app->nr, app->name);
		ss7_application_start(app);
	}

        while (1) {
		osmo_select_main(0);
        }

	return 0;
}

