/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/* The protocol implementation */

/*
 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009 by on-waves.com
 * 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 <arpa/inet.h>

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

#include <vty/command.h>
#include <vty/vty.h>

#warning "Make use of the rtp proxy code"

static int source_port = 2427;
static const char *local_ip = NULL;
static const char *source_addr = "0.0.0.0";
static unsigned int number_endpoints = 0;
static const char *bts_ip = NULL;
static struct in_addr bts_in;
static const char *audio_name = "GSM-EFR/8000";
static int audio_payload = 97;
static int audio_loop = 0;
static int early_bind = 0;

static char *forward_ip = NULL;
static int forward_port = 0;

enum mgcp_connection_mode {
	MGCP_CONN_NONE = 0,
	MGCP_CONN_RECV_ONLY = 1,
	MGCP_CONN_SEND_ONLY = 2,
	MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
};

enum {
	DEST_NETWORK = 0,
	DEST_BTS = 1,
};

enum {
	PROTO_RTP,
	PROTO_RTCP,
};

#define CI_UNUSED 0
static unsigned int last_call_id = 0;

struct mgcp_endpoint {
	int ci;
	char *callid;
	char *local_options;
	int conn_mode;

	/* the local rtp port we are binding to */
	int rtp_port;

	/*
	 * RTP mangling:
	 *  - we get RTP and RTCP to us and need to forward to the BTS
	 *  - we get RTP and RTCP from the BTS and forward to the network
	 */
	struct bsc_fd local_rtp;
	struct bsc_fd local_rtcp;

	struct in_addr remote;
	struct in_addr bts;

	/* in network byte order */
	int net_rtp, net_rtcp;
	int bts_rtp, bts_rtcp;
};

static struct mgcp_endpoint *endpoints = NULL;
#define ENDPOINT_NUMBER(endp) abs(endp - endpoints)

/**
 * Macro for tokenizing MGCP messages and SDP in one go.
 *
 */
#define MSG_TOKENIZE_START \
	line_start = 0;						\
	for (i = 0; i < msgb_l3len(msg); ++i) {			\
		/* we have a line end */			\
		if (msg->l3h[i] == '\n') {			\
			/* skip the first line */		\
			if (line_start == 0) {			\
				line_start = i + 1;		\
				continue;			\
			}					\
								\
			/* check if we have a proper param */	\
			if (i - line_start == 1 && msg->l3h[line_start] == '\r') { \
			} else if (i - line_start > 2		\
			    && islower(msg->l3h[line_start])	\
			    && msg->l3h[line_start + 1] == '=') { \
			} else if (i - line_start < 3		\
			    || msg->l3h[line_start + 1] != ':'	\
			    || msg->l3h[line_start + 2] != ' ')	\
				goto error;			\
								\
			msg->l3h[i] = '\0';			\
			if (msg->l3h[i-1] == '\r')		\
				msg->l3h[i-1] = '\0';

#define MSG_TOKENIZE_END \
			line_start = i + 1; \
		}			    \
	}


struct mgcp_msg_ptr {
	unsigned int start;
	unsigned int length;
};

struct mgcp_request {
	char *name;
	int (*handle_request) (int fd, struct msgb *msg, struct sockaddr_in *source);
	char *debug_name;
};

#define MGCP_REQUEST(NAME, REQ, DEBUG_NAME) \
	{ .name = NAME, .handle_request = REQ, .debug_name = DEBUG_NAME },

static int handle_audit_endpoint(int fd, struct msgb *msg, struct sockaddr_in *source);
static int handle_create_con(int fd, struct msgb *msg, struct sockaddr_in *source);
static int handle_delete_con(int fd, struct msgb *msg, struct sockaddr_in *source);
static int handle_modify_con(int fd, struct msgb *msg, struct sockaddr_in *source);

static mgcp_change change_cb;
static void *change_cb_data;

static int generate_call_id()
{
	int i;

	/* use the call id */
	++last_call_id;

	/* handle wrap around */
	if (last_call_id == CI_UNUSED)
		++last_call_id;

	/* callstack can only be of size number_of_endpoints */
	/* verify that the call id is free, e.g. in case of overrun */
	for (i = 1; i < number_endpoints; ++i)
		if (endpoints[i].ci == last_call_id)
			return generate_call_id();

	return last_call_id;
}

/* FIXIME/TODO: need to have a list of pending transactions and check that */
static unsigned int generate_transaction_id()
{
	return abs(rand());
}

