/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/* The main method to drive it as a standalone process      */

/*
 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009 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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include <unistd.h>

#include <sys/socket.h>

#include <openbsc/debug.h>
#include <osmocore/msgb.h>
#include <osmocore/talloc.h>
#include <openbsc/gsm_data.h>
#include <osmocore/select.h>
#include <openbsc/mgcp.h>
#include <openbsc/mgcp_internal.h>
#include <openbsc/telnet_interface.h>
#include <openbsc/vty.h>

#include <vty/command.h>

#include "../../bscconfig.h"

/* this is here for the vty... it will never be called */
void subscr_put() { abort(); }

#define _GNU_SOURCE
#include <getopt.h>

#warning "Make use of the rtp proxy code"

static struct bsc_fd bfd;
static struct mgcp_config *cfg;
static int reset_endpoints = 0;

const char *openbsc_copyright =
	"Copyright (C) 2009-2010 Holger Freyther and On-Waves\n"
	"Contributions by Daniel Willmann, Jan Lübbe,Stefan Schmidt\n"
	"Dieter Spaar, Andreas Eversberg, Harald Welte\n\n"
	"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
	"This is free software: you are free to change and redistribute it.\n"
	"There is NO WARRANTY, to the extent permitted by law.\n";

static char *config_file = "mgcp.cfg";

/* used by msgb and mgcp */
void *tall_bsc_ctx = NULL;

static void print_help()
{
	printf("Some useful help...\n");
	printf(" -h --help is printing this text.\n");
	printf(" -c --config-file filename The config file to use.\n");
}

static void handle_options(int argc, char** argv)
{
	while (1) {
		int option_index = 0, c;
		static struct option long_options[] = {
			{"help", 0, 0, 'h'},
			{"config-file", 1, 0, 'c'},
			{"version", 0, 0, 'V'},
			{0, 0, 0, 0},
		};

		c = getopt_long(argc, argv, "hc:V", long_options, &option_index);

		if (c == -1)
			break;

		switch(c) {
		case 'h':
			print_help();
			exit(0);
			break;
		case 'c':
			config_file = talloc_strdup(tall_bsc_ctx, optarg);
			break;
		case 'V':
			print_version(1);
			exit(0);
			break;
		default:
			/* ignore */
			break;
		};
	}
}

/* simply remember this */
static int mgcp_rsip_cb(struct mgcp_config *cfg)
{
	reset_endpoints = 1;

	return 0;
}

static int mgcp_change_cb(struct mgcp_config *cfg, int endpoint, int state, int local_rtp)
{
	if (state != MGCP_ENDP_MDCX)
		return 0;

	mgcp_send_dummy(&cfg->endpoints[endpoint]);
	return 0;
}

static int read_call_agent(struct bsc_fd *fd, unsigned int what)
{
	struct sockaddr_in addr;
	socklen_t slen = sizeof(addr);
	struct msgb *msg;
	struct msgb *resp;
	int i;

	msg = (struct msgb *) fd->data;

	/* read one less so we can use it as a \0 */
	int rc = recvfrom(bfd.fd, msg->data, msg->data_len - 1, 0,
		(struct sockaddr *) &addr, &slen);
	if (rc < 0) {
		perror("Gateway failed to read");
		return -1;
	} else if (slen > sizeof(addr)) {
		fprintf(stderr, "Gateway received message from outerspace: %d %d\n",
			slen, sizeof(addr));
		return -1;
	}

	/* handle message now */
	msg->l2h = msgb_put(msg, rc);
	resp = mgcp_handle_message(cfg, msg);
	msgb_reset(msg);

	if (resp) {
		sendto(bfd.fd, resp->l2h, msgb_l2len(resp), 0, (struct sockaddr *) &addr, sizeof(addr));
		msgb_free(resp);
	}

	if (reset_endpoints) {
		LOGP(DMGCP, LOGL_NOTICE, "Asked to reset endpoints.\n");
		reset_endpoints = 0;

		/* is checking in_addr.s_addr == INADDR_LOOPBACK making it more secure? */
		for (i = 1; i < cfg->number_endpoints; ++i)
			mgcp_free_endp(&cfg->endpoints[i]);
	}

	return 0;
}


int main(int argc, char** argv)
{
	struct gsm_network dummy_network;
	struct sockaddr_in addr;
	int on = 1, rc;
	struct log_target *stderr_target;

	tall_bsc_ctx = talloc_named_const(NULL, 1, "mgcp-callagent");

	log_init(&log_info);
	stderr_target = log_target_create_stderr();
	log_add_target(stderr_target);
	log_set_all_filter(stderr_target, 1);

	cfg = mgcp_config_alloc();
	if (!cfg)
		return -1;

	telnet_init(&dummy_network, 4243);

	handle_options(argc, argv);

        rc = mgcp_parse_config(config_file, cfg);
	if (rc < 0)
		return rc;

	/* set some callbacks */
	cfg->reset_cb = mgcp_rsip_cb;
	cfg->change_cb = mgcp_change_cb;

        /* we need to bind a socket */
        if (rc == 0) {
		bfd.when = BSC_FD_READ;
		bfd.cb = read_call_agent;
		bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
		if (bfd.fd < 0) {
			perror("Gateway failed to listen");
			return -1;
		}

		setsockopt(bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

		memset(&addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		addr.sin_port = htons(cfg->source_port);
		inet_aton(cfg->source_addr, &addr.sin_addr);

		if (bind(bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
			perror("Gateway failed to bind");
			return -1;
		}

		bfd.data = msgb_alloc(4096, "mgcp-msg");
		if (!bfd.data) {
			fprintf(stderr, "Gateway memory error.\n");
			return -1;
		}


		if (bsc_register_fd(&bfd) != 0) {
			LOGP(DMGCP, LOGL_FATAL, "Failed to register the fd\n");
			return -1;
		}

		LOGP(DMGCP, LOGL_NOTICE, "Configured for MGCP.\n");
	}

	/* initialisation */
	srand(time(NULL));

	/* main loop */
	while (1) {
		bsc_select_main(0);
	}


	return 0;
}

struct gsm_network;
int bsc_vty_init(struct gsm_network *dummy)
{
	cmd_init(1);
	vty_init("OpenBSC MGCP", PACKAGE_VERSION, openbsc_copyright);

	openbsc_vty_add_cmds();
        mgcp_vty_init();
	return 0;
}

