/* 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 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 <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;
}