static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
{
	struct sockaddr_in out;
	out.sin_family = AF_INET;
	out.sin_port = port;
	memcpy(&out.sin_addr, addr, sizeof(*addr));

	return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
}

/*
 * There is data coming. We will have to figure out if it
 * came from the BTS or the MediaGateway of the MSC. On top
 * of that we need to figure out if it was RTP or RTCP.
 *
 * Currently we do not communicate with the BSC so we have
 * no idea where the BTS is listening for RTP and need to
 * do the classic routing trick. Wait for the first packet
 * from the BTS and then go ahead.
 */
static int rtp_data_cb(struct bsc_fd *fd, unsigned int what)
{
	char buf[4096];
	struct sockaddr_in addr;
	socklen_t slen = sizeof(addr);
	struct mgcp_endpoint *endp;
	int rc, dest, proto;

	endp = (struct mgcp_endpoint *) fd->data;

	rc = recvfrom(fd->fd, &buf, sizeof(buf), 0,
			    (struct sockaddr *) &addr, &slen);
	if (rc < 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x\n",
			ENDPOINT_NUMBER(endp));
		return -1;
	}

	/* do not forward aynthing... maybe there is a packet from the bts */
	if (endp->ci == CI_UNUSED) {
		LOGP(DMGCP, LOGL_ERROR, "Unknown message on endpoint: 0x%x\n", ENDPOINT_NUMBER(endp));
		return -1;
	}

	/*
	 * Figure out where to forward it to. This code assumes that we
	 * have received the Connection Modify and know who is a legitimate
	 * partner. According to the spec we could attempt to forward even
	 * after the Create Connection but we will not as we are not really
	 * able to tell if this is legitimate.
	 */
	#warning "Slight spec violation. With connection mode recvonly we should attempt to forward."
	dest = memcmp(&addr.sin_addr, &endp->remote, sizeof(addr.sin_addr)) == 0 &&
                    (endp->net_rtp == addr.sin_port || endp->net_rtcp == addr.sin_port)
			? DEST_BTS : DEST_NETWORK;
	proto = fd == &endp->local_rtp ? PROTO_RTP : PROTO_RTCP;

	/* We have no idea who called us, maybe it is the BTS. */
	if (dest == DEST_NETWORK && (endp->bts_rtp == 0 || forward_ip)) {
		/* it was the BTS... */
		if (!bts_ip || memcmp(&addr.sin_addr, &bts_in, sizeof(bts_in)) == 0) {
			if (fd == &endp->local_rtp) {
				endp->bts_rtp = addr.sin_port;
			} else {
				endp->bts_rtcp = addr.sin_port;
			}

			endp->bts = addr.sin_addr;
			LOGP(DMGCP, LOGL_NOTICE, "Found BTS for endpoint: 0x%x on port: %d/%d\n",
				ENDPOINT_NUMBER(endp), ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp));
		}
	}

	/* dispatch */
	if (audio_loop)
		dest = !dest;

	if (dest == DEST_NETWORK) {
		return udp_send(fd->fd, &endp->remote,
			     proto == PROTO_RTP ? endp->net_rtp : endp->net_rtcp,
			     buf, rc);
	} else {
		return udp_send(fd->fd, &endp->bts,
			     proto == PROTO_RTP ? endp->bts_rtp : endp->bts_rtcp,
			     buf, rc);
	}
}

static int create_bind(struct bsc_fd *fd, int port)
{
	struct sockaddr_in addr;
	int on = 1;

	fd->fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd->fd < 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to create UDP port.\n");
		return -1;
	}

	setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	inet_aton(source_addr, &addr.sin_addr);

	if (bind(fd->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		return -1;
	}

	return 0;
}

static int bind_rtp(struct mgcp_endpoint *endp)
{
	if (create_bind(&endp->local_rtp, endp->rtp_port) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
		       source_addr, endp->rtp_port, ENDPOINT_NUMBER(endp));
		goto cleanup0;
	}

	if (create_bind(&endp->local_rtcp, endp->rtp_port + 1) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
		       source_addr, endp->rtp_port + 1, ENDPOINT_NUMBER(endp));
		goto cleanup1;
	}

	endp->local_rtp.cb = rtp_data_cb;
	endp->local_rtp.data = endp;
	endp->local_rtp.when = BSC_FD_READ;
	if (bsc_register_fd(&endp->local_rtp) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTP port %d on 0x%x\n",
			endp->rtp_port, ENDPOINT_NUMBER(endp));
		goto cleanup2;
	}

	endp->local_rtcp.cb = rtp_data_cb;
	endp->local_rtcp.data = endp;
	endp->local_rtcp.when = BSC_FD_READ;
	if (bsc_register_fd(&endp->local_rtcp) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTCP port %d on 0x%x\n",
			endp->rtp_port + 1, ENDPOINT_NUMBER(endp));
		goto cleanup3;
	}

	return 0;

