/* MSC related stuff... */
/*
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010 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 <bsc_data.h>
#include <bss_patch.h>
#include <bssap_sccp.h>
#include <ipaccess.h>
#include <mtp_data.h>
#include <cellmgr_debug.h>

#include <osmocore/tlv.h>
#include <osmocore/utils.h>

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/tcp.h>

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define RECONNECT_TIME		10, 0
#define NAT_MUX 0xfc

static void msc_send_id_response(struct bsc_data *bsc);
static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto);

void mtp_link_slta_recv(struct mtp_link *link)
{
	struct msgb *msg;
	unsigned int sls;

	while (!llist_empty(&link->pending_msgs)) {
		msg = msgb_dequeue(&link->pending_msgs);
		sls = (unsigned int) msg->l3h;

		if (mtp_link_submit_sccp_data(link, sls, msg->l2h, msgb_l2len(msg)) != 0)
			LOGP(DMSC, LOGL_ERROR, "Could not forward SCCP message.\n");

		msgb_free(msg);
	}
}

void msc_clear_queue(struct bsc_data *data)
{
	struct msgb *msg;

	LOGP(DMSC, LOGL_NOTICE, "Clearing the MSC to BSC queue.\n");
	while (!llist_empty(&data->link.the_link->pending_msgs)) {
		msg = msgb_dequeue(&data->link.the_link->pending_msgs);
		msgb_free(msg);
	}
}

void msc_close_connection(struct bsc_data *bsc)
{
	struct bsc_fd *bfd = &bsc->msc_connection.bfd;

	close(bfd->fd);
	bsc_unregister_fd(bfd);
	bfd->fd = -1;
	release_bsc_resources(bsc);
	bsc_del_timer(&bsc->ping_timeout);
	bsc_del_timer(&bsc->pong_timeout);
}

static void msc_connect_timeout(void *_bsc_data)
{
	struct bsc_data *bsc_data = _bsc_data;

	LOGP(DMSC, LOGL_ERROR, "Timeout on the MSC connection.\n");
	msc_close_connection(bsc_data);
}

static void msc_pong_timeout(void *_bsc_data)
{
	struct bsc_data *bsc_data = _bsc_data;
	LOGP(DMSC, LOGL_ERROR, "MSC didn't respond to ping. Closing.\n");
	msc_close_connection(bsc_data);
}

static void send_ping(struct bsc_data *bsc)
{
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "ping");
	if (!msg) {
		LOGP(DMSC, LOGL_ERROR, "Failed to create PING.\n");
		return;
	}

	msg->l2h = msgb_put(msg, 1);
	msg->l2h[0] = IPAC_MSGT_PING;

	msc_send(bsc, msg, IPAC_PROTO_IPACCESS);
}

static void msc_ping_timeout(void *_bsc_data)
{
	struct bsc_data *bsc_data = _bsc_data;

	if (bsc_data->ping_time < 0)
		return;

	send_ping(bsc_data);

	/* send another ping in 20 seconds */
	bsc_schedule_timer(&bsc_data->ping_timeout, bsc_data->ping_time, 0);

	/* also start a pong timer */
	bsc_schedule_timer(&bsc_data->pong_timeout, bsc_data->pong_time, 0);
}

/*
 * callback with IP access data
 */
