/* Endpoint types */

/*
 * (C) 2017-2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * Author: Philipp Maier
 *
 * 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/mgcp/mgcp.h>
#include <osmocom/mgcp/mgcp_protocol.h>
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_endp.h>
#include <osmocom/mgcp/mgcp_trunk.h>

#include <osmocom/abis/e1_input.h>
#include <osmocom/mgcp/mgcp_e1.h>
#include <osmocom/core/stat_item.h>

#define E1_RATE_MAX 64
#define E1_OFFS_MAX 8

/* Endpoint typeset definition */
const struct mgcp_endpoint_typeset ep_typeset = {
	/* Specify endpoint properties for RTP endpoint */
	.rtp = {
		.max_conns = 2,
		.dispatch_rtp_cb = mgcp_dispatch_rtp_bridge_cb,
		.cleanup_cb = mgcp_cleanup_rtp_bridge_cb,
	},
	/* Specify endpoint properties for E1 endpoint */
	.e1 = {
		.max_conns = 1,
		.dispatch_rtp_cb = mgcp_dispatch_e1_bridge_cb,
		.cleanup_cb = mgcp_cleanup_e1_bridge_cb,
	},
};

/* Generate virtual endpoint name from given parameters */
static char *gen_virtual_epname(void *ctx, const char *domain,
			       unsigned int index)
{
	return talloc_asprintf(ctx, "%s%x@%s",
		 MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, index, domain);
}

/* Generate E1 endpoint name from given numeric parameters */
static char *gen_e1_epname(void *ctx, const char *domain, unsigned int trunk_nr,
			   uint8_t ts_nr, uint8_t ss_nr)
{
	unsigned int rate;
	unsigned int offset;

	OSMO_ASSERT(ss_nr < sizeof(e1_rates));

	rate = e1_rates[ss_nr];
	offset = e1_offsets[ss_nr];

	return talloc_asprintf(ctx, "%s%u/s-%u/su%u-%u@%s",
			       MGCP_ENDPOINT_PREFIX_E1_TRUNK, trunk_nr, ts_nr,
			       rate, offset, domain);
}

/*! allocate an endpoint and set default values.
 *  \param[in] trunk configuration.
 *  \param[in] name endpoint index.
 *  \returns endpoint on success, NULL on failure. */
struct mgcp_endpoint *mgcp_endp_alloc(struct mgcp_trunk *trunk,
				      unsigned int index)
{
	struct mgcp_endpoint *endp;

	endp = talloc_zero(trunk->endpoints, struct mgcp_endpoint);
	if (!endp)
		return NULL;

	INIT_LLIST_HEAD(&endp->conns);
	endp->trunk = trunk;

	switch (trunk->trunk_type) {
	case MGCP_TRUNK_VIRTUAL:
		endp->type = &ep_typeset.rtp;
		endp->name = gen_virtual_epname(endp, trunk->cfg->domain, index);
		break;
	case MGCP_TRUNK_E1:
		endp->type = &ep_typeset.e1;
		endp->name = gen_e1_epname(endp, trunk->cfg->domain,
					   trunk->trunk_nr,
					   index / MGCP_ENDP_E1_SUBSLOTS, index % MGCP_ENDP_E1_SUBSLOTS);
		break;
	default:
		osmo_panic("Cannot allocate unimplemented trunk type %d! %s:%d\n",
			   trunk->trunk_type, __FILE__, __LINE__);
	}

	return endp;
}

/*! release endpoint, all open connections are closed.
 *  \param[in] endp endpoint to release */