cleanup3:
	bsc_unregister_fd(&endp->local_rtp);
cleanup2:
	close(endp->local_rtcp.fd);
	endp->local_rtcp.fd = -1;
cleanup1:
	close(endp->local_rtp.fd);
	endp->local_rtp.fd = -1;
cleanup0:
	return -1;
}

/*
 * array of function pointers for handling various
 * messages. In the future this might be binary sorted
 * for performance reasons.
 */
static const struct mgcp_request mgcp_requests [] = {
	MGCP_REQUEST("AUEP", handle_audit_endpoint, "AuditEndpoint")
	MGCP_REQUEST("CRCX", handle_create_con, "CreateConnection")
	MGCP_REQUEST("DLCX", handle_delete_con, "DeleteConnection")
	MGCP_REQUEST("MDCX", handle_modify_con, "ModifiyConnection")
};

static int send_response_with_data(int fd, int code, const char *msg, const char *trans,
				    const char *data, struct sockaddr_in *source)
{
	char buf[4096];
	int len;

	if (data) {
		len = snprintf(buf, sizeof(buf), "%d %s\n%s", code, trans, data);
	} else {
		len = snprintf(buf, sizeof(buf), "%d %s\n", code, trans);
	}
	LOGP(DMGCP, LOGL_NOTICE, "Sending response: code: %d for '%s'\n", code, msg);

	if (source)
		return sendto(fd, buf, len, 0, (struct sockaddr *)source, sizeof(*source));
	else
		return write(fd, buf, len);
}

static int send_response(int fd, int code, const char *msg,
			  const char *trans, struct sockaddr_in *source)
{
	return send_response_with_data(fd, code, msg, trans, NULL, source);
}

static int send_with_sdp(int fd, struct mgcp_endpoint *endp, const char *msg, const char *trans_id, struct sockaddr_in *source)
{
	const char *addr = local_ip;
	char sdp_record[4096];

	if (!addr)
		addr = source_addr;

	snprintf(sdp_record, sizeof(sdp_record) - 1,
			"I: %d\n\n"
			"v=0\r\n"
			"c=IN IP4 %s\r\n"
			"m=audio %d RTP/AVP %d\r\n"
			"a=rtpmap:%d %s\r\n",
			endp->ci, addr, endp->rtp_port,
			audio_payload, audio_payload, audio_name);
	return send_response_with_data(fd, 200, msg, trans_id, sdp_record, source);
}

/* send a static record */
int mgcp_send_rsip(int fd, struct sockaddr_in *source)
{
	char reset[4096];
	int len, rc;

	len = snprintf(reset, sizeof(reset) - 1,
			"RSIP %u *@mgw MGCP 1.0\n"
			"RM: restart\n", generate_transaction_id());
	if (source)
		rc = sendto(fd, reset, len, 0, (struct sockaddr *) source, sizeof(*source));
	else
		rc = write(fd, reset, len);

	if (rc < 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to send RSIP: %d\n", rc);
	}

	return rc;
}

/*
 * handle incoming messages:
 *   - this can be a command (four letters, space, transaction id)
 *   - or a response (three numbers, space, transaction id)
 */
int mgcp_handle_message(int fd, struct msgb *msg, struct sockaddr_in *source)
{
        int code;

	if (msg->len < 4) {
		LOGP(DMGCP, LOGL_ERROR, "mgs too short: %d\n", msg->len);
		return -1;
	}

        /* attempt to treat it as a response */
        if (sscanf((const char *)&msg->data[0], "%3d %*s", &code) == 1) {
		LOGP(DMGCP, LOGL_NOTICE, "Response: Code: %d\n", code);
	} else {
		int i, handled = 0;
		msg->l3h = &msg->l2h[4];
		for (i = 0; i < ARRAY_SIZE(mgcp_requests); ++i)
			if (strncmp(mgcp_requests[i].name, (const char *) &msg->data[0], 4) == 0) {
				handled = 1;
				mgcp_requests[i].handle_request(fd, msg, source);
			}
		if (!handled) {
			LOGP(DMGCP, LOGL_NOTICE, "MSG with type: '%.4s' not handled\n", &msg->data[0]);
		}
	}

	return 0;
}

