/*
 * (C) 2012-2013 by Pablo Neira Ayuso <pablo@gnumonks.org>
 * (C) 2012-2013 by On Waves ehf <http://www.on-waves.com>
 * All rights not specifically granted under this license are 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.
 */

#include <stdio.h> /* for printf */
#include <string.h> /* for memcpy */
#include <stdlib.h> /* for abs */
#include <inttypes.h> /* for PRIu64 */
#include <netinet/in.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>

#include <osmocom/netif/osmux.h>
#include <osmocom/netif/rtp.h>

#include <osmocom/mgcp/mgcp.h>
#include <osmocom/mgcp/mgcp_internal.h>
#include <osmocom/mgcp/osmux.h>
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_endp.h>

static struct osmo_fd osmux_fd;

static LLIST_HEAD(osmux_handle_list);

struct osmux_handle {
	struct llist_head head;
	struct osmux_in_handle *in;
	struct in_addr rem_addr;
	int rem_port;
	int refcnt;
};

static void *osmux;

/* Deliver OSMUX batch to the remote end */
static void osmux_deliver_cb(struct msgb *batch_msg, void *data)
{
	struct osmux_handle *handle = data;
	struct sockaddr_in out = {
		.sin_family = AF_INET,
		.sin_port = handle->rem_port,
	};

	memcpy(&out.sin_addr, &handle->rem_addr, sizeof(handle->rem_addr));
	sendto(osmux_fd.fd, batch_msg->data, batch_msg->len, 0,
		(struct sockaddr *)&out, sizeof(out));
	msgb_free(batch_msg);
}

/* Lookup existing OSMUX handle for specified destination address. */
static struct osmux_handle *
osmux_handle_find_get(struct in_addr *addr, int rem_port)
{
	struct osmux_handle *h;

	llist_for_each_entry(h, &osmux_handle_list, head) {
		if (memcmp(&h->rem_addr, addr, sizeof(struct in_addr)) == 0 &&
		    h->rem_port == rem_port) {
			LOGP(DLMGCP, LOGL_DEBUG, "using existing OSMUX handle "
						"for addr=%s:%d\n",
				inet_ntoa(*addr), ntohs(rem_port));
			h->refcnt++;
			return h;
		}
	}

	return NULL;
}

/* Put down no longer needed OSMUX handle */
static void osmux_handle_put(struct osmux_in_handle *in)
{
	struct osmux_handle *h;

	llist_for_each_entry(h, &osmux_handle_list, head) {
		if (h->in == in) {
			if (--h->refcnt == 0) {
				LOGP(DLMGCP, LOGL_INFO,
				     "Releasing unused osmux handle for %s:%d\n",
				     inet_ntoa(h->rem_addr),
				     ntohs(h->rem_port));
				LOGP(DLMGCP, LOGL_INFO, "Stats: "
				     "input RTP msgs: %u bytes: %"PRIu64" "
				     "output osmux msgs: %u bytes: %"PRIu64"\n",
				     in->stats.input_rtp_msgs,
				     in->stats.input_rtp_bytes,
				     in->stats.output_osmux_msgs,
				     in->stats.output_osmux_bytes);
				llist_del(&h->head);
				osmux_xfrm_input_fini(h->in);
				talloc_free(h);
			}
			return;
		}
	}
	LOGP(DLMGCP, LOGL_ERROR, "cannot find Osmux input handle %p\n", in);
}