void mgcp_endp_release(struct mgcp_endpoint *endp)
{
	LOGPENDP(endp, DLMGCP, LOGL_DEBUG, "Releasing endpoint\n");

	/* Normally this function should only be called when
	 * all connections have been removed already. In case
	 * that there are still connections open (e.g. when
	 * RSIP is executed), free them all at once. */
	mgcp_conn_free_all(endp);

	/* We must only decrement the stat item when the endpoint as actually
	 * claimed. An endpoint is claimed when a call-id is set */
	if (endp->callid)
		osmo_stat_item_dec(osmo_stat_item_group_get_item(endp->trunk->stats.common,
								 TRUNK_STAT_ENDPOINTS_USED), 1);

	/* Reset endpoint parameters and states */
	talloc_free(endp->callid);
	endp->callid = NULL;
	talloc_free(endp->local_options.string);
	endp->local_options.string = NULL;
	talloc_free(endp->local_options.codec);
	endp->local_options.codec = NULL;

	if (endp->trunk->trunk_type == MGCP_TRUNK_E1)
		mgcp_e1_endp_release(endp);
}

/* Check if the endpoint name contains the prefix (e.g. "rtpbridge/" or
 * "ds/e1-") and write the epname without the prefix back to the memory
 * pointed at by epname. (per trunk the prefix is the same for all endpoints,
 * so no ambiguity is introduced) */
static void chop_epname_prefix(char *epname, const struct mgcp_trunk *trunk)
{
	size_t prefix_len;
	switch (trunk->trunk_type) {
	case MGCP_TRUNK_VIRTUAL:
		prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK) - 1;
		if (strncmp
		    (epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK,
		     prefix_len) == 0)
			memmove(epname, epname + prefix_len,
				strlen(epname) - prefix_len + 1);
		return;
	case MGCP_TRUNK_E1:
		prefix_len = sizeof(MGCP_ENDPOINT_PREFIX_E1_TRUNK) - 1;
		if (strncmp
		    (epname, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK,
		     prefix_len) == 0)
			memmove(epname, epname + prefix_len,
				strlen(epname) - prefix_len + 1);
		return;
	default:
		OSMO_ASSERT(false);
	}
}

/* Check if the endpoint name contains a suffix (e.g. "@mgw") and truncate
 * epname by writing a '\0' char where the suffix starts. */
static void chop_epname_suffix(char *epname, const struct mgcp_trunk *trunk)
{
	char *suffix_begin;

	/* Endpoints on the virtual trunk may have a domain name that is
	 * followed after an @ character, this can be chopped off. All
	 * other supported trunk types do not have any suffixes that may
	 * be chopped off */
	if (trunk->trunk_type == MGCP_TRUNK_VIRTUAL) {
		suffix_begin = strchr(epname, '@');
		if (!suffix_begin)
			return;
		*suffix_begin = '\0';
	}
}


 /*! Convert all characters in epname to lowercase and strip trunk prefix and
 * endpoint name suffix (domain name) from epname. The result is written to
 * to the memory pointed at by epname_stripped. The expected size of the
 * result is either equal or lower then the length of the input string
 * (epname)
 *  \param[out] epname_stripped pointer to store the stripped ep name.
 *  \param[in] epname endpoint name to lookup.
 *  \param[in] trunk where the endpoint is located. */
void mgcp_endp_strip_name(char *epname_stripped, const char *epname,
			 const struct mgcp_trunk *trunk)
{
	osmo_str_tolower_buf(epname_stripped, MGCP_ENDPOINT_MAXLEN, epname);
	chop_epname_prefix(epname_stripped, trunk);
	chop_epname_suffix(epname_stripped, trunk);
}

/* Go through the trunk and find a random free (no active calls) endpoint,
 * this function is called when a wildcarded request is carried out, which
 * means that it is up to the MGW to choose a random free endpoint. */
static struct mgcp_endpoint *find_free_endpoint(const struct mgcp_trunk *trunk)
{
	struct mgcp_endpoint *endp;
	unsigned int i;

	for (i = 0; i < trunk->number_endpoints; i++) {
		endp = trunk->endpoints[i];
		/* A free endpoint must not serve a call already and it must
		 * be available. */
		if (endp->callid == NULL && mgcp_endp_avail(endp))
			return endp;
	}

	return NULL;
}

