/* 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 Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <bsc_data.h>
#include <bsc_ussd.h>
#include <bss_patch.h>
#include <bsc_sccp.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_msc_forward *bsc);
static void msc_send(struct bsc_msc_forward *bsc, struct msgb *msg, int proto);
static void msc_schedule_reconnect(struct bsc_msc_forward *bsc);

int send_or_queue_bsc_msg(struct mtp_link_set *link, int sls, struct msgb *msg)
{
	if (mtp_link_set_submit_sccp_data(link, sls, msg->l2h, msgb_l2len(msg)) != 0)
		LOGP(DMSC, LOGL_ERROR, "Could not forward SCCP message.\n");
	return 0;
}

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

	close(bfd->fd);
	bsc_unregister_fd(bfd);
	bfd->fd = -1;
	fw->msc_link_down = 1;
	release_bsc_resources(fw);
	bsc_del_timer(&fw->ping_timeout);
	bsc_del_timer(&fw->pong_timeout);
	bsc_del_timer(&fw->msc_timeout);
	msc_schedule_reconnect(fw);
}

static void msc_connect_timeout(void *_fw_data)
{
	struct bsc_msc_forward *fw = _fw_data;

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

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

static void send_ping(struct bsc_msc_forward *fw)
{
	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(fw, msg, IPAC_PROTO_IPACCESS);
}

static void msc_ping_timeout(void *_fw_data)
{
	struct bsc_msc_forward *fw = _fw_data;

	if (fw->ping_time < 0)
		return;

	send_ping(fw);

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

	/* also start a pong timer */
	bsc_schedule_timer(&fw->pong_timeout, fw->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 bsc_msc_forward *fw;
	struct msgb *msg;

	fw = bfd->data;
	msg = ipaccess_read_msg(bfd, &error);

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

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

		/* we can not forward it right now */
		if (fw->forward_only && fw->bsc->sccp_up) {
			if (send_or_queue_bsc_msg(fw->bsc, -1, msg) != 1)
				msgb_free(msg);
			return 0;
		}


		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(fw, 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 (fw->bsc->sccp_up) {
			unsigned int sls;

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

			/* Check for Location Update Accept */
			bsc_ussd_handle_in_msg(fw, &result, msg);

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

			/* we can not forward it right now */
			if (send_or_queue_bsc_msg(fw->bsc, sls, msg) == 1)
				return 0;

		}
	} else if (hh->proto == NAT_MUX) {
		mgcp_forward(fw, 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_msc_forward *fw;

	fw = fd->data;

	if (fd != &fw->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(&fw->msc_connection.msg_queue))
		fd->when |= BSC_FD_WRITE;
	return 0;

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

static int 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 -1;
	}

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

	return 0;
}

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 */
	if (setnonblocking(fd) != 0)
		return -1;

	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_msc_forward *fw = _data;

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

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

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

static void msc_schedule_reconnect(struct bsc_msc_forward *fw)
{
	bsc_schedule_timer(&fw->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_msc_forward *fw, 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(&fw->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_msc_forward *fw)
{
	int on;
	struct sockaddr_in addr;

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

	on = 1;
	setsockopt(fw->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(fw->mgcp_agent.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		LOGP(DMGCP, LOGL_FATAL, "Failed to bind to any port.\n");
		close(fw->mgcp_agent.bfd.fd);
		fw->mgcp_agent.bfd.fd = -1;
		return -1;
	}

	/* connect to the remote */
	addr.sin_port = htons(2427);
	if (connect(fw->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(fw->mgcp_agent.bfd.fd);
		fw->mgcp_agent.bfd.fd = -1;
		return -1;
	}

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

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

	return 0;
}

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

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

	/* create MGCP port */
	if (mgcp && mgcp_create_port(fw) != 0)
		return -1;

	/* now connect to the BSC */
	msc_schedule_reconnect(fw);
	return 0;
}

static void msc_send(struct bsc_msc_forward *fw, struct msgb *msg, int proto)
{
	if (fw->msc_link_down) {
		LOGP(DMSC, LOGL_NOTICE, "Dropping data due lack of MSC connection.\n");
		msgb_free(msg);
		return;
	}

	ipaccess_prepend_header(msg, proto);

	if (write_queue_enqueue(&fw->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_msc_forward *fw,
		  struct sccp_source_reference *src, struct sccp_source_reference *dst)
{
	struct msgb *msg;

	if (fw->msc_link_down) {
		LOGP(DMSC, LOGL_NOTICE, "Not releasing connection due lack of connection.\n");
		return;
	}

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

	msc_send(fw, msg, IPAC_PROTO_SCCP);
}

void msc_send_reset(struct bsc_msc_forward *fw)
{
	struct msgb *msg;

	if (fw->msc_link_down) {
		LOGP(DMSC, LOGL_NOTICE, "Not sending reset due lack of connection.\n");
		return;
	}

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

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

static void msc_send_id_response(struct bsc_msc_forward *fw)
{
	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(fw->token) + 1,
		       IPAC_IDTAG_UNITNAME, (uint8_t *) fw->token);

	msc_send(fw, msg, IPAC_PROTO_IPACCESS);
}

void msc_send_direct(struct bsc_msc_forward *fw, struct msgb *msg)
{
	return msc_send(fw, msg, IPAC_PROTO_SCCP);
}

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

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

	bsc_ussd_handle_out_msg(fw, result, _msg);

	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(fw, msg, IPAC_PROTO_SCCP);
}