/* Allocate free OSMUX handle */
static struct osmux_handle *
osmux_handle_alloc(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
{
	struct osmux_handle *h;

	h = talloc_zero(osmux, struct osmux_handle);
	if (!h)
		return NULL;
	h->rem_addr = *addr;
	h->rem_port = rem_port;
	h->refcnt++;

	h->in = talloc_zero(h, struct osmux_in_handle);
	if (!h->in) {
		talloc_free(h);
		return NULL;
	}

	/* sequence number to start OSMUX message from */
	h->in->osmux_seq = 0;

	h->in->batch_factor = cfg->osmux_batch;

	/* If batch size is zero, the library defaults to 1470 bytes. */
	h->in->batch_size = cfg->osmux_batch_size;
	h->in->deliver = osmux_deliver_cb;
	osmux_xfrm_input_init(h->in);
	h->in->data = h;

	llist_add(&h->head, &osmux_handle_list);

	LOGP(DLMGCP, LOGL_DEBUG, "created new OSMUX handle for addr=%s:%d\n",
		inet_ntoa(*addr), ntohs(rem_port));

	return h;
}

/* Lookup existing handle for a specified address, if the handle can not be
 * found, the function will automatically allocate one */
static struct osmux_in_handle *
osmux_handle_lookup(struct mgcp_config *cfg, struct in_addr *addr, int rem_port)
{
	struct osmux_handle *h;

	h = osmux_handle_find_get(addr, rem_port);
	if (h != NULL)
		return h->in;

	h = osmux_handle_alloc(cfg, addr, rem_port);
	if (h == NULL)
		return NULL;

	return h->in;
}

/*! send RTP packet through OSMUX connection.
 *  \param[in] buf rtp data
 *  \param[in] buf_len length of rtp data
 *  \param[in] conn associated RTP connection
 *  \returns 0 on success, -1 on ERROR */
int osmux_xfrm_to_osmux(char *buf, int buf_len, struct mgcp_conn_rtp *conn)
{
	int ret;
	struct msgb *msg;

	msg = msgb_alloc(4096, "RTP");
	if (!msg)
		return -1;

	memcpy(msg->data, buf, buf_len);
	msgb_put(msg, buf_len);

	while ((ret = osmux_xfrm_input(conn->osmux.in, msg, conn->osmux.cid)) > 0) {
		/* batch full, build and deliver it */
		osmux_xfrm_input_deliver(conn->osmux.in);
	}
	return 0;
}

/* Lookup the endpoint that corresponds to the specified address (port) */
static struct mgcp_endpoint *
endpoint_lookup(struct mgcp_config *cfg, int cid,
		struct in_addr *from_addr, int type)
{
	struct mgcp_endpoint *endp = NULL;
	int i;
	struct mgcp_conn_rtp *conn_net = NULL;
	struct mgcp_conn_rtp *conn_bts = NULL;

	for (i=0; i<cfg->trunk.number_endpoints; i++) {
		struct in_addr *this;

		endp = &cfg->trunk.endpoints[i];

#if 0
		if (!tmp->allocated)
			continue;
#endif

		switch(type) {
		case MGCP_DEST_NET:
			/* FIXME: Get rid of CONN_ID_XXX! */
			conn_net = mgcp_conn_get_rtp(endp, CONN_ID_NET);
			if (conn_net)
				this = &conn_net->end.addr;
			else
				this = NULL;
			break;
		case MGCP_DEST_BTS:
			/* FIXME: Get rid of CONN_ID_XXX! */
			conn_bts = mgcp_conn_get_rtp(endp, CONN_ID_BTS);
			if (conn_bts)
				this = &conn_bts->end.addr;
			else
				this = NULL;
			break;
		default:
			/* Should not ever happen */
			LOGP(DLMGCP, LOGL_ERROR, "Bad type %d. Fix your code.\n", type);
			return NULL;
		}

		/* FIXME: Get rid of CONN_ID_XXX! */
		conn_net = mgcp_conn_get_rtp(endp, CONN_ID_NET);
		if (conn_net && this && conn_net->osmux.cid == cid
		    && this->s_addr == from_addr->s_addr)
			return endp;
	}

	LOGP(DLMGCP, LOGL_ERROR, "Cannot find endpoint with cid=%d\n", cid);

	return NULL;
}

static void scheduled_tx_net_cb(struct msgb *msg, void *data)
{
	struct mgcp_endpoint *endp = data;
	struct mgcp_conn_rtp *conn_net = NULL;
	struct mgcp_conn_rtp *conn_bts = NULL;

	/* FIXME: Get rid of CONN_ID_XXX! */
	conn_bts = mgcp_conn_get_rtp(endp, CONN_ID_BTS);
	conn_net = mgcp_conn_get_rtp(endp, CONN_ID_NET);
	if (!conn_bts || !conn_net)
		return;

	struct sockaddr_in addr = {
		.sin_addr = conn_net->end.addr,
		.sin_port = conn_net->end.rtp_port,
	};

	rate_ctr_inc(&conn_bts->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR]);
	rate_ctr_add(&conn_bts->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR], msg->len);

	/* Send RTP data to NET */
	/* FIXME: Get rid of conn_bts and conn_net! */
	mgcp_send(endp, 1, &addr, (char *)msg->data, msg->len,
		  conn_bts, conn_net);
	msgb_free(msg);
}