/*! Find an endpoint of a trunk specified by its name.
 *  \param[in] epname endpoint name to check.
 *  \param[in] trunk mgcp_trunk that might have this endpoint.
 *  \returns NULL if no ep found, else endpoint. */
struct mgcp_endpoint *mgcp_endp_find_specific(const char *epname,
						    const struct mgcp_trunk *trunk)
{
	char epname_stripped[MGCP_ENDPOINT_MAXLEN];
	char epname_stripped_endp[MGCP_ENDPOINT_MAXLEN];
	struct mgcp_endpoint *endp;
	unsigned int i;

	/* Strip irrelevant information from the endpoint name */
	mgcp_endp_strip_name(epname_stripped, epname, trunk);

	for (i = 0; i < trunk->number_endpoints; i++) {
		endp = trunk->endpoints[i];
		mgcp_endp_strip_name(epname_stripped_endp, endp->name, trunk);
		if (strcmp(epname_stripped_endp, epname_stripped) == 0)
			return endp;
	}

	return NULL;
}

/*! Check if the given epname refers to a wildcarded request or to a specific
 *  endpoint.
 *  \param[in] epname endpoint name to check
 *  \returns true if epname refers to wildcarded request, else false. */
bool mgcp_endp_is_wildcarded(const char *epname)
{
	if (strstr(epname, "*"))
		return true;

	return false;
}

/*! Find an endpoint by its name on a specified trunk.
 *  \param[out] cause pointer to store cause code, can be NULL.
 *  \param[in] epname endpoint name to lookup.
 *  \param[in] trunk where the endpoint is located.
 *  \returns endpoint or NULL if endpoint was not found. */
struct mgcp_endpoint *mgcp_endp_by_name_trunk(int *cause, const char *epname,
					      const struct mgcp_trunk *trunk)
{
	struct mgcp_endpoint *endp;

	if (cause)
		*cause = 0;

	/* At the moment we only support a primitive ('*'-only) method of
	 * wildcarded endpoint searches that picks the next free endpoint on
	 * a trunk. */
	if (mgcp_endp_is_wildcarded(epname)) {
		endp = find_free_endpoint(trunk);
		if (endp) {
			LOGPENDP(endp, DLMGCP, LOGL_DEBUG,
				 "(trunk:%d) found free endpoint: %s\n",
				 trunk->trunk_nr, endp->name);
			return endp;
		}

		LOGP(DLMGCP, LOGL_ERROR,
		     "(trunk:%d) Not able to find a free endpoint\n",
		     trunk->trunk_nr);
		if (cause)
			*cause = -403;
		return NULL;
	}

	/* Find an endpoint by its name (if wildcarded request is not
	 * applicable) */
	endp = mgcp_endp_find_specific(epname, trunk);
	if (endp) {
		LOGPENDP(endp, DLMGCP, LOGL_DEBUG,
			 "(trunk:%d) found endpoint: %s\n",
			 trunk->trunk_nr, endp->name);
		return endp;
	}

	LOGP(DLMGCP, LOGL_ERROR,
	     "(trunk:%d) Not able to find specified endpoint: %s\n",
	     trunk->trunk_nr, epname);
	if (cause)
		*cause = -500;

	return NULL;
}

/*! Find an endpoint by its name, search at all trunks.
 *  \param[out] cause, pointer to store cause code, can be NULL.
 *  \param[in] epname, must contain trunk prefix.
 *  \param[in] cfg, mgcp configuration (trunks).
 *  \returns endpoint or NULL if endpoint was not found. */
struct mgcp_endpoint *mgcp_endp_by_name(int *cause, const char *epname,
					struct mgcp_config *cfg)
{
	struct mgcp_trunk *trunk;
	struct mgcp_endpoint *endp;
	char epname_lc[MGCP_ENDPOINT_MAXLEN];

	osmo_str_tolower_buf(epname_lc, sizeof(epname_lc), epname);
	epname = epname_lc;

	if (cause)
		*cause = -500;

