/* MTP level3 link */
/*
 * (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 <mtp_data.h>
#include <mtp_level3.h>
#include <cellmgr_debug.h>
#include <counter.h>

#include <osmocore/talloc.h>

#include <string.h>

static struct msgb *mtp_create_sltm(struct mtp_link *link)
{
	const uint8_t test_ptrn[14] = { 'G', 'S', 'M', 'M', 'M', 'S', };
	struct mtp_level_3_hdr *hdr;
	struct mtp_level_3_mng *mng;
	struct msgb *msg = mtp_msg_alloc(link->set);
	uint8_t *data;
	if (!msg)
		return NULL;

	hdr = (struct mtp_level_3_hdr *) msg->l2h;
	hdr->ser_ind = MTP_SI_MNT_REG_MSG;
	hdr->addr = MTP_ADDR(link->nr % 16, link->set->dpc, link->set->opc);

	mng = (struct mtp_level_3_mng *) msgb_put(msg, sizeof(*mng));
	mng->cmn.h0 = MTP_TST_MSG_GRP;
	mng->cmn.h1 = MTP_TST_MSG_SLTM;
	mng->length = ARRAY_SIZE(test_ptrn);

	data = msgb_put(msg, ARRAY_SIZE(test_ptrn));
	memcpy(data, test_ptrn, ARRAY_SIZE(test_ptrn));

	/* remember the last tst ptrn... once we have some */
	memcpy(link->test_ptrn, test_ptrn, ARRAY_SIZE(test_ptrn));

	return msg;
}

static void mtp_send_sltm(struct mtp_link *link)
{
	struct msgb *msg;

	link->sltm_pending = 1;
	msg = mtp_create_sltm(link);
	if (!msg) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate SLTM on link %d/%s of %d/%s.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
		return;
	}

	mtp_link_submit(link, msg);
}

static void mtp_sltm_t1_timeout(void *_link)
{
	struct mtp_link *link = (struct mtp_link *) _link;

	rate_ctr_inc(&link->ctrg->ctr[MTP_LNK_SLTM_TOUT]);

	if (link->slta_misses == 0) {
		LOGP(DINP, LOGL_ERROR,
		     "No SLTM response on link %d/%s of %d/%s.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
		++link->slta_misses;
		mtp_send_sltm(link);
		bsc_schedule_timer(&link->t1_timer, MTP_T1);
	} else {
		LOGP(DINP, LOGL_ERROR,
		     "Two missing SLTAs on link %d/%s of %d/%s.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
		bsc_del_timer(&link->t2_timer);
		mtp_link_failure(link);
	}
}

static void mtp_sltm_t2_timeout(void *_link)
{
	struct mtp_link *link = (struct mtp_link *) _link;

	if (!link->set->running) {
		LOGP(DINP, LOGL_INFO,
		     "The linkset is not active. Stopping link test on %d/%s of %d/%s.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
		return;
	}

	link->slta_misses = 0;
	mtp_send_sltm(link);

	bsc_schedule_timer(&link->t1_timer, MTP_T1);

	if (link->set->sltm_once && link->was_up)
		LOGP(DINP, LOGL_INFO, "Not sending SLTM again on link %d/%s of %d/%s.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
	else
		bsc_schedule_timer(&link->t2_timer, MTP_T2);
}

void mtp_link_stop_link_test(struct mtp_link *link)
{
	bsc_del_timer(&link->t1_timer);
	bsc_del_timer(&link->t2_timer);

	link->sltm_pending = 0;
}

void mtp_link_start_link_test(struct mtp_link *link)
{
	if (link->blocked) {
		LOGP(DINP, LOGL_ERROR, "Not starting linktest on %d/%s of %d/%s.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
		return;
	}

	mtp_sltm_t2_timeout(link);
}

int mtp_link_slta(struct mtp_link *link, uint16_t l3_len,
		  struct mtp_level_3_mng *mng)
{
	if (mng->length != 14) {
		LOGP(DINP, LOGL_ERROR, "Wrongly sized SLTA: %u\n", mng->length);
		return -1;
	}

	if (l3_len != 16) {
		LOGP(DINP, LOGL_ERROR, "Wrongly sized SLTA: %u\n", mng->length);
		return -1;
	}

	if (memcmp(mng->data, link->test_ptrn, sizeof(link->test_ptrn)) != 0) {
		LOGP(DINP, LOGL_ERROR, "Wrong test pattern SLTA\n");
		return -1;
	}

	/* we had a matching slta */
	bsc_del_timer(&link->t1_timer);
	link->sltm_pending = 0;
	link->was_up = 1;

	return 0;
}

void mtp_link_failure(struct mtp_link *link)
{
	if (link->blocked) {
		LOGP(DINP, LOGL_ERROR, "Ignoring failure on blocked link %d/%s on %d/%s.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
		return;
	}

	LOGP(DINP, LOGL_ERROR, "Link %d/%s of %d/%s has failed, going to reset it.\n",
		     link->nr, link->name, link->set->nr, link->set->name);
	rate_ctr_inc(&link->ctrg->ctr[MTP_LNK_ERROR]);
	link->reset(link);
}

void mtp_link_block(struct mtp_link *link)
{
	link->blocked = 1;
	link->shutdown(link);
}

void mtp_link_unblock(struct mtp_link *link)
{
	if (!link->blocked)
		return;
	link->blocked = 0;
	link->reset(link);
}

static int dummy_arg1(struct mtp_link *link)
{
	LOGP(DINP, LOGL_ERROR, "The link %d/%s of linkset %d/%s is not typed.\n",
	     link->nr, link->name, link->set->nr, link->set->name);
	return 0;
}

static int dummy_arg2(struct mtp_link *link, struct msgb *msg)
{
	LOGP(DINP, LOGL_ERROR, "The link %d/%s of linkset %d/%s is not typed.\n",
	     link->nr, link->name, link->set->nr, link->set->name);
	msgb_free(msg);
	return 0;
}

struct mtp_link *mtp_link_alloc(struct mtp_link_set *set)
{
	struct mtp_link *link;

	link = talloc_zero(set, struct mtp_link);
	if (!link) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate the link.\n");
		return NULL;
	}

	link->nr = set->nr_links++;
	link->ctrg = rate_ctr_group_alloc(link,
					  mtp_link_rate_ctr_desc(), link->nr);
	if (!link->ctrg) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate rate_ctr.\n");
		talloc_free(link);
		return NULL;
	}

	/* make sure a unconfigured link does not crash */
	link->start = dummy_arg1;
	link->write = dummy_arg2;
	link->shutdown = dummy_arg1;
	link->reset = dummy_arg1;
	link->clear_queue = dummy_arg1;

	link->pcap_fd = -1;

	link->t1_timer.data = link;
	link->t1_timer.cb = mtp_sltm_t1_timeout;
	link->t2_timer.data = link;
	link->t2_timer.cb = mtp_sltm_t2_timeout;

	link->set = set;

	llist_add_tail(&link->entry, &set->links);
	mtp_link_set_init_slc(set);

	return link;
}

struct mtp_link *mtp_link_num(struct mtp_link_set *set, int num)
{
	struct mtp_link *link;

	llist_for_each_entry(link, &set->links, entry)
		if (link->nr == num)
			return link;

	return NULL;
}