static void scheduled_tx_bts_cb(struct msgb *msg, void *data)
{
	struct mgcp_endpoint *endp = data;
	struct mgcp_conn_rtp *conn_net = NULL;
	struct mgcp_conn_rtp *conn_bts = NULL;

	/* FIXME: Get rid of CONN_ID_XXX! */
	conn_bts = mgcp_conn_get_rtp(endp, CONN_ID_BTS);
	conn_net = mgcp_conn_get_rtp(endp, CONN_ID_NET);
	if (!conn_bts || !conn_net)
		return;

	struct sockaddr_in addr = {
		.sin_addr = conn_bts->end.addr,
		.sin_port = conn_bts->end.rtp_port,
	};

	rate_ctr_inc(&conn_net->rate_ctr_group->ctr[RTP_PACKETS_TX_CTR]);
	rate_ctr_add(&conn_net->rate_ctr_group->ctr[RTP_OCTETS_TX_CTR], msg->len);

	/* Send RTP data to BTS */
	/* FIXME: Get rid of conn_bts and conn_net! */
	mgcp_send(endp, 1, &addr, (char *)msg->data, msg->len,
		  conn_net, conn_bts);
	msgb_free(msg);
}

static struct msgb *osmux_recv(struct osmo_fd *ofd, struct sockaddr_in *addr)
{
	struct msgb *msg;
	socklen_t slen = sizeof(*addr);
	int ret;

	msg = msgb_alloc(4096, "OSMUX");
	if (!msg) {
		LOGP(DLMGCP, LOGL_ERROR, "cannot allocate message\n");
		return NULL;
	}
	ret = recvfrom(ofd->fd, msg->data, msg->data_len, 0,
			(struct sockaddr *)addr, &slen);
	if (ret <= 0) {
		msgb_free(msg);
		LOGP(DLMGCP, LOGL_ERROR, "cannot receive message\n");
		return NULL;
	}
	msgb_put(msg, ret);

	return msg;
}

/* Updates endp osmux state and returns 0 if it can process messages, -1 otherwise */
static int endp_osmux_state_check(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
				  bool sending)
{
	switch(conn->osmux.state) {
	case OSMUX_STATE_ACTIVATING:
	if (osmux_enable_conn(endp, conn, &conn->end.addr, htons(endp->cfg->osmux_port)) < 0) {
			LOGP(DLMGCP, LOGL_ERROR,
				"Could not enable osmux for conn:%s\n",
				mgcp_conn_dump(conn->conn));
			return -1;
		}
		LOGP(DLMGCP, LOGL_ERROR,
		    "Osmux CID %u for %s:%u is now enabled\n",
		    conn->osmux.cid, inet_ntoa(conn->end.addr),
		    endp->cfg->osmux_port);
		return 0;
	case OSMUX_STATE_ENABLED:
		return 0;
	default:
		LOGP(DLMGCP, LOGL_ERROR,
		     "Osmux %s in conn %s without full negotiation, state %d\n",
		     sending ? "sent" : "received",
		     mgcp_conn_dump(conn->conn), conn->osmux.state);
		return -1;
	}
}

static int osmux_legacy_dummy_parse_cid(struct sockaddr_in *addr, struct msgb *msg,
					uint8_t *osmux_cid)
{
	if (msg->len < 1 + sizeof(osmux_cid)) {
		LOGP(DLMGCP, LOGL_ERROR,
		     "Discarding truncated Osmux dummy load\n");
		return -1;
	}

	/* extract the osmux CID from the dummy message */
	memcpy(osmux_cid, &msg->data[1], sizeof(*osmux_cid));
	return 0;
}

#define osmux_chunk_length(msg, rem) (rem - msg->len);