/* string tokenizer for the poor */
static int find_msg_pointers(struct msgb *msg, struct mgcp_msg_ptr *ptrs, int ptrs_length)
{
	int i, found = 0;

	int whitespace = 1;
	for (i = 0; i < msgb_l3len(msg) && ptrs_length > 0; ++i) {
		/* if we have a space we found an end */
		if (msg->l3h[i]	== ' ' || msg->l3h[i] == '\r' || msg->l3h[i] == '\n') {
			if (!whitespace) {
				++found;
				whitespace = 1;
				ptrs->length = i - ptrs->start - 1;
				++ptrs;
				--ptrs_length;
			} else {
			    /* skip any number of whitespace */
			}

			/* line end... stop */
			if (msg->l3h[i] == '\r' || msg->l3h[i] == '\n')
				break;
		} else if (msg->l3h[i] == '\r' || msg->l3h[i] == '\n') {
			/* line end, be done */
			break;
		} else if (whitespace) {
			whitespace = 0;
			ptrs->start = i;
		}
	}

	if (ptrs_length == 0)
		return -1;
	return found;
}

static struct mgcp_endpoint *find_endpoint(const char *mgcp)
{
	char *endptr = NULL;
	unsigned int gw = INT_MAX;

	gw = strtoul(mgcp, &endptr, 16);
	if (gw == 0 || gw >= number_endpoints || strcmp(endptr, "@mgw") != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Not able to find endpoint: '%s'\n", mgcp);
		return NULL;
	}

	return &endpoints[gw];
}

static int analyze_header(struct msgb *msg, struct mgcp_msg_ptr *ptr, int size,
			  const char **transaction_id, struct mgcp_endpoint **endp)
{
	int found;

	if (size < 3) {
		LOGP(DMGCP, LOGL_ERROR, "Not enough space in ptr\n");
		return -1;
	}

	found = find_msg_pointers(msg, ptr, size);

	if (found < 3) {
		LOGP(DMGCP, LOGL_ERROR, "Gateway: Not enough params. Found: %d\n", found);
		return -1;
	}

	/*
	 * replace the space with \0. the main method gurantess that
	 * we still have + 1 for null termination
	 */
	msg->l3h[ptr[3].start + ptr[3].length + 1] = '\0';
	msg->l3h[ptr[2].start + ptr[2].length + 1] = '\0';
	msg->l3h[ptr[1].start + ptr[1].length + 1] = '\0';
	msg->l3h[ptr[0].start + ptr[0].length + 1] = '\0';

	if (strncmp("1.0", (const char *)&msg->l3h[ptr[3].start], 3) != 0
	    || strncmp("MGCP", (const char *)&msg->l3h[ptr[2].start], 4) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Wrong MGCP version. Not handling: '%s' '%s'\n",
			(const char *)&msg->l3h[ptr[3].start],
			(const char *)&msg->l3h[ptr[2].start]);
		return -1;
	}

	*transaction_id = (const char *)&msg->l3h[ptr[0].start];
	*endp = find_endpoint((const char *)&msg->l3h[ptr[1].start]);
	return *endp == NULL;
}

static int verify_call_id(const struct mgcp_endpoint *endp,
			  const char *callid)
{
	if (strcmp(endp->callid, callid) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "CallIDs does not match on 0x%x. '%s' != '%s'\n",
			ENDPOINT_NUMBER(endp), endp->callid, callid);
		return -1;
	}

	return 0;
}

static int verify_ci(const struct mgcp_endpoint *endp,
		     const char *ci)
{
	if (atoi(ci) != endp->ci) {
		LOGP(DMGCP, LOGL_ERROR, "ConnectionIdentifiers do not match on 0x%x. %d != %s\n",
			ENDPOINT_NUMBER(endp), endp->ci, ci);
		return -1;
	}

	return 0;
}

