/*
 * Some SDP file parsing...
 *
 * (C) 2009-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009-2014 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 <osmocom/core/msgb.h>
#include <osmocom/mgcp/mgcp.h>
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/mgcp_msg.h>
#include <osmocom/mgcp/mgcp_endp.h>
#include <osmocom/mgcp/mgcp_codec.h>
#include <osmocom/mgcp/mgcp_sdp.h>

#include <errno.h>

/* Two structs to store intermediate parsing results. The function
 * mgcp_parse_sdp_data() is using the following two structs as temporary
 * storage for parsing the SDP codec information. */
struct sdp_rtp_map {
	/* the type */
	int payload_type;
	/* null, static or later dynamic codec name */
	char *codec_name;
	/* A pointer to the original line for later parsing */
	char *map_line;

	int rate;
	int channels;
};
struct sdp_fmtp_param {
	int payload_type;
	struct mgcp_codec_param param;
};


/* Helper function to extrapolate missing codec parameters in a codec mao from
 * an already filled in payload_type, called from: mgcp_parse_sdp_data() */
static void codecs_initialize(void *ctx, struct sdp_rtp_map *codecs, int used)
{
	int i;

	for (i = 0; i < used; ++i) {
		switch (codecs[i].payload_type) {
		case 0:
			codecs[i].codec_name = "PCMU";
			codecs[i].rate = 8000;
			codecs[i].channels = 1;
			break;
		case 3:
			codecs[i].codec_name = "GSM";
			codecs[i].rate = 8000;
			codecs[i].channels = 1;
			break;
		case 8:
			codecs[i].codec_name = "PCMA";
			codecs[i].rate = 8000;
			codecs[i].channels = 1;
			break;
		case 18:
			codecs[i].codec_name = "G729";
			codecs[i].rate = 8000;
			codecs[i].channels = 1;
			break;
		default:
			codecs[i].codec_name = NULL;
			codecs[i].rate = 0;
			codecs[i].channels = 0;
		}
	}
}

/* Helper function to update codec map information with additional data from
 * SDP, called from: mgcp_parse_sdp_data() */
static void codecs_update(void *ctx, struct sdp_rtp_map *codecs, int used,
			  int payload, const char *audio_name)
{
	int i;

	for (i = 0; i < used; ++i) {
		char audio_codec[64];
		int rate = -1;
		int channels = -1;

		/* Note: We can only update payload codecs that already exist
		 * in our codec list. If we get an unexpected payload type,
		 * we just drop it */
		if (codecs[i].payload_type != payload)
			continue;

		if (sscanf(audio_name, "%63[^/]/%d/%d",
			   audio_codec, &rate, &channels) < 1) {
			LOGP(DLMGCP, LOGL_ERROR, "Failed to parse '%s'\n",
			     audio_name);
			continue;
		}

		codecs[i].map_line = talloc_strdup(ctx, audio_name);
		codecs[i].codec_name = talloc_strdup(ctx, audio_codec);
		codecs[i].rate = rate;
		codecs[i].channels = channels;
		return;
	}

	LOGP(DLMGCP, LOGL_ERROR, "Unconfigured PT(%d) with %s\n", payload,
	     audio_name);
}

/* Extract payload types from SDP, also check for duplicates */
static int pt_from_sdp(void *ctx, struct sdp_rtp_map *codecs,
		       unsigned int codecs_len, char *sdp)
{
	char *str;
	char *str_ptr;
	char *pt_str;
	unsigned int pt;
	unsigned int count = 0;
	unsigned int i;

	str = talloc_zero_size(ctx, strlen(sdp) + 1);
	str_ptr = str;
	strcpy(str_ptr, sdp);

	str_ptr = strstr(str_ptr, "RTP/AVP ");
	if (!str_ptr)
		goto exit;

	pt_str = strtok(str_ptr, " ");
	if (!pt_str)
		goto exit;

	while (1) {
		/* Do not allow excessive payload types */
		if (count > codecs_len)
			goto error;

		pt_str = strtok(NULL, " ");
		if (!pt_str)
			break;

		pt = atoi(pt_str);

		/* Do not allow duplicate payload types */
		for (i = 0; i < count; i++)
			if (codecs[i].payload_type == pt)
				goto error;

		codecs[count].payload_type = pt;
		count++;
	}

exit:
	talloc_free(str);
	return count;
error:
	talloc_free(str);
	return -EINVAL;
}