int osmux_read_from_bsc_nat_cb(struct osmo_fd *ofd, unsigned int what)
{
	struct msgb *msg;
	struct osmux_hdr *osmuxh;
	struct sockaddr_in addr;
	struct mgcp_config *cfg = ofd->data;
	uint32_t rem;
	struct mgcp_conn_rtp *conn_bts = NULL;

	msg = osmux_recv(ofd, &addr);
	if (!msg)
		return -1;

	if (!cfg->osmux) {
		LOGP(DLMGCP, LOGL_ERROR,
		     "bsc-nat wants to use Osmux but bsc did not request it\n");
		goto out;
	}

	/* not any further processing dummy messages */
	if (msg->data[0] == MGCP_DUMMY_LOAD)
		goto out;

	rem = msg->len;
	while((osmuxh = osmux_xfrm_output_pull(msg)) != NULL) {
		struct mgcp_endpoint *endp;

		/* Yes, we use MGCP_DEST_NET to locate the origin */
		endp = endpoint_lookup(cfg, osmuxh->circuit_id,
				       &addr.sin_addr, MGCP_DEST_NET);

		/* FIXME: Get rid of CONN_ID_XXX! */
		conn_bts = mgcp_conn_get_rtp(endp, CONN_ID_BTS);
		if (!conn_bts)
			continue;

		if (!endp) {
			LOGP(DLMGCP, LOGL_ERROR,
			     "Cannot find an endpoint for circuit_id=%d\n",
			     osmuxh->circuit_id);
			goto out;
		}
		if (endp_osmux_state_check(endp, conn_bts, false) == 0) {
			conn_bts->osmux.stats.octets += osmux_chunk_length(msg, rem);
			conn_bts->osmux.stats.chunks++;
			osmux_xfrm_output_sched(&conn_bts->osmux.out, osmuxh);
		}
		rem = msg->len;
	}
out:
	msgb_free(msg);
	return 0;
}

/* This is called from the bsc-nat */
static int osmux_handle_dummy(struct mgcp_config *cfg, struct sockaddr_in *addr,
			      struct msgb *msg, int endp_type)
{
	struct mgcp_endpoint *endp;
	uint8_t osmux_cid;
	struct mgcp_conn_rtp *conn = NULL;

	if (osmux_legacy_dummy_parse_cid(addr, msg, &osmux_cid) < 0)
		goto out;

	endp = endpoint_lookup(cfg, osmux_cid, &addr->sin_addr, endp_type);
	if (!endp) {
		LOGP(DLMGCP, LOGL_ERROR,
		     "Cannot find endpoint for Osmux CID %d\n", osmux_cid);
		goto out;
	}

	/* FIXME: Get rid of CONN_ID_XXX! */
	conn = mgcp_conn_get_rtp(endp, endp_type == MGCP_DEST_BTS ? CONN_ID_NET : CONN_ID_BTS);
	if (!conn)
		goto out;

	endp_osmux_state_check(endp, conn, false);
	/* Only needed to punch hole in firewall, it can be dropped */
out:
	msgb_free(msg);
	return 0;
}

int osmux_read_from_bsc_cb(struct osmo_fd *ofd, unsigned int what)
{
	struct msgb *msg;
	struct osmux_hdr *osmuxh;
	struct sockaddr_in addr;
	struct mgcp_config *cfg = ofd->data;
	uint32_t rem;
	struct mgcp_conn_rtp *conn_net = NULL;

	msg = osmux_recv(ofd, &addr);
	if (!msg)
		return -1;

	if (!cfg->osmux) {
		LOGP(DLMGCP, LOGL_ERROR,
		     "bsc wants to use Osmux but bsc-nat did not request it\n");
		goto out;
	}

	/* not any further processing dummy messages */
	if (msg->data[0] == MGCP_DUMMY_LOAD)
		return osmux_handle_dummy(cfg, &addr, msg, MGCP_DEST_BTS);

	rem = msg->len;
	while((osmuxh = osmux_xfrm_output_pull(msg)) != NULL) {
		struct mgcp_endpoint *endp;

		/* Yes, we use MGCP_DEST_BTS to locate the origin */
		endp = endpoint_lookup(cfg, osmuxh->circuit_id,
				       &addr.sin_addr, MGCP_DEST_BTS);

		/* FIXME: Get rid of CONN_ID_XXX! */
		conn_net = mgcp_conn_get_rtp(endp, CONN_ID_NET);
		if (!conn_net)
			continue;

		if (!endp) {
			LOGP(DLMGCP, LOGL_ERROR,
			     "Cannot find an endpoint for circuit_id=%d\n",
			     osmuxh->circuit_id);
			goto out;
		}
		if (endp_osmux_state_check(endp, conn_net, false) == 0) {
			conn_net->osmux.stats.octets += osmux_chunk_length(msg, rem);
			conn_net->osmux.stats.chunks++;
			osmux_xfrm_output_sched(&conn_net->osmux.out, osmuxh);
		}
		rem = msg->len;
	}
out:
	msgb_free(msg);
	return 0;
}