	/* Identify the trunk where the endpoint is located */
	trunk = mgcp_trunk_by_name(cfg, epname);
	if (!trunk)
		return NULL;

	/* Identify the endpoint on the trunk */
        endp = mgcp_endp_by_name_trunk(cause, epname, trunk);
	if (!endp) {
		return NULL;
	}

	if (cause)
		*cause = 0;
	return endp;
}

/* Get the E1 timeslot number from a given E1 endpoint name
 * (e.g. ds/e1-0/s-30/su16-4), returns 0xff on error. */
static uint8_t e1_ts_nr_from_epname(const char *epname)
{
	char buf[MGCP_ENDPOINT_MAXLEN + 1];
	char *save_ptr = NULL;
	char *buf_ptr = buf;
	char *token;
	unsigned long int res = 0;

	strncpy(buf, epname, MGCP_ENDPOINT_MAXLEN);

	while (1) {
		token = strtok_r(buf_ptr, "/", &save_ptr);
		buf_ptr = NULL;
		if (!token)
			break;
		if (strncmp(token, "s-", 2) == 0) {
			errno = 0;
			res = strtoul(token + 2, NULL, 10);
			if (errno == ERANGE || res > NUM_E1_TS)
				return 0xff;
			return (uint8_t) res;
		}
	}

	return 0xff;
}

/* Get the E1 timeslot number from a given E1 endpoint name
 * (e.g. ds/e1-0/s-30/su16-4), returns 0xff on error. */
static uint8_t e1_rate_from_epname(const char *epname)
{
	char buf[MGCP_ENDPOINT_MAXLEN + 1];
	char *save_ptr = NULL;
	char *buf_ptr = buf;
	char *token;
	unsigned long int res = 0;
	unsigned int i;

	strncpy(buf, epname, MGCP_ENDPOINT_MAXLEN);

	while (1) {
		token = strtok_r(buf_ptr, "/", &save_ptr);
		buf_ptr = NULL;
		if (!token)
			break;
		if (strncmp(token, "su", 2) == 0) {
			errno = 0;
			res = strtoul(token + 2, NULL, 10);
			if (errno == ERANGE || res > E1_RATE_MAX)
				return 0xff;
			/* Make sure the rate is a valid rate */
			for (i = 0; i < sizeof(e1_rates); i++) {
				if (res == e1_rates[i])
					return (uint8_t) res;
			}
			return 0xff;
		}
	}

	return 0xff;
}

/* Get the E1 bitstream offset from a given E1 endpoint name
 * (e.g. ds/e1-0/s-30/su16-4), returns 0xff on error. */
static uint8_t e1_offs_from_epname(const char *epname)
{
	char buf[MGCP_ENDPOINT_MAXLEN + 1];
	char *save_ptr = NULL;
	char *buf_ptr = buf;
	char *token;
	unsigned long int res = 0;

	strncpy(buf, epname, MGCP_ENDPOINT_MAXLEN);

	while (1) {
		token = strtok_r(buf_ptr, "/", &save_ptr);
		buf_ptr = NULL;
		if (!token)
			break;
		if (strncmp(token, "su", 2) == 0) {
			token = strstr(token, "-");
			if (!token)
				return 0xff;
			token += 1;
			errno = 0;
			res = strtoul(token, NULL, 10);
			if (errno == ERANGE || res > E1_OFFS_MAX)
				return 0xff;
			return (uint8_t) res;
		}
	}

	return 0xff;
}

/* Get the E1 subslot number (internal) from a given E1 endpoint name
 * (e.g. ds/e1-0/s-30/su16-4), returns 0xff on error. */
static uint8_t e1_ss_nr_from_epname(const char *epname)
{
	uint8_t rate;
	uint8_t offs;
	unsigned int i;

	rate = e1_rate_from_epname(epname);
	offs = e1_offs_from_epname(epname);

	osmo_static_assert(sizeof(e1_rates) == sizeof(e1_offsets), e1_rates_e1_offsets_size);

	for (i = 0; i < sizeof(e1_rates); i++) {
		if ((e1_rates[i] == rate) && (e1_offsets[i] == offs))
			return i;
	}

	return 0xff;
}

