/* Create GSM 08.08 messages */
/*
 * (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 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 <bssap_sccp.h>
#include <cellmgr_debug.h>

#include <osmocore/msgb.h>
#include <osmocore/protocol/gsm_08_08.h>

#include <string.h>


struct msgb *create_clear_command(struct sccp_source_reference *dest_ref)
{
	struct sccp_data_form1 *form1;
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "clear command");
	if (!msg) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate clear command.\n");
		return NULL;
	}

	msg->l2h = msgb_put(msg, sizeof(*form1));
	form1 = (struct sccp_data_form1 *) msg->l2h;
	form1->type = SCCP_MSG_TYPE_DT1;
	form1->destination_local_reference = *dest_ref;
	form1->segmenting = 0;
	form1->variable_start = 1;

	/* create a Clear Command Call Control msg */
	msg->l3h = msgb_put(msg, 7);
	msg->l3h[0] = msgb_l3len(msg) - 1;
	msg->l3h[1] = BSSAP_MSG_BSS_MANAGEMENT;
	msg->l3h[2] = msg->l3h[0] - 2;
	msg->l3h[3] = BSS_MAP_MSG_CLEAR_CMD;
	msg->l3h[4] = 4;
	msg->l3h[5] = 1;
	msg->l3h[6] = 0x09;

	return msg;
}

struct msgb *create_sccp_rlsd(struct sccp_source_reference *src_ref,
			      struct sccp_source_reference *dst_ref)
{
	struct sccp_connection_released *rel;
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "rlsd");
	if (!msg) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate clear command.\n");
		return NULL;
	}

	msg->l2h = msgb_put(msg, sizeof(*rel));
	rel = (struct sccp_connection_released *) msg->l2h;
	rel->type = SCCP_MSG_TYPE_RLSD;
	rel->release_cause = SCCP_RELEASE_CAUSE_END_USER_ORIGINATED;
	rel->destination_local_reference = *dst_ref;
	rel->source_local_reference = *src_ref;

	return msg;
}

struct msgb *create_sccp_rlc(struct sccp_source_reference *src_ref,
			     struct sccp_source_reference *dst_ref)
{
	struct sccp_connection_release_complete *rlc;
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "rlc");
	if (!msg) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate rlc.\n");
		return NULL;
	}

	msg->l2h = msgb_put(msg, sizeof(*rlc));
	rlc = (struct sccp_connection_release_complete *) msg->l2h;
	rlc->type = SCCP_MSG_TYPE_RLC;
	rlc->destination_local_reference = *dst_ref;
	rlc->source_local_reference = *src_ref;

	return msg;
}

struct msgb *create_sccp_refuse(struct sccp_source_reference *dest_ref)
{
	struct sccp_connection_refused *ref;
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "rlsd");
	if (!msg) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate connection refuse.\n");
		return NULL;
	}

	msg->l2h = msgb_put(msg, sizeof(*ref));
	ref = (struct sccp_connection_refused *) msg->l2h;
	ref->type = SCCP_MSG_TYPE_CREF;
	ref->destination_local_reference = *dest_ref;
	ref->cause = SCCP_REFUSAL_END_USER_ORIGINATED;
	ref->optional_start = 1;

	msg->l3h = msgb_put(msg, 1);
	msg->l3h[0] = SCCP_PNC_END_OF_OPTIONAL;

	return msg;
}

struct msgb *create_reset()
{
	static const uint8_t reset[] = {
		0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
		0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
		0x01, 0x20
	};

	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "reset");
	if (!msg) {
		LOGP(DMSC, LOGL_ERROR, "Failed to allocate reset msg.\n");
		return NULL;
	}

	msg->l2h = msgb_put(msg, sizeof(reset));
	memcpy(msg->l2h, reset, msgb_l2len(msg));
	return msg;
}