int osmux_init(int role, struct mgcp_config *cfg)
{
	int ret;

	switch(role) {
	case OSMUX_ROLE_BSC:
		osmux_fd.cb = osmux_read_from_bsc_nat_cb;
		break;
	case OSMUX_ROLE_BSC_NAT:
		osmux_fd.cb = osmux_read_from_bsc_cb;
		break;
	default:
		LOGP(DLMGCP, LOGL_ERROR, "wrong role for OSMUX\n");
		return -1;
	}
	osmux_fd.data = cfg;

	ret = mgcp_create_bind(cfg->osmux_addr, &osmux_fd, cfg->osmux_port);
	if (ret < 0) {
		LOGP(DLMGCP, LOGL_ERROR, "cannot bind OSMUX socket\n");
		return ret;
	}
	mgcp_set_ip_tos(osmux_fd.fd, cfg->endp_dscp);
	osmux_fd.when |= BSC_FD_READ;

	ret = osmo_fd_register(&osmux_fd);
	if (ret < 0) {
		LOGP(DLMGCP, LOGL_ERROR, "cannot register OSMUX socket\n");
		return ret;
	}
	cfg->osmux_init = 1;

	return 0;
}

/*! enable OSXMUX circuit for a specified connection.
 *  \param[in] endp mgcp endpoint (configuration)
 *  \param[in] conn connection to disable
 *  \param[in] addr IP address of remote OSMUX endpoint
 *  \param[in] port portnumber of the remote OSMUX endpoint
 *  \returns 0 on success, -1 on ERROR */
int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
		      struct in_addr *addr, uint16_t port)
{
	/*! If osmux is enabled, initialize the output handler. This handler is
	 *  used to reconstruct the RTP flow from osmux. The RTP SSRC is
	 *  allocated based on the circuit ID (conn_net->osmux.cid), which is unique
	 *  in the local scope to the BSC/BSC-NAT. We use it to divide the RTP
	 *  SSRC space (2^32) by the OSMUX_CID_MAX + 1 possible circuit IDs, then randomly
	 *  select one value from that window. Thus, we have no chance to have
	 *  overlapping RTP SSRC traveling to the BTSes behind the BSC,
	 *  similarly, for flows traveling to the MSC.
	 */
	static const uint32_t rtp_ssrc_winlen = UINT32_MAX / (OSMUX_CID_MAX + 1);
	uint16_t osmux_dummy = endp->cfg->osmux_dummy;

	/* Check if osmux is enabled for the specified connection */
	if (conn->osmux.state != OSMUX_STATE_ACTIVATING) {
		LOGP(DLMGCP, LOGL_ERROR, "conn:%s didn't negotiate Osmux, state %d\n",
		     mgcp_conn_dump(conn->conn), conn->osmux.state);
		return -1;
	}

	conn->osmux.in = osmux_handle_lookup(endp->cfg, addr, port);
	if (!conn->osmux.in) {
		LOGP(DLMGCP, LOGL_ERROR, "Cannot allocate input osmux handle for conn:%s\n",
		     mgcp_conn_dump(conn->conn));
		return -1;
	}
	if (!osmux_xfrm_input_open_circuit(conn->osmux.in, conn->osmux.cid, osmux_dummy)) {
		LOGP(DLMGCP, LOGL_ERROR, "Cannot open osmux circuit %u for conn:%s\n",
		     conn->osmux.cid, mgcp_conn_dump(conn->conn));
		return -1;
	}

	osmux_xfrm_output_init(&conn->osmux.out,
			       (conn->osmux.cid * rtp_ssrc_winlen) +
			       (random() % rtp_ssrc_winlen));

	switch (endp->cfg->role) {
		case MGCP_BSC_NAT:
			conn->type = MGCP_OSMUX_BSC_NAT;
			osmux_xfrm_output_set_tx_cb(&conn->osmux.out,
							scheduled_tx_net_cb, endp);
			break;
		case MGCP_BSC:
			conn->type = MGCP_OSMUX_BSC;
			osmux_xfrm_output_set_tx_cb(&conn->osmux.out,
							scheduled_tx_bts_cb, endp);
			break;
	}

	conn->osmux.state = OSMUX_STATE_ENABLED;

	return 0;
}

/*! disable OSXMUX circuit for a specified connection.
 *  \param[in] conn connection to disable */