static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
{
	int error;
	struct ipaccess_head *hh;
	struct mtp_link *link;
	struct bsc_data *bsc;
	struct msgb *msg;

	msg = ipaccess_read_msg(bfd, &error);

	bsc = (struct bsc_data *) bfd->data;

	if (!msg) {
		if (error == 0)
			fprintf(stderr, "The connection to the MSC was lost, exiting\n");
		else
			fprintf(stderr, "Error in the IPA stream.\n");

		msc_close_connection(bsc);
		return -1;
	}

	LOGP(DMSC, LOGL_DEBUG, "From MSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);

	/* handle base message handling */
	hh = (struct ipaccess_head *) msg->data;
	ipaccess_rcvmsg_base(msg, bfd);

	link = bsc->link.the_link;

	/* initialize the networking. This includes sending a GSM08.08 message */
	if (hh->proto == IPAC_PROTO_IPACCESS) {
		if (bsc->first_contact) {
			LOGP(DMSC, LOGL_NOTICE, "Connected to MSC. Sending reset.\n");
			bsc_del_timer(&bsc->msc_timeout);
			bsc->first_contact = 0;
			bsc->msc_link_down = 0;
			msc_send_reset(bsc);
		}
		if (msg->l2h[0] == IPAC_MSGT_ID_GET && bsc->token) {
			msc_send_id_response(bsc);
		} else if (msg->l2h[0] == IPAC_MSGT_PONG) {
			bsc_del_timer(&bsc->pong_timeout);
		}
	} else if (hh->proto == IPAC_PROTO_SCCP) {
		struct sccp_parse_result result;
		int rc;
		rc = bss_patch_filter_msg(msg, &result);

		if (rc == BSS_FILTER_RESET_ACK) {
			LOGP(DMSC, LOGL_NOTICE, "Filtering reset ack from the MSC\n");
		} else if (rc == BSS_FILTER_RLSD) {
			LOGP(DMSC, LOGL_DEBUG, "Filtering RLSD from the MSC\n");
			update_con_state(rc, &result, msg, 1, 0);
		} else if (rc == BSS_FILTER_RLC) {
			/* if we receive this we have forwarded a RLSD to the network */
			LOGP(DMSC, LOGL_ERROR, "RLC from the network. BAD!\n");
		} else if (rc == BSS_FILTER_CLEAR_COMPL) {
			LOGP(DMSC, LOGL_ERROR, "Clear Complete from the network.\n");
		} else if (link->sccp_up) {
			unsigned int sls;

			update_con_state(rc, &result, msg, 1, 0);
			sls = sls_for_src_ref(result.destination_local_reference);

			/* patch a possible PC */
			bss_rewrite_header_to_bsc(msg, link->opc, link->dpc);

			/* we can not forward it right now */
			if (link->sltm_pending) {
				LOGP(DMSC, LOGL_NOTICE, "Queueing msg for pending SLTM.\n");
				msg->l3h = (uint8_t *) sls;
				msgb_enqueue(&link->pending_msgs, msg);
				return 0;
			}

			if (mtp_link_submit_sccp_data(link, sls, msg->l2h, msgb_l2len(msg)) != 0)
				LOGP(DMSC, LOGL_ERROR, "Could not forward SCCP message.\n");
		}
	} else if (hh->proto == NAT_MUX) {
		mgcp_forward(bsc, msg->l2h, msgb_l2len(msg));
	} else {
		LOGP(DMSC, LOGL_ERROR, "Unknown IPA proto 0x%x\n", hh->proto);
	}

	msgb_free(msg);
	return 0;
}

static int ipaccess_write_cb(struct bsc_fd *fd, struct msgb *msg)
{
	int rc;

	LOGP(DMSC, LOGL_DEBUG, "Sending to MSC: %s\n", hexdump(msg->data, msg->len));
	rc = write(fd->fd, msg->data, msg->len);
	if (rc != msg->len)
		LOGP(DMSC, LOGL_ERROR, "Could not write to MSC.\n");

	return rc;
}

/* called in the case of a non blocking connect */
static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
{
	int rc;
	int val;
	socklen_t len = sizeof(val);
	struct bsc_data *bsc;

	bsc = (struct bsc_data *) fd->data;

	if (fd != &bsc->msc_connection.bfd) {
		LOGP(DMSC, LOGL_ERROR, "This is only working with the MSC connection.\n");
		return -1;
	}

	if ((what & BSC_FD_WRITE) == 0)
		return -1;

	/* check the socket state */
	rc = getsockopt(fd->fd, SOL_SOCKET, SO_ERROR, &val, &len);
	if (rc != 0) {
		LOGP(DMSC, LOGL_ERROR, "getsockopt for the MSC socket failed.\n");
		goto error;
	}
	if (val != 0) {
		LOGP(DMSC, LOGL_ERROR, "Not connected to the MSC.\n");
		goto error;
	}


	/* go to full operation */
	fd->cb = write_queue_bfd_cb;
	fd->when = BSC_FD_READ;
	if (!llist_empty(&bsc->msc_connection.msg_queue))
		fd->when |= BSC_FD_WRITE;
	return 0;

error:
	msc_close_connection(bsc);
	return -1;
}

static void setnonblocking(struct bsc_fd *fd)
{
	int flags;

	flags = fcntl(fd->fd, F_GETFL);
	if (flags < 0) {
		perror("fcntl get failed");
		close(fd->fd);
		fd->fd = -1;
		return;
	}

	flags |= O_NONBLOCK;
	flags = fcntl(fd->fd, F_SETFL, flags);
	if (flags < 0) {
		perror("fcntl get failed");
		close(fd->fd);
		fd->fd = -1;
		return;
	}
}

static int connect_to_msc(struct bsc_fd *fd, const char *ip, int port, int tos)
{
	struct sockaddr_in sin;
	int on = 1, ret;

	LOGP(DMSC, LOGL_NOTICE, "Attempting to connect MSC at %s:%d\n", ip, port);

	fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (fd->fd < 0) {
		perror("Creating TCP socket failed");
		return fd->fd;
	}

	/* make it non blocking */
	setnonblocking(fd);

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	inet_aton(ip, &sin.sin_addr);

	setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	ret = setsockopt(fd->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
	if (ret != 0)
		LOGP(DMSC, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno));
	ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
	if (ret != 0)
		LOGP(DMSC, LOGL_ERROR, "Failed to set IP_TOS: %s\n", strerror(errno));

	ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));

	if (ret == -1 && errno == EINPROGRESS) {
		LOGP(DMSC, LOGL_ERROR, "MSC Connection in progress\n");
		fd->when = BSC_FD_WRITE;
		fd->cb = msc_connection_connect;
	} else if (ret < 0) {
		perror("Connection failed");
		close(fd->fd);
		fd->fd = -1;
		return ret;
	} else {
		fd->when = BSC_FD_READ;
		fd->cb = write_queue_bfd_cb;
	}

	ret = bsc_register_fd(fd);
	if (ret < 0) {
		perror("Registering the fd failed");
		close(fd->fd);
		fd->fd = -1;
		return ret;
	}

	return ret;
}