/* Extract fmtp parameters from SDP, called from: mgcp_parse_sdp_data() */
static int fmtp_from_sdp(void *ctx, struct sdp_fmtp_param *fmtp_param, char *sdp)
{
	char *str;
	char *str_ptr;
	char *param_str;
	unsigned int pt;
	unsigned int count = 0;
	char delimiter;
	unsigned int amr_octet_aligned;

	memset(fmtp_param, 0, sizeof(*fmtp_param));

	str = talloc_zero_size(ctx, strlen(sdp) + 1);
	str_ptr = str;
	strcpy(str_ptr, sdp);

	/* Check if the input string begins with an fmtp token */
	str_ptr = strstr(str_ptr, "fmtp:");
	if (!str_ptr)
		goto exit;
	str_ptr += 5;

	/* Extract payload type */
	if (sscanf(str_ptr, "%u ", &pt) != 1)
		goto error;
	fmtp_param->payload_type = pt;

	/* Advance pointer to the beginning of the parameter section and
	 * tokenize string */
	str_ptr = strstr(str_ptr, " ");
	if (!str_ptr)
		goto error;
	str_ptr++;

	param_str = strtok(str_ptr, " ");
	if (!param_str)
		goto exit;

	while (1) {
		/* Make sure that we don't get trapped in an endless loop */
		if (count > 256)
			goto error;

		/* Chop off delimiters ';' at the end */
		delimiter = str_ptr[strlen(str_ptr) - 1];
		if (delimiter == ';' || delimiter == ',')
			str_ptr[strlen(str_ptr) - 1] = '\0';

		/* AMR octet aligned parameter */
		if (sscanf(param_str, "octet-align=%d", &amr_octet_aligned) == 1) {
			fmtp_param->param.amr_octet_aligned_present = true;
			fmtp_param->param.amr_octet_aligned = false;
			if (amr_octet_aligned == 1)
				fmtp_param->param.amr_octet_aligned = true;

		}

		param_str = strtok(NULL, " ");
		if (!param_str)
			break;
		count++;
	}

exit:
	talloc_free(str);
	return 0;
error:
	talloc_free(str);
	return -EINVAL;
}

/* Pick optional fmtp parameters by payload type, if there are no fmtp
 * parameters, a nullpointer is returned */
static struct mgcp_codec_param *param_by_pt(int pt, struct sdp_fmtp_param *fmtp_params, unsigned int fmtp_params_len)
{
	unsigned int i;

	for (i = 0; i < fmtp_params_len; i++) {
		if (fmtp_params[i].payload_type == pt)
			return &fmtp_params[i].param;
	}

	return NULL;
}

/*! Analyze SDP input string.
 *  \param[in] endp trunk endpoint.
 *  \param[out] conn associated rtp connection.
 *  \param[out] caller provided memory to store the parsing results.
 *
 *  Note: In conn (conn->end) the function returns the packet duration,
 *  rtp port, rtcp port and the codec information.
 *  \returns 0 on success, -1 on failure. */
int mgcp_parse_sdp_data(const struct mgcp_endpoint *endp,
			struct mgcp_conn_rtp *conn, struct mgcp_parse_data *p)
{
	struct sdp_rtp_map codecs[MGCP_MAX_CODECS];
	unsigned int codecs_used = 0;
	struct sdp_fmtp_param fmtp_params[MGCP_MAX_CODECS];
	unsigned int fmtp_used = 0;
	struct mgcp_codec_param *codec_param;
	char *line;
	unsigned int i;
	void *tmp_ctx = talloc_new(NULL);
	struct mgcp_rtp_end *rtp;

	int payload;
	int ptime, ptime2 = 0;
	char audio_name[64];
	int port, rc;
	char ipv4[16];

	OSMO_ASSERT(endp);
	OSMO_ASSERT(conn);
	OSMO_ASSERT(p);

	rtp = &conn->end;
	memset(&codecs, 0, sizeof(codecs));