void osmux_disable_conn(struct mgcp_conn_rtp *conn)
{
	if (!conn)
		return;

	if (conn->osmux.state != OSMUX_STATE_ENABLED)
		return;

	LOGP(DLMGCP, LOGL_INFO, "Releasing connection %s using Osmux CID %u\n",
	     conn->conn->id, conn->osmux.cid);

	/* We are closing, we don't need pending RTP packets to be transmitted */
	osmux_xfrm_output_set_tx_cb(&conn->osmux.out, NULL, NULL);
	osmux_xfrm_output_flush(&conn->osmux.out);

	osmux_xfrm_input_close_circuit(conn->osmux.in, conn->osmux.cid);
	conn->osmux.state = OSMUX_STATE_DISABLED;
	conn->osmux.cid = -1;
	osmux_handle_put(conn->osmux.in);
}

/*! relase OSXMUX cid, that had been allocated to this connection.
 *  \param[in] conn connection with OSMUX cid to release */
void osmux_release_cid(struct mgcp_conn_rtp *conn)
{
	if (!conn)
		return;

	if (conn->osmux.state != OSMUX_STATE_ENABLED)
		return;

	if (conn->osmux.allocated_cid >= 0)
		osmux_put_cid(conn->osmux.allocated_cid);
	conn->osmux.allocated_cid = -1;
}

/*! allocate OSXMUX cid to connection.
 *  \param[in] conn connection for which we allocate the OSMUX cid*/
void osmux_allocate_cid(struct mgcp_conn_rtp *conn)
{
	osmux_release_cid(conn);
	conn->osmux.allocated_cid = osmux_get_cid();
}

/*! send RTP dummy packet to OSMUX connection port.
 *  \param[in] endp mcgp endpoint that holds the RTP connection
 *  \param[in] conn associated RTP connection
 *  \returns bytes sent, -1 on error */
int osmux_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn)
{
	char buf[1 + sizeof(uint8_t)];
	struct in_addr addr_unset = {};

	/*! The dummy packet will not be sent via the actual OSMUX connection,
	 *  instead it is sent out of band to port where the remote OSMUX
	 *  multplexer is listening. The goal is to ensure that the connection
	 *  is kept open */

	/*! We don't need to send the dummy load for osmux so often as another
	 *  endpoint may have already punched the hole in the firewall. This
	 *  approach is simple though. */

	buf[0] = MGCP_DUMMY_LOAD;
	memcpy(&buf[1], &conn->osmux.cid, sizeof(conn->osmux.cid));

	/* Wait until we have the connection information from MDCX */
	if (memcmp(&conn->end.addr, &addr_unset, sizeof(addr_unset)) == 0)
		return 0;

	if (endp_osmux_state_check(endp, conn, true) < 0)
		return 0;

	LOGP(DLMGCP, LOGL_DEBUG,
	     "sending OSMUX dummy load to %s CID %u\n",
	     inet_ntoa(conn->end.addr), conn->osmux.cid);

	return mgcp_udp_send(osmux_fd.fd, &conn->end.addr,
			     htons(endp->cfg->osmux_port), buf, sizeof(buf));
}

/* bsc-nat allocates/releases the Osmux circuit ID. +7 to round up to 8 bit boundary. */
static uint8_t osmux_cid_bitmap[(OSMUX_CID_MAX + 1 + 7) / 8];

/*! count the number of taken OSMUX cids.
 *  \returns number of OSMUX cids in use */
int osmux_used_cid(void)
{
	int i, j, used = 0;

	for (i = 0; i < sizeof(osmux_cid_bitmap); i++) {
		for (j = 0; j < 8; j++) {
			if (osmux_cid_bitmap[i] & (1 << j))
				used += 1;
		}
	}

	return used;
}

/*! take a free OSMUX cid.
 *  \returns OSMUX cid */
int osmux_get_cid(void)
{
	int i, j;

	for (i = 0; i < sizeof(osmux_cid_bitmap); i++) {
		for (j = 0; j < 8; j++) {
			if (osmux_cid_bitmap[i] & (1 << j))
				continue;

			osmux_cid_bitmap[i] |= (1 << j);
			LOGP(DLMGCP, LOGL_DEBUG,
			     "Allocating Osmux CID %u from pool\n", (i * 8) + j);
			return (i * 8) + j;
		}
	}

	LOGP(DLMGCP, LOGL_ERROR, "All Osmux circuits are in use!\n");
	return -1;
}

/*! put back a no longer used OSMUX cid.
 *  \param[in] osmux_cid OSMUX cid */
void osmux_put_cid(uint8_t osmux_cid)
{
	LOGP(DLMGCP, LOGL_DEBUG, "Osmux CID %u is back to the pool\n", osmux_cid);
	osmux_cid_bitmap[osmux_cid / 8] &= ~(1 << (osmux_cid % 8));
}
