/* 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/application.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>

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();

	osmo_init_logging(&log_info);

	/* enable filters */
	log_set_category_filter(osmo_stderr_target, DINP, 1, LOGL_INFO);
	log_set_category_filter(osmo_stderr_target, DSCCP, 1, LOGL_INFO);
	log_set_category_filter(osmo_stderr_target, DMSC, 1, LOGL_INFO);
	log_set_category_filter(osmo_stderr_target, DMGCP, 1, LOGL_INFO);
	log_set_print_timestamp(osmo_stderr_target, 1);
	log_set_use_color(osmo_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;
}