static int handle_audit_endpoint(int fd, struct msgb *msg, struct sockaddr_in *source)
{
	struct mgcp_msg_ptr data_ptrs[6];
	int found, response;
	const char *trans_id;
	struct mgcp_endpoint *endp;

	found = analyze_header(msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
	if (found != 0)
	    response = 500;
	else
	    response = 200;

	return send_response(fd, response, "AUEP", trans_id, source);
}

static int parse_conn_mode(const char* msg, int *conn_mode)
{
	int ret = 0;
	if (strcmp(msg, "recvonly") == 0)
		*conn_mode = MGCP_CONN_RECV_ONLY;
	else if (strcmp(msg, "sendrecv") == 0)
		*conn_mode = MGCP_CONN_RECV_SEND;
	else {
		LOGP(DMGCP, LOGL_ERROR, "Unknown connection mode: '%s'\n", msg);
		ret = -1;
	}

	return ret;
}

static int handle_create_con(int fd, struct msgb *msg, struct sockaddr_in *source)
{
	struct mgcp_msg_ptr data_ptrs[6];
	int found, i, line_start;
	const char *trans_id;
	struct mgcp_endpoint *endp;
	int error_code = 500;

	found = analyze_header(msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
	if (found != 0)
		return send_response(fd, 500, "CRCX", trans_id, source);

	if (endp->ci != CI_UNUSED) {
		LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n", ENDPOINT_NUMBER(endp));
		return send_response(fd, 500, "CRCX", trans_id, source);
	}

	/* parse CallID C: and LocalParameters L: */
	MSG_TOKENIZE_START
	switch (msg->l3h[line_start]) {
	case 'L':
		endp->local_options = talloc_strdup(endpoints,
			(const char *)&msg->l3h[line_start + 3]);
		break;
	case 'C':
		endp->callid = talloc_strdup(endpoints,
			(const char *)&msg->l3h[line_start + 3]);
		break;
	case 'M':
		if (parse_conn_mode((const char *)&msg->l3h[line_start + 3],
			    &endp->conn_mode) != 0) {
		    error_code = 517;
		    goto error2;
		}
		break;
	default:
		LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n",
			msg->l3h[line_start], msg->l3h[line_start],
			ENDPOINT_NUMBER(endp));
		break;
	}
	MSG_TOKENIZE_END

	/* initialize */
	endp->net_rtp = endp->net_rtcp = endp->bts_rtp = endp->bts_rtcp = 0;

	/* set to zero until we get the info */
	memset(&endp->remote, 0, sizeof(endp->remote));

	/* bind to the port now */
	endp->rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp), rtp_base_port);
	if (!early_bind && bind_rtp(endp) != 0)
		goto error2;

	/* assign a local call identifier or fail */
	endp->ci = generate_call_id();
	if (endp->ci == CI_UNUSED)
		goto error2;

	LOGP(DMGCP, LOGL_NOTICE, "Creating endpoint on: 0x%x CI: %u port: %u\n",
		ENDPOINT_NUMBER(endp), endp->ci, endp->rtp_port);
	if (change_cb)
		change_cb(ENDPOINT_NUMBER(endp), MGCP_ENDP_CRCX, endp->rtp_port, change_cb_data);

	return send_with_sdp(fd, endp, "CRCX", trans_id, source);
error:
	LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d\n",
		    hexdump(msg->l3h, msgb_l3len(msg)),
		    ENDPOINT_NUMBER(endp), line_start, i);
	return send_response(fd, error_code, "CRCX", trans_id, source);

error2:
	LOGP(DMGCP, LOGL_NOTICE, "Resource error on 0x%x\n", ENDPOINT_NUMBER(endp));
	return send_response(fd, error_code, "CRCX", trans_id, source);
}