static void msc_reconnect(void *_data)
{
	int rc;
	struct bsc_data *bsc = (struct bsc_data *) _data;

	bsc_del_timer(&bsc->reconnect_timer);
	bsc->first_contact = 1;

	rc = connect_to_msc(&bsc->msc_connection.bfd, bsc->msc_address, 5000, bsc->msc_ip_dscp);
	if (rc < 0) {
		fprintf(stderr, "Opening the MSC connection failed. Trying again\n");
		bsc_schedule_timer(&bsc->reconnect_timer, RECONNECT_TIME);
		return;
	}

	bsc->msc_timeout.cb = msc_connect_timeout;
	bsc->msc_timeout.data = bsc;
	bsc_schedule_timer(&bsc->msc_timeout, bsc->msc_time, 0);
}

void msc_schedule_reconnect(struct bsc_data *bsc)
{
	bsc_schedule_timer(&bsc->reconnect_timer, RECONNECT_TIME);
}

/*
 * mgcp forwarding is below
 */
static int mgcp_do_write(struct bsc_fd *fd, struct msgb *msg)
{
	int ret;

	LOGP(DMGCP, LOGL_DEBUG, "Sending msg to MGCP GW size: %u\n", msg->len);

	ret = write(fd->fd, msg->data, msg->len);
	if (ret != msg->len)
		LOGP(DMGCP, LOGL_ERROR, "Failed to forward message to MGCP GW (%s).\n", strerror(errno));

	return ret;
}

static int mgcp_do_read(struct bsc_fd *fd)
{
	struct msgb *mgcp;
	int ret;

	mgcp = msgb_alloc_headroom(4096, 128, "mgcp_from_gw");
	if (!mgcp) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to allocate MGCP message.\n");
		return -1;
	}

	ret = read(fd->fd, mgcp->data, 4096 - 128);
	if (ret <= 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to read: %d/%s\n", errno, strerror(errno));
		msgb_free(mgcp);
		return -1;
	} else if (ret > 4096 - 128) {
		LOGP(DMGCP, LOGL_ERROR, "Too much data: %d\n", ret);
		msgb_free(mgcp);
		return -1; 
        }

	mgcp->l2h = msgb_put(mgcp, ret);
	msc_send(fd->data, mgcp, NAT_MUX);
	return 0;
}

void mgcp_forward(struct bsc_data *bsc, const uint8_t *data, unsigned int length)
{
	struct msgb *mgcp;

	if (length > 4096) {
		LOGP(DMGCP, LOGL_ERROR, "Can not forward too big message.\n");
		return;
	}

	mgcp = msgb_alloc(4096, "mgcp_to_gw");
	if (!mgcp) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to send message.\n");
		return;
	}

	msgb_put(mgcp, length);
	memcpy(mgcp->data, data, mgcp->len);
	if (write_queue_enqueue(&bsc->mgcp_agent, mgcp) != 0) {
		LOGP(DMGCP, LOGL_FATAL, "Could not queue message to MGCP GW.\n");
		msgb_free(mgcp);
	}
}