/* Check if the selected E1 endpoint is avalable, which means that none of
 * the overlapping endpoints are currently serving a call. (if the system
 * is properly configured such a situation should never ocurr!) */
static bool endp_avail_e1(struct mgcp_endpoint *endp)
{
	/* The following map shows the overlapping of the subslots and their
	 * respective rates. The numbers on the right running from top to bottom
	 * are the bit offsets in the whole 64k timeslot. The numbers inside the
	 * boxes symbolize the internal subslot number (array index) and the
	 * rate in the form: i:r where i is the subslot number and r the
	 * respective rate.
	 *
	 * +--------+--------+--------+--------+ 0
	 * |        |        |        |  7:8k  |
	 * |        |        + 3:16k  +--------+ 1
	 * |        |        |        |  8:8k  |
	 * |        | 1:32k  +--------+--------+ 2
	 * |        |        |        |  9:8k  |
	 * |        |        + 4:16k  +--------+ 3
	 * |        |        |        | 10:8k  |
	 * | 0:64k  +--------+--------+--------+ 4
	 * |        |        |        | 11:8k  |
	 * |        |        + 5:16k  +--------+ 5
	 * |        |        |        | 12:8k  |
	 * |        | 2:32k  +--------+--------+ 6
	 * |        |        |        | 13:8k  |
	 * |        |        + 6:16k  +--------+ 7
	 * |        |        |        | 14:8k  |
	 * +--------+--------+--------+--------+ 8
	 *
	 * The following array contains tables with the subslot numbers that must be
	 * unused for each subslot. During this test we do not have to check the
	 * endpoint we need to verify, only the overlaps need to be checked. This is
	 * also the reason why the related subslot number is missing from each each
	 * line. */
	const int8_t interlock_tab[MGCP_ENDP_E1_SUBSLOTS][15] = {
		{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1 },
		{ 0, 3, 4, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 5, 6, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 1, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 1, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 2, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 2, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 2, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 2, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		{ 0, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } };

	const int8_t *interlock;
	unsigned int i;
	uint8_t ts_nr = 0;
	uint8_t ss_nr = 0;
	char *epname_check;
	struct mgcp_endpoint *endp_check;
	bool available = true;

	/* This function must only be used with E1 type endpoints! */
	OSMO_ASSERT(endp->trunk->trunk_type == MGCP_TRUNK_E1);

	ts_nr = e1_ts_nr_from_epname(endp->name);
	ss_nr = e1_ss_nr_from_epname(endp->name);
	if (ts_nr == 0xff || ss_nr == 0xff) {
		LOGPENDP(endp, DLMGCP, LOGL_ERROR,
			 "cannot check endpoint availability, endpoint name not parseable!\n");
		return false;
	}

	interlock = interlock_tab[ss_nr];

	for (i = 0; i < sizeof(interlock_tab[0]); i++) {
		/* Detect row end */
		if (interlock[i] == -1)
			break;

		/* Pick overlapping endpoint to check */
		epname_check = gen_e1_epname(endp, endp->trunk->cfg->domain,
					     endp->trunk->trunk_nr, ts_nr,
					     interlock[i]);
		endp_check = mgcp_endp_find_specific(epname_check, endp->trunk);
		if (!endp_check) {
			LOGPENDP(endp, DLMGCP, LOGL_ERROR,
				 "cannot check endpoint availability, overlapping endpoint:%s not found!\n",
				 epname_check);
			talloc_free(epname_check);
			continue;
		}
		talloc_free(epname_check);

		/* Check if overlapping endpoint currently serves another call
		 * (This is an exceptional situation, that should not occur
		 * in a properly configured environment!) */
		if (endp_check->callid) {
			LOGPENDP(endp, DLMGCP, LOGL_ERROR,
				 "endpoint unavailable - overlapping endpoint:%s already serves a call!\n",
				 endp_check->name);
			available = false;
		}
	}

	return available;
}

/*! check if an endpoint is available for any kind of operation.
 *  \param[in] endp endpoint to check.
 *  \returns true if endpoint is avalable, false it is blocked for any reason. */
bool mgcp_endp_avail(struct mgcp_endpoint *endp)
{
	switch (endp->trunk->trunk_type) {
	case MGCP_TRUNK_VIRTUAL:
		/* There are no obstacles that may render a virtual trunk
		 * endpoint unusable, so virtual trunk endpoints are always
		 * available */
		return true;
	case MGCP_TRUNK_E1:
		return endp_avail_e1(endp);
	default:
		OSMO_ASSERT(false);
	}

	return false;
}

/*! claim endpoint, sets callid and activates endpoint, should be called at the
 *  beginning of the CRCX procedure when it is clear that a new call should be
 *  created.
 *  \param[in] endp endpoint to claim.
 *  \param[in] callid that is assingned to this endpoint. */
int mgcp_endp_claim(struct mgcp_endpoint *endp, const char *callid)
{
	int rc = 0;
	uint8_t ts;
	uint8_t ss;
	uint8_t offs;

	/* TODO: Make this function more intelligent, it should run the
	 * call id checks we currently have in protocol.c directly here. */

	/* Set the callid, creation of another connection will only be possible
	 * when the callid matches up. (Connections are distinguished by their
	 * connection ids) */
	endp->callid = talloc_strdup(endp, callid);
	OSMO_ASSERT(endp->callid);
	osmo_stat_item_inc(osmo_stat_item_group_get_item(endp->trunk->stats.common,
							 TRUNK_STAT_ENDPOINTS_USED), 1);

	/* Allocate resources */
	switch (endp->trunk->trunk_type) {
	case MGCP_TRUNK_VIRTUAL:
		/* No additional initaliziation required here, virtual
		 * endpoints will open/close network sockets themselves
		 * on demand. */
		break;
	case MGCP_TRUNK_E1:
		ts = e1_ts_nr_from_epname(endp->name);
		ss = e1_ss_nr_from_epname(endp->name);
		offs = e1_offs_from_epname(endp->name);
		OSMO_ASSERT(ts != 0xFF);
		OSMO_ASSERT(ts != 0);
		OSMO_ASSERT(ss != 0xFF);
		OSMO_ASSERT(offs != 0xFF);
		rc = mgcp_e1_endp_equip(endp, ts, ss, offs);
		break;
	default:
		OSMO_ASSERT(false);
	}

	/* Make sure the endpoint is released when claiming the endpoint fails. */
	if (rc < 0)
		mgcp_endp_release(endp);

	return rc;
}

/*! update endpoint, updates internal endpoint specific data, should be
 *  after when MDCX or CRCX has been executed successuflly.
 *  \param[in] endp endpoint to update. */
void mgcp_endp_update(struct mgcp_endpoint *endp)
{
	/* Allocate resources */
	switch (endp->trunk->trunk_type) {
	case MGCP_TRUNK_VIRTUAL:
		/* No updating initaliziation required for virtual endpoints. */
		break;
	case MGCP_TRUNK_E1:
		mgcp_e1_endp_update(endp);
		break;
	default:
		OSMO_ASSERT(false);
	}
}

void mgcp_endp_add_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn)
{
	llist_add(&conn->entry, &endp->conns);
}

void mgcp_endp_remove_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn)
{
	/* Run endpoint cleanup action. By this we inform the endpoint about
	 * the removal of the connection and allow it to clean up its inner
	 * state accordingly */
	if (endp->type->cleanup_cb)
		endp->type->cleanup_cb(endp, conn);
	llist_del(&conn->entry);
	if (llist_empty(&endp->conns))
		mgcp_endp_release(endp);
}