static int handle_modify_con(int fd, struct msgb *msg, struct sockaddr_in *source)
{
	struct mgcp_msg_ptr data_ptrs[6];
	int found, i, line_start;
	const char *trans_id;
	struct mgcp_endpoint *endp;
	int error_code = 500;

	found = analyze_header(msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
	if (found != 0)
		return send_response(fd, error_code, "MDCX", trans_id, source);

	if (endp->ci == CI_UNUSED) {
		LOGP(DMGCP, LOGL_ERROR, "Endpoint is not holding a connection. 0x%x\n", ENDPOINT_NUMBER(endp));
		return send_response(fd, error_code, "MDCX", trans_id, source);
	}

	MSG_TOKENIZE_START
	switch (msg->l3h[line_start]) {
	case 'C': {
		if (verify_call_id(endp, (const char *)&msg->l3h[line_start + 3]) != 0)
			goto error3;
		break;
	}
	case 'I': {
		if (verify_ci(endp, (const char *)&msg->l3h[line_start + 3]) != 0)
			goto error3;
		break;
	}
	case 'L':
		/* skip */
		break;
	case 'M':
		if (parse_conn_mode((const char *)&msg->l3h[line_start + 3],
			    &endp->conn_mode) != 0) {
		    error_code = 517;
		    goto error3;
		}
		break;
	case '\0':
		/* SDP file begins */
		break;
	case 'a':
	case 'o':
	case 's':
	case 't':
	case 'v':
		/* skip these SDP attributes */
		break;
	case 'm': {
		int port;
		const char *param = (const char *)&msg->l3h[line_start];

		if (sscanf(param, "m=audio %d RTP/AVP %*d", &port) == 1) {
			endp->net_rtp = htons(port);
			endp->net_rtcp = htons(port + 1);
		}
		break;
	}
	case 'c': {
		char ipv4[16];
		const char *param = (const char *)&msg->l3h[line_start];

		if (sscanf(param, "c=IN IP4 %15s", ipv4) == 1) {
			inet_aton(ipv4, &endp->remote);
		}
		break;
	}
	default:
		LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n",
			msg->l3h[line_start], msg->l3h[line_start],
			ENDPOINT_NUMBER(endp));
		break;
	}
	MSG_TOKENIZE_END

	/* modify */
	LOGP(DMGCP, LOGL_NOTICE, "Modified endpoint on: 0x%x Server: %s:%u\n",
		ENDPOINT_NUMBER(endp), inet_ntoa(endp->remote), endp->net_rtp);
	if (change_cb)
		change_cb(ENDPOINT_NUMBER(endp), MGCP_ENDP_MDCX, endp->rtp_port, change_cb_data);
	return send_with_sdp(fd, endp, "MDCX", trans_id, source);

error:
	LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d %d\n",
		    hexdump(msg->l3h, msgb_l3len(msg)),
		    ENDPOINT_NUMBER(endp), line_start, i, msg->l3h[line_start]);
	return send_response(fd, error_code, "MDCX", trans_id, source);

error3:
	return send_response(fd, error_code, "MDCX", trans_id, source);
}

static int handle_delete_con(int fd, struct msgb *msg, struct sockaddr_in *source)
{
	struct mgcp_msg_ptr data_ptrs[6];
	int found, i, line_start;
	const char *trans_id;
	struct mgcp_endpoint *endp;
	int error_code = 500;

	found = analyze_header(msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
	if (found != 0)
		return send_response(fd, error_code, "DLCX", trans_id, source);

	if (endp->ci == CI_UNUSED) {
		LOGP(DMGCP, LOGL_ERROR, "Endpoint is not used. 0x%x\n", ENDPOINT_NUMBER(endp));
		return send_response(fd, error_code, "DLCX", trans_id, source);
	}

	MSG_TOKENIZE_START
	switch (msg->l3h[line_start]) {
	case 'C': {
		if (verify_call_id(endp, (const char *)&msg->l3h[line_start + 3]) != 0)
			goto error3;
		break;
	}
	case 'I': {
		if (verify_ci(endp, (const char *)&msg->l3h[line_start + 3]) != 0)
			goto error3;
		break;
	}
	default:
		LOGP(DMGCP, LOGL_NOTICE, "Unhandled option: '%c'/%d on 0x%x\n",
			msg->l3h[line_start], msg->l3h[line_start],
			ENDPOINT_NUMBER(endp));
		break;
	}
	MSG_TOKENIZE_END


	/* free the connection */
	LOGP(DMGCP, LOGL_NOTICE, "Deleting endpoint on: 0x%x\n", ENDPOINT_NUMBER(endp));
	endp->ci= CI_UNUSED;
	talloc_free(endp->callid);
	talloc_free(endp->local_options);

	if (!early_bind) {
		bsc_unregister_fd(&endp->local_rtp);
		bsc_unregister_fd(&endp->local_rtcp);
	}

	endp->net_rtp = endp->net_rtcp = endp->bts_rtp = endp->bts_rtcp = 0;
	if (change_cb)
		change_cb(ENDPOINT_NUMBER(endp), MGCP_ENDP_DLCX, endp->rtp_port, change_cb_data);

	return send_response(fd, 250, "DLCX", trans_id, source);

error:
	LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d\n",
		    hexdump(msg->l3h, msgb_l3len(msg)),
		    ENDPOINT_NUMBER(endp), line_start, i);
	return send_response(fd, error_code, "DLCX", trans_id, source);

error3:
	return send_response(fd, error_code, "DLCX", trans_id, source);
}

/*
 * vty code for mgcp below
 */
struct cmd_node mgcp_node = {
	MGCP_NODE,
	"%s(mgcp)#",
	1,
};