static int mgcp_create_port(struct bsc_data *bsc)
{
	int on;
	struct sockaddr_in addr;

	bsc->mgcp_agent.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (bsc->mgcp_agent.bfd.fd < 0) {
		LOGP(DMGCP, LOGL_FATAL, "Failed to create UDP socket errno: %d\n", errno);
		return -1;
	}

	on = 1;
	setsockopt(bsc->mgcp_agent.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	/* try to bind the socket */
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	addr.sin_port = 0;

	if (bind(bsc->mgcp_agent.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		LOGP(DMGCP, LOGL_FATAL, "Failed to bind to any port.\n");
		close(bsc->mgcp_agent.bfd.fd);
		bsc->mgcp_agent.bfd.fd = -1;
		return -1;
	}

	/* connect to the remote */
	addr.sin_port = htons(2427);
	if (connect(bsc->mgcp_agent.bfd.fd, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
		LOGP(DMGCP, LOGL_FATAL, "Failed to connect to local MGCP GW. %s\n", strerror(errno));
		close(bsc->mgcp_agent.bfd.fd);
		bsc->mgcp_agent.bfd.fd = -1;
		return -1;
	}

	write_queue_init(&bsc->mgcp_agent, 10);
	bsc->mgcp_agent.bfd.data = bsc;
	bsc->mgcp_agent.bfd.when = BSC_FD_READ;
	bsc->mgcp_agent.read_cb = mgcp_do_read;
	bsc->mgcp_agent.write_cb = mgcp_do_write;

	if (bsc_register_fd(&bsc->mgcp_agent.bfd) != 0) {
		LOGP(DMGCP, LOGL_FATAL, "Failed to register BFD\n");
		close(bsc->mgcp_agent.bfd.fd);
		bsc->mgcp_agent.bfd.fd = -1;
		return -1;
	}

	return 0;
}

int msc_init(struct bsc_data *bsc)
{
	write_queue_init(&bsc->msc_connection, 100);
	bsc->reconnect_timer.cb = msc_reconnect;
	bsc->reconnect_timer.data = bsc;
	bsc->msc_connection.read_cb = ipaccess_a_fd_cb;
	bsc->msc_connection.write_cb = ipaccess_write_cb;
	bsc->msc_connection.bfd.data = bsc;
	bsc->msc_link_down = 1;

	/* handle the timeout */
	bsc->ping_timeout.cb = msc_ping_timeout;
	bsc->ping_timeout.data = bsc;
	bsc->pong_timeout.cb = msc_pong_timeout;
	bsc->pong_timeout.data = bsc;

	/* create MGCP port */
	if (mgcp_create_port(bsc) != 0)
		return -1;
	return 0;
}

static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto)
{
	ipaccess_prepend_header(msg, proto);

	if (write_queue_enqueue(&bsc->msc_connection, msg) != 0) {
		LOGP(DMSC, LOGL_FATAL, "Failed to queue MSG for the MSC.\n");
		msgb_free(msg);
		return;
	}
}

void msc_send_rlc(struct bsc_data *bsc,
		  struct sccp_source_reference *src, struct sccp_source_reference *dst)
{
	struct msgb *msg;

	msg = create_sccp_rlc(src, dst);
	if (!msg)
		return;

	msc_send(bsc, msg, IPAC_PROTO_SCCP);
}

void msc_send_reset(struct bsc_data *bsc)
{
	struct msgb *msg;

	msg = create_reset();
	if (!msg)
		return;

	msc_send(bsc, msg, IPAC_PROTO_SCCP);
	msc_ping_timeout(bsc);
}

static void msc_send_id_response(struct bsc_data *bsc)
{
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "id resp");
	msg->l2h = msgb_v_put(msg, IPAC_MSGT_ID_RESP);
	msgb_l16tv_put(msg, strlen(bsc->token) + 1,
		       IPAC_IDTAG_UNITNAME, (uint8_t *) bsc->token);

	msc_send(bsc, msg, IPAC_PROTO_IPACCESS);
}

void msc_send_msg(struct bsc_data *bsc, int rc, struct sccp_parse_result *result, struct msgb *_msg)
{
	struct msgb *msg;

	if (bsc->msc_connection.bfd.fd < 0) {
		LOGP(DMSC, LOGL_ERROR, "No connection to the MSC. dropping\n");
		return;
	}

	msg = msgb_alloc_headroom(4096, 128, "SCCP to MSC");
	if (!msg) {
		LOGP(DMSC, LOGL_ERROR, "Failed to alloc MSC msg.\n");
		return;
	}

	bss_rewrite_header_for_msc(rc, msg, _msg, result);
	msc_send(bsc, msg, IPAC_PROTO_SCCP);
}