	for_each_line(line, p->save) {
		switch (line[0]) {
		case 'o':
		case 's':
		case 't':
		case 'v':
			/* skip these SDP attributes */
			break;
		case 'a':
			if (sscanf(line, "a=rtpmap:%d %63s", &payload, audio_name) == 2) {
				codecs_update(tmp_ctx, codecs, codecs_used, payload, audio_name);
				break;
			}

			if (sscanf(line, "a=ptime:%d-%d", &ptime, &ptime2) >= 1) {
				if (ptime2 > 0 && ptime2 != ptime)
					rtp->packet_duration_ms = 0;
				else
					rtp->packet_duration_ms = ptime;
				break;
			}

			if (sscanf(line, "a=maxptime:%d", &ptime2) == 1) {
				rtp->maximum_packet_time = ptime2;
				break;
			}

			if (strncmp("a=fmtp:", line, 6) == 0) {
				rc = fmtp_from_sdp(conn->conn, &fmtp_params[fmtp_used], line);
				if (rc >= 0)
					fmtp_used++;
				break;
			}

			break;
		case 'm':
			rc = sscanf(line, "m=audio %d RTP/AVP", &port);
			if (rc == 1) {
				rtp->rtp_port = htons(port);
				rtp->rtcp_port = htons(port + 1);
			}

			rc = pt_from_sdp(conn->conn, codecs,
					 ARRAY_SIZE(codecs), line);
			if (rc > 0)
				codecs_used = rc;
			break;
		case 'c':

			if (sscanf(line, "c=IN IP4 %15s", ipv4) == 1) {
				inet_aton(ipv4, &rtp->addr);
			}
			break;
		default:
			if (p->endp)
				LOGP(DLMGCP, LOGL_NOTICE,
				     "Unhandled SDP option: '%c'/%d on 0x%x\n",
				     line[0], line[0],
				     ENDPOINT_NUMBER(p->endp));
			else
				LOGP(DLMGCP, LOGL_NOTICE,
				     "Unhandled SDP option: '%c'/%d\n",
				     line[0], line[0]);
			break;
		}
	}
	OSMO_ASSERT(codecs_used <= MGCP_MAX_CODECS);

	/* So far we have only set the payload type in the codec struct. Now we
	 * fill up the remaining fields of the codec description with some default
	 * information */
	codecs_initialize(tmp_ctx, codecs, codecs_used);

	/* Store parsed codec information */
	for (i = 0; i < codecs_used; i++) {
		codec_param = param_by_pt(codecs[i].payload_type, fmtp_params, fmtp_used);
		rc = mgcp_codec_add(conn, codecs[i].payload_type, codecs[i].map_line, codec_param);
		if (rc < 0)
			LOGP(DLMGCP, LOGL_NOTICE, "endpoint:0x%x, failed to add codec\n", ENDPOINT_NUMBER(p->endp));
	}

	talloc_free(tmp_ctx);

	LOGPCONN(conn->conn, DLMGCP, LOGL_NOTICE,
	     "Got media info via SDP: port:%d, addr:%s, duration:%d, payload-types:",
	     ntohs(rtp->rtp_port), inet_ntoa(rtp->addr),
	     rtp->packet_duration_ms);
	if (codecs_used == 0)
		LOGPC(DLMGCP, LOGL_NOTICE, "none");
	for (i = 0; i < codecs_used; i++) {
		LOGPC(DLMGCP, LOGL_NOTICE, "%d=%s",
		      rtp->codecs[i].payload_type,
		      rtp->codecs[i].subtype_name ? rtp-> codecs[i].subtype_name : "unknown");
		LOGPC(DLMGCP, LOGL_NOTICE, " ");
	}
	LOGPC(DLMGCP, LOGL_NOTICE, "\n");

	return 0;
}


/* Add rtpmap string to the sdp payload, but only when the payload type falls
 * into the dynamic payload type range */
static int add_rtpmap(struct msgb *sdp, int payload_type, const char *audio_name)
{
	int rc;

	if (payload_type >= 96 && payload_type <= 127) {
		if (!audio_name)
			return -EINVAL;
		rc = msgb_printf(sdp, "a=rtpmap:%d %s\r\n", payload_type, audio_name);
		if (rc < 0)
			return -EINVAL;
	}

	return 0;
}

/* Add audio strings to sdp payload */
static int add_audio(struct msgb *sdp, int *payload_types, unsigned int payload_types_len, int local_port)
{
	int rc;
	unsigned int i;

	if (payload_types_len < 0)
		return -EINVAL;

	rc = msgb_printf(sdp, "m=audio %d RTP/AVP", local_port);
	if (rc < 0)
		return -EINVAL;

	for (i = 0; i < payload_types_len; i++) {
		rc = msgb_printf(sdp, " %d", payload_types[i]);
		if (rc < 0)
			return -EINVAL;
	}

	rc = msgb_printf(sdp, "\r\n");
	if (rc < 0)
		return -EINVAL;

	return 0;
}