static int config_write_mgcp(struct vty *vty)
{
	vty_out(vty, "mgcp%s", VTY_NEWLINE);
	if (local_ip)
		vty_out(vty, " local ip %s%s", local_ip, VTY_NEWLINE);
	if (bts_ip)
		vty_out(vty, "  bts ip %s%s", bts_ip, VTY_NEWLINE);
	vty_out(vty, "  bind ip %s%s", source_addr, VTY_NEWLINE);
	vty_out(vty, "  bind port %u%s", source_port, VTY_NEWLINE);
	vty_out(vty, "  bind early %u%s", !!early_bind, VTY_NEWLINE);
	vty_out(vty, "  rtp base %u%s", rtp_base_port, VTY_NEWLINE);
	vty_out(vty, "  sdp audio payload number %u%s", audio_payload, VTY_NEWLINE);
	vty_out(vty, "  sdp audio payload name %s%s", audio_name, VTY_NEWLINE);
	vty_out(vty, "  loop %u%s", !!audio_loop, VTY_NEWLINE);
	vty_out(vty, "  endpoints %u%s", number_endpoints, VTY_NEWLINE);
	if (forward_ip)
		vty_out(vty, " forward audio ip %s%s", forward_ip, VTY_NEWLINE);
	if (forward_port != 0)
		vty_out(vty, " forward audio port %d%s", forward_port, VTY_NEWLINE);

	return CMD_SUCCESS;
}

DEFUN(show_mcgp, show_mgcp_cmd, "show mgcp",
      SHOW_STR "Display information about the MGCP Media Gateway")
{
	int i;

	vty_out(vty, "MGCP is up and running with %u endpoints:%s", number_endpoints - 1, VTY_NEWLINE);
	for (i = 1; i < number_endpoints; ++i) {
		struct mgcp_endpoint *endp = &endpoints[i];
		vty_out(vty, " Endpoint 0x%.2x: CI: %d net: %u/%u bts: %u/%u%s",
			i, endp->ci,
			ntohs(endp->net_rtp), ntohs(endp->net_rtcp),
			ntohs(endp->bts_rtp), ntohs(endp->bts_rtcp), VTY_NEWLINE);
	}

	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp,
      cfg_mgcp_cmd,
      "mgcp",
      "Configure the MGCP")
{
	vty->node = MGCP_NODE;
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_local_ip,
      cfg_mgcp_local_ip_cmd,
      "local ip IP",
      "Set the IP to be used in SDP records")
{
	local_ip = talloc_strdup(tall_bsc_ctx, argv[0]);
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_bts_ip,
      cfg_mgcp_bts_ip_cmd,
      "bts ip IP",
      "Set the IP of the BTS for RTP forwarding")
{
	bts_ip = talloc_strdup(tall_bsc_ctx, argv[0]);
	inet_aton(bts_ip, &bts_in);
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_bind_ip,
      cfg_mgcp_bind_ip_cmd,
      "bind ip IP",
      "Bind the MGCP to this local addr")
{
	source_addr = talloc_strdup(tall_bsc_ctx, argv[0]);
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_bind_port,
      cfg_mgcp_bind_port_cmd,
      "bind port <0-65534>",
      "Bind the MGCP to this port")
{
	unsigned int port = atoi(argv[0]);
	if (port > 65534) {
		vty_out(vty, "%% wrong bind port '%s'%s", argv[0], VTY_NEWLINE);
		return CMD_WARNING;
	}

	source_port = port;
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_bind_early,
      cfg_mgcp_bind_early_cmd,
      "bind early (0|1)",
      "Bind all RTP ports early")
{
	unsigned int bind = atoi(argv[0]);
	if (bind != 0 && bind != 1) {
		vty_out(vty, "%% param must be 0 or 1.%s", VTY_NEWLINE);
		return CMD_WARNING;
	}

	early_bind = bind == 1;
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_rtp_base_port,
      cfg_mgcp_rtp_base_port_cmd,
      "rtp base <0-65534>",
      "Base port to use")
{
	unsigned int port = atoi(argv[0]);
	if (port > 65534) {
		vty_out(vty, "%% wrong base port '%s'%s", argv[0], VTY_NEWLINE);
		return CMD_WARNING;
	}

	rtp_base_port = port;
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_sdp_payload_number,
      cfg_mgcp_sdp_payload_number_cmd,
      "sdp audio payload number <1-255>",
      "Set the audio codec to use")
{
	unsigned int payload = atoi(argv[0]);
	if (payload > 255) {
		vty_out(vty, "%% wrong payload number '%s'%s", argv[0], VTY_NEWLINE);
		return CMD_WARNING;
	}

	audio_payload = payload;
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_sdp_payload_name,
      cfg_mgcp_sdp_payload_name_cmd,
      "sdp audio payload name NAME",
      "Set the audio name to use")
{
	audio_name = talloc_strdup(tall_bsc_ctx, argv[0]);
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_loop,
      cfg_mgcp_loop_cmd,
      "loop (0|1)",
      "Loop the audio")
{
	audio_loop = atoi(argv[0]);
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_number_endp,
      cfg_mgcp_number_endp_cmd,
      "number endpoints <0-65534>",
      "The number of endpoints to allocate. This is not dynamic.")
{
	/* + 1 as we start counting at one */
	number_endpoints = atoi(argv[0]) + 1;
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_forward_ip,
      cfg_mgcp_forward_ip_cmd,
      "forward audio ip IP",
      "Forward packets from and to the IP. This disables most of the MGCP feature.")
{
	if (forward_ip)
		talloc_free(forward_ip);
	forward_ip = talloc_strdup(tall_bsc_ctx, argv[0]);
	return CMD_SUCCESS;
}