/* Add fmtp strings to sdp payload */
static int add_fmtp(struct msgb *sdp, struct sdp_fmtp_param *fmtp_params, unsigned int fmtp_params_len,
		    const char *fmtp_extra)
{
	unsigned int i;
	int rc;
	int fmtp_extra_pt = -1;
	char *fmtp_extra_pars = "";

	/* When no fmtp parameters ara available but an fmtp extra string
	 * is configured, just add the fmtp extra string */
	if (fmtp_params_len == 0 && fmtp_extra) {
		return msgb_printf(sdp, "%s\r\n", fmtp_extra);
	}

	/* When there is fmtp extra configured we dissect it in order to drop
	 * in the configured extra parameters at the right place when
	 * generating the fmtp strings. */
	if (fmtp_extra) {
		if (sscanf(fmtp_extra, "a=fmtp:%d ", &fmtp_extra_pt) != 1)
			fmtp_extra_pt = -1;

		fmtp_extra_pars = strstr(fmtp_extra, " ");

		if (!fmtp_extra_pars)
			fmtp_extra_pars = "";
		else
			fmtp_extra_pars++;
	}

	for (i = 0; i < fmtp_params_len; i++) {
		rc = msgb_printf(sdp, "a=fmtp:%u", fmtp_params[i].payload_type);

		/* Add amr octet align parameter */
		if (fmtp_params[i].param.amr_octet_aligned_present) {
			if (fmtp_params[i].param.amr_octet_aligned)
				rc = msgb_printf(sdp, " octet-align=1");
			else
				rc = msgb_printf(sdp, " octet-align=0");
			if (rc < 0)
				return -EINVAL;
		}

		/* Append extra parameters from fmtp extra */
		if (fmtp_params[i].payload_type == fmtp_extra_pt) {
			rc = msgb_printf(sdp, " %s", fmtp_extra_pars);
			if (rc < 0)
				return -EINVAL;
		}

		rc = msgb_printf(sdp, "\r\n", fmtp_params[i].payload_type);
		if (rc < 0)
			return -EINVAL;
	}

	return 0;
}

/*! Generate SDP response string.
 *  \param[in] endp trunk endpoint.
 *  \param[in] conn associated rtp connection.
 *  \param[out] sdp msg buffer to append resulting SDP string data.
 *  \param[in] addr IPV4 address string (e.g. 192.168.100.1).
 *  \returns 0 on success, -1 on failure. */
int mgcp_write_response_sdp(const struct mgcp_endpoint *endp,
			    const struct mgcp_conn_rtp *conn, struct msgb *sdp,
			    const char *addr)
{
	const struct mgcp_rtp_codec *codec;
	const char *fmtp_extra;
	const char *audio_name;
	int payload_type;
	struct sdp_fmtp_param fmtp_param;
	int rc;
	int payload_types[1];
	struct sdp_fmtp_param fmtp_params[1];
        unsigned int fmtp_params_len = 0;

	OSMO_ASSERT(endp);
	OSMO_ASSERT(conn);
	OSMO_ASSERT(sdp);
	OSMO_ASSERT(addr);

	/* FIXME: constify endp and conn args in get_net_donwlink_format_cb() */
	endp->cfg->get_net_downlink_format_cb((struct mgcp_endpoint *)endp,
					      &codec, &fmtp_extra,
					      (struct mgcp_conn_rtp *)conn);

	audio_name = codec->audio_name;
	payload_type = codec->payload_type;

	rc = msgb_printf(sdp,
			 "v=0\r\n"
			 "o=- %s 23 IN IP4 %s\r\n"
			 "s=-\r\n"
			 "c=IN IP4 %s\r\n"
			 "t=0 0\r\n", conn->conn->id, addr, addr);

	if (rc < 0)
		goto buffer_too_small;

	if (payload_type >= 0) {

		payload_types[0] = payload_type;
		rc = add_audio(sdp, payload_types, 1, conn->end.local_port);
		if (rc < 0)
			goto buffer_too_small;

		if (endp->tcfg->audio_send_name) {
			rc = add_rtpmap(sdp, payload_type, audio_name);
			if (rc < 0)
				goto buffer_too_small;
		}

		if (codec->param_present) {
			fmtp_param.payload_type = payload_type;
			fmtp_param.param = codec->param;
			fmtp_params[0] = fmtp_param;
			fmtp_params_len = 1;
		}
		rc = add_fmtp(sdp, fmtp_params, fmtp_params_len, fmtp_extra);
		if (rc < 0)
			goto buffer_too_small;
	}
	if (conn->end.packet_duration_ms > 0 && endp->tcfg->audio_send_ptime) {
		rc = msgb_printf(sdp, "a=ptime:%u\r\n",
				 conn->end.packet_duration_ms);
		if (rc < 0)
			goto buffer_too_small;
	}

	return 0;

buffer_too_small:
	LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR, "SDP messagebuffer too small\n");
	return -1;
}