DEFUN(cfg_mgcp_forward_port,
      cfg_mgcp_forward_port_cmd,
      "forward audio port <1-15000>",
      "Forward packets from and to the port. This disables most of the MGCP feature.")
{
	forward_port = atoi(argv[0]);
	return CMD_SUCCESS;
}

int mgcp_vty_init(void)
{
	install_element(VIEW_NODE, &show_mgcp_cmd);

	install_element(CONFIG_NODE, &cfg_mgcp_cmd);
	install_node(&mgcp_node, config_write_mgcp);
	install_default(MGCP_NODE);
	install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_bts_ip_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_bind_port_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_bind_early_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_rtp_base_port_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_number_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_name_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_loop_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_number_endp_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_forward_ip_cmd);
	install_element(MGCP_NODE, &cfg_mgcp_forward_port_cmd);
	return 0;
}

int mgcp_parse_config(const char *config_file, struct gsm_network *dummy_network)
{
	int i, rc;

	rc = vty_read_config_file(config_file);
	if (rc < 0) {
		fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
		return rc;
	}


	if (!bts_ip)
		fprintf(stderr, "No BTS ip address specified. This will allow everyone to connect.\n");

	endpoints = _talloc_zero_array(tall_bsc_ctx,
				       sizeof(struct mgcp_endpoint),
				       number_endpoints, "endpoints");
	if (!endpoints) {
		fprintf(stderr, "Failed to allocate endpoints: %d. Quitting.\n", number_endpoints);
		return -1;
	}

	/* Initialize all endpoints */
	for (i = 0; i < number_endpoints; ++i) {
		endpoints[i].local_rtp.fd = -1;
		endpoints[i].local_rtcp.fd = -1;
		endpoints[i].ci = CI_UNUSED;
	}

	/*
	 * This application supports two modes.
         *    1.) a true MGCP gateway with support for AUEP, CRCX, MDCX, DLCX
         *    2.) plain forwarding of RTP packets on the endpoints.
	 * both modes are mutual exclusive
	 */
	if (forward_ip) {
		int port = rtp_base_port;
		if (forward_port != 0)
			port = forward_port;

		if (!early_bind) {
			LOGP(DMGCP, LOGL_NOTICE, "Forwarding requires early bind.\n");
			return -1;
		}

		/*
		 * Store the forward IP and assign a ci. For early bind
		 * the sockets will be created after this.
		 */
		for (i = 1; i < number_endpoints; ++i) {
			struct mgcp_endpoint *endp = &endpoints[i];
			inet_aton(forward_ip, &endp->remote);
			endp->ci = CI_UNUSED + 23;
			endp->net_rtp = htons(rtp_calculate_port(ENDPOINT_NUMBER(endp), port));
			endp->net_rtcp = htons(rtp_calculate_port(ENDPOINT_NUMBER(endp), port) + 1);
		}

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

	/* early bind */
	if (early_bind) {
		for (i = 1; i < number_endpoints; ++i) {
			struct mgcp_endpoint *endp = &endpoints[i];
			endp->rtp_port = rtp_calculate_port(ENDPOINT_NUMBER(endp), rtp_base_port);
			if (bind_rtp(endp) != 0) {
				LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", endp->rtp_port);
				return -1;
			}
		}
	}

	return !!forward_ip;
}

void mgcp_set_change_cb(mgcp_change cb, void *data)
{
	change_cb = cb;
	change_cb_data = data;
}
