/* high-level RANAP messsage generation code */

/* (C) 2015 by Harald Welte <laforge@gnumonks.org>
 * 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 <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>

#include "asn1helpers.h"
#include <osmocom/ranap/iu_helpers.h>

#include <osmocom/ranap/ranap_common.h>
#include <osmocom/ranap/ranap_ies_defs.h>
#include <osmocom/ranap/ranap_msg_factory.h>

#define DRANAP _ranap_DRANAP

/*! \brief allocate a new long and assing a value to it */
static long *new_long(long in)
{
	long *out = CALLOC(1, sizeof(long));
	*out = in;
	return out;
}

/*! \brief generate RANAP RESET message */
struct msgb *ranap_new_msg_reset(RANAP_CN_DomainIndicator_t domain,
				 const RANAP_Cause_t *cause)
{
	RANAP_ResetIEs_t ies;
	RANAP_Reset_t out;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	ies.cN_DomainIndicator = domain;
	if (cause)
		memcpy(&ies.cause, cause, sizeof(ies.cause));

	memset(&out, 0, sizeof(out));
	rc = ranap_encode_reseties(&out, &ies);
	if (rc < 0) {
		LOGP(DRANAP, LOGL_ERROR, "error encoding reset IEs: %d\n", rc);
		return NULL;
	}

	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Reset,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_Reset,
						&out);

	/* release dynamic allocations attached to dt */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Reset, &out);

	return msg;
}

/*! \brief generate RANAP RESET ACK message */
struct msgb *ranap_new_msg_reset_ack(RANAP_CN_DomainIndicator_t domain,
				     RANAP_GlobalRNC_ID_t *rnc_id)
{
	RANAP_ResetAcknowledgeIEs_t ies;
	RANAP_ResetAcknowledge_t out;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	ies.cN_DomainIndicator = domain;

	/* The RNC shall include the globalRNC_ID in the RESET
	 * ACKNOWLEDGE message to the CN */
	if (rnc_id) {
		ies.presenceMask = RESETACKNOWLEDGEIES_RANAP_GLOBALRNC_ID_PRESENT;
		OCTET_STRING_noalloc(&ies.globalRNC_ID.pLMNidentity,
				     rnc_id->pLMNidentity.buf,
				     rnc_id->pLMNidentity.size);
		ies.globalRNC_ID.rNC_ID = rnc_id->rNC_ID;
	}

	/* FIXME: Do we need criticalityDiagnostics */

	memset(&out, 0, sizeof(out));
	rc = ranap_encode_resetacknowledgeies(&out, &ies);
	if (rc < 0) {
		LOGP(DRANAP, LOGL_ERROR, "error encoding reset ack IEs: %d\n", rc);
		return NULL;
	}

	msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_Reset,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_ResetAcknowledge,
						&out);

	/* release dynamic allocations attached to dt */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_ResetAcknowledge, &out);

	return msg;
}

/*! \brief generate RANAP INITIAL UE message */
struct msgb *ranap_new_msg_initial_ue(uint32_t conn_id, int is_ps,
				     RANAP_GlobalRNC_ID_t *rnc_id,
				     uint8_t *nas_pdu, unsigned int nas_len)
{
	RANAP_InitialUE_MessageIEs_t ies;
	RANAP_InitialUE_Message_t out;
	struct msgb *msg;
	uint32_t ctxidbuf;
	int rc;
	uint16_t buf0 = 0x2342;

	memset(&ies, 0, sizeof(ies));
	if (is_ps)
		ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain;

	OCTET_STRING_noalloc(&ies.lai.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
	OCTET_STRING_noalloc(&ies.lai.lAC, (uint8_t *)&buf0, sizeof(buf0));

	OCTET_STRING_noalloc(&ies.sai.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
	OCTET_STRING_noalloc(&ies.sai.lAC, (uint8_t *)&buf0, sizeof(buf0));
	OCTET_STRING_noalloc(&ies.sai.sAC, (uint8_t *)&buf0, sizeof(buf0));

	OCTET_STRING_noalloc(&ies.nas_pdu, nas_pdu, nas_len);
	asn1_u24_to_bitstring(&ies.iuSigConId, &ctxidbuf, conn_id);
	OCTET_STRING_noalloc(&ies.globalRNC_ID.pLMNidentity, rnc_id->pLMNidentity.buf, rnc_id->pLMNidentity.size);
	ies.globalRNC_ID.rNC_ID = rnc_id->rNC_ID;

	memset(&out, 0, sizeof(out));
	rc = ranap_encode_initialue_messageies(&out, &ies);
	if (rc < 0) {
		LOGP(DRANAP, LOGL_ERROR, "error encoding initial UE IEs: %d\n", rc);
		return NULL;
	}

	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_InitialUE_Message,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_InitialUE_Message,
						&out);

	/* release dynamic allocations attached to dt */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_InitialUE_Message, &out);

	return msg;
}


/*! \brief generate RANAP DIRECT TRANSFER message */
struct msgb *ranap_new_msg_dt(uint8_t sapi, const uint8_t *nas, unsigned int nas_len)
{
	RANAP_DirectTransferIEs_t ies;
	RANAP_DirectTransfer_t dt;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&dt, 0, sizeof(dt));

	/* only SAPI optional field shall be present for CN->RNC */
	ies.presenceMask = DIRECTTRANSFERIES_RANAP_SAPI_PRESENT;

	if (sapi == 3)
		ies.sapi = RANAP_SAPI_sapi_3;
	else
		ies.sapi = RANAP_SAPI_sapi_0;

	/* Avoid copying + later freeing of OCTET STRING */
	OCTET_STRING_noalloc(&ies.nas_pdu, nas, nas_len);

	/* ies -> dt */
	rc = ranap_encode_directtransferies(&dt, &ies);

	/* dt -> msg */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_DirectTransfer,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_DirectTransfer,
						&dt);

	/* release dynamic allocations attached to dt */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_DirectTransfer, &dt);

	return msg;
}

static const enum RANAP_IntegrityProtectionAlgorithm ip_alg[2] = {
	RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA1,
	RANAP_IntegrityProtectionAlgorithm_standard_UMTS_integrity_algorithm_UIA2,
};

static const RANAP_EncryptionAlgorithm_t enc_alg[2] = {
	RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorith_UEA1,
	RANAP_EncryptionAlgorithm_standard_UMTS_encryption_algorithm_UEA2,
};

/*! \brief generate RANAP SECURITY MODE COMMAND message */
struct msgb *ranap_new_msg_sec_mod_cmd(const uint8_t *ik, const uint8_t *ck, enum RANAP_KeyStatus status)
{
	RANAP_SecurityModeCommandIEs_t ies;
	RANAP_SecurityModeCommand_t out;
	struct msgb *msg;
	int i, rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
		/* needs to be dynamically allocated, as
		 * SET_OF_free() will call FREEMEM() on it */
		RANAP_IntegrityProtectionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
		*alg = ip_alg[i];
		ASN_SEQUENCE_ADD(&ies.integrityProtectionInformation.permittedAlgorithms, alg);
	}

	BIT_STRING_fromBuf(&ies.integrityProtectionInformation.key, ik, 16*8);

	if (ck) {
		ies.presenceMask = SECURITYMODECOMMANDIES_RANAP_ENCRYPTIONINFORMATION_PRESENT;
		for (i = 0; i < ARRAY_SIZE(ip_alg); i++) {
			/* needs to be dynamically allocated, as
			 * SET_OF_free() will call FREEMEM() on it */
			RANAP_EncryptionAlgorithm_t *alg = CALLOC(1, sizeof(*alg));
			*alg = enc_alg[i];
			ASN_SEQUENCE_ADD(&ies.encryptionInformation.permittedAlgorithms, alg);
		}
		BIT_STRING_fromBuf(&ies.encryptionInformation.key, ck, 16*8);
	}

	ies.keyStatus = status;

	/* ies -> out */
	rc = ranap_encode_securitymodecommandies(&out, &ies);

	/* release dynamic allocations attached to ies */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_IntegrityProtectionInformation, &ies.integrityProtectionInformation);
	if (ck)
		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_EncryptionInformation, &ies.encryptionInformation);

	/* out -> msg */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_SecurityModeControl,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_SecurityModeCommand,
						&out);

	/* release dynamic allocations attached to out */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_SecurityModeCommand, &out);

	return msg;
}

/*! \brief generate RANAP SECURITY MODE COMPLETE message */
struct msgb *ranap_new_msg_sec_mod_compl(
	RANAP_ChosenIntegrityProtectionAlgorithm_t chosen_ip_alg,
	RANAP_ChosenEncryptionAlgorithm_t chosen_enc_alg)
{
	RANAP_SecurityModeCompleteIEs_t ies;
	RANAP_SecurityModeComplete_t out;
	struct msgb *msg;
	int i, rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	ies.presenceMask = SECURITYMODECOMPLETEIES_RANAP_CHOSENENCRYPTIONALGORITHM_PRESENT;
	ies.chosenIntegrityProtectionAlgorithm = chosen_ip_alg;
	ies.chosenEncryptionAlgorithm = chosen_enc_alg;

	/* ies -> out */
	rc = ranap_encode_securitymodecompleteies(&out, &ies);

	/* out -> msg */
	msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_SecurityModeControl,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_SecurityModeComplete,
						&out);

	/* release dynamic allocations attached to out */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_SecurityModeComplete, &out);

	return msg;
}

/*! \brief generate RANAP COMMON ID message */
struct msgb *ranap_new_msg_common_id(const char *imsi)
{
	RANAP_CommonID_IEs_t ies;
	RANAP_CommonID_t out;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	if (imsi) {
		uint8_t *imsi_buf = CALLOC(1, 16);
		rc = ranap_imsi_encode(imsi_buf, 16, imsi);
		ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
		ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
		ies.permanentNAS_UE_ID.choice.iMSI.size = rc;
	} else
		ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_NOTHING;

	/* ies -> out */
	rc = ranap_encode_commonid_ies(&out, &ies);
	/* release dynamic allocations attached to ies */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
	if (rc < 0)
		return NULL;

	/* out -> msg */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_CommonID,
						RANAP_Criticality_ignore,
						&asn_DEF_RANAP_CommonID,
						&out);

	/* release dynamic allocations attached to out */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_CommonID, &out);

	return msg;
}

/*! \brief generate RANAP IU RELEASE COMMAND message */
struct msgb *ranap_new_msg_iu_rel_cmd(const RANAP_Cause_t *cause_in)
{
	RANAP_Iu_ReleaseCommandIEs_t ies;
	RANAP_Iu_ReleaseCommand_t out;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	memcpy(&ies.cause, cause_in, sizeof(ies.cause));

	/* ies -> out */
	rc = ranap_encode_iu_releasecommandies(&out, &ies);
	if (rc < 0)
		return NULL;

	/* out -> msg */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_Release,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_Iu_ReleaseCommand,
						&out);

	/* release dynamic allocations attached to out */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseCommand, &out);

	return msg;
}

/*! \brief generate RAPAP IU RELEASE COMPLETE message */
struct msgb *ranap_new_msg_iu_rel_compl(void)
{
	RANAP_Iu_ReleaseCompleteIEs_t ies;
	RANAP_Iu_ReleaseComplete_t out;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	/* ies -> out */
	rc = ranap_encode_iu_releasecompleteies(&out, &ies);
	if (rc < 0)
		return NULL;

	/* out -> msg */
	msg = ranap_generate_successful_outcome(RANAP_ProcedureCode_id_Iu_Release,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_Iu_ReleaseComplete,
						&out);

	/* release dynamic allocations attached to out */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseComplete, &out);

	return msg;
}

/*! \brief generate RANAP PAGING COMMAND message */
struct msgb *ranap_new_msg_paging_cmd(const char *imsi, const uint32_t *tmsi, int is_ps, uint32_t cause)
{
	RANAP_PagingIEs_t ies;
	RANAP_Paging_t out;
	struct msgb *msg;
	uint8_t *imsi_buf = CALLOC(1, 16);
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	/* put together the 'ies' */
	if (is_ps)
		ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RANAP_CN_DomainIndicator_cs_domain;

	rc = ranap_imsi_encode(imsi_buf, 16, imsi);
	ies.permanentNAS_UE_ID.present = RANAP_PermanentNAS_UE_ID_PR_iMSI;
	ies.permanentNAS_UE_ID.choice.iMSI.buf = imsi_buf;
	ies.permanentNAS_UE_ID.choice.iMSI.size = rc;

	if (tmsi) {
		uint32_t *tmsi_buf = CALLOC(1, sizeof(*tmsi_buf));
		*tmsi_buf = *tmsi;
		ies.presenceMask |= PAGINGIES_RANAP_TEMPORARYUE_ID_PRESENT;
		if (is_ps) {
			ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_p_TMSI;
			ies.temporaryUE_ID.choice.tMSI.buf = (uint8_t *) tmsi_buf;
			ies.temporaryUE_ID.choice.tMSI.size = sizeof(*tmsi_buf);
		} else {
			ies.temporaryUE_ID.present = RANAP_TemporaryUE_ID_PR_tMSI;
			ies.temporaryUE_ID.choice.p_TMSI.buf = (uint8_t *) tmsi_buf;
			ies.temporaryUE_ID.choice.p_TMSI.size = sizeof(*tmsi_buf);
		}
	}

	if (cause) {
		ies.presenceMask |= PAGINGIES_RANAP_PAGINGCAUSE_PRESENT;
		ies.pagingCause = cause;
	}

	/* ies -> out */
	rc = ranap_encode_pagingies(&out, &ies);
	/* release dynamic allocation attached to ies */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_PermanentNAS_UE_ID, &ies.permanentNAS_UE_ID);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_TemporaryUE_ID, &ies.temporaryUE_ID);
	if (rc < 0)
		return NULL;

	/* out -> msg */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Paging,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_Paging,
						&out);

	/* release dynamic allocations attached to out */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Paging, &out);

	return msg;
}

static RANAP_SDU_ErrorRatio_t *new_sdu_error_ratio(long mantissa, long exponent)
{
	RANAP_SDU_ErrorRatio_t *err = CALLOC(1, sizeof(*err));

	err->mantissa = mantissa;
	err->exponent = exponent;

	return err;
}


static RANAP_SDU_FormatInformationParameterItem_t *
new_format_info_pars(long sdu_size)
{
	RANAP_SDU_FormatInformationParameterItem_t *fmti = CALLOC(1, sizeof(*fmti));
	fmti->subflowSDU_Size = new_long(sdu_size);
	return fmti;
}

enum sdu_par_profile {
	SDUPAR_P_VOICE0,
	SDUPAR_P_VOICE1,
	SDUPAR_P_VOICE2,
	SDUPAR_P_DATA,
};

/* See Chapter 5 of TS 26.102 */
static RANAP_SDU_ParameterItem_t *new_sdu_par_item(enum sdu_par_profile profile)
{
	RANAP_SDU_ParameterItem_t *sdui = CALLOC(1, sizeof(*sdui));
	RANAP_SDU_FormatInformationParameters_t *fmtip = CALLOC(1, sizeof(*fmtip));
	RANAP_SDU_FormatInformationParameterItem_t *fmti;

	switch (profile) {
	case SDUPAR_P_VOICE0:
		sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 5);
		sdui->residualBitErrorRatio.mantissa = 1;
		sdui->residualBitErrorRatio.exponent = 6;
		sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_yes;
		sdui->sDU_FormatInformationParameters = fmtip;
		fmti = new_format_info_pars(81);
		ASN_SEQUENCE_ADD(fmtip, fmti);
		fmti = new_format_info_pars(39);
		ASN_SEQUENCE_ADD(fmtip, fmti);
		/* FIXME: could be 10 SDU descriptors for AMR! */
		break;
	case SDUPAR_P_VOICE1:
		sdui->residualBitErrorRatio.mantissa = 1;
		sdui->residualBitErrorRatio.exponent = 3;
		sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
		sdui->sDU_FormatInformationParameters = fmtip;
		fmti = new_format_info_pars(103);
		ASN_SEQUENCE_ADD(fmtip, fmti);
		fmti = new_format_info_pars(0);
		ASN_SEQUENCE_ADD(fmtip, fmti);
		/* FIXME: could be 10 SDU descriptors for AMR! */
		break;
	case SDUPAR_P_VOICE2:
		sdui->residualBitErrorRatio.mantissa = 5;
		sdui->residualBitErrorRatio.exponent = 3;
		sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no_error_detection_consideration;
		sdui->sDU_FormatInformationParameters = fmtip;
		fmti = new_format_info_pars(60);
		ASN_SEQUENCE_ADD(fmtip, fmti);
		fmti = new_format_info_pars(0);
		ASN_SEQUENCE_ADD(fmtip, fmti);
		/* FIXME: could be 10 SDU descriptors for AMR! */
		break;
	case SDUPAR_P_DATA:
		sdui->sDU_ErrorRatio = new_sdu_error_ratio(1, 4);
		sdui->residualBitErrorRatio.mantissa = 1;
		sdui->residualBitErrorRatio.exponent = 5;
		sdui->deliveryOfErroneousSDU = RANAP_DeliveryOfErroneousSDU_no;
		FREEMEM(fmtip);
		break;
	}

	return sdui;
}

static RANAP_AllocationOrRetentionPriority_t *
new_alloc_ret_prio(RANAP_PriorityLevel_t level, int capability, int vulnerability,
		   int queueing_allowed)
{
	RANAP_AllocationOrRetentionPriority_t *arp = CALLOC(1, sizeof(*arp));

	arp->priorityLevel = level;

	if (capability)
		arp->pre_emptionCapability = RANAP_Pre_emptionCapability_may_trigger_pre_emption;
	else
		arp->pre_emptionCapability = RANAP_Pre_emptionCapability_shall_not_trigger_pre_emption;

	if (vulnerability)
		arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_pre_emptable;
	else
		arp->pre_emptionVulnerability = RANAP_Pre_emptionVulnerability_not_pre_emptable;

	if (queueing_allowed)
		arp->queuingAllowed = RANAP_QueuingAllowed_queueing_allowed;
	else
		arp->queuingAllowed = RANAP_QueuingAllowed_queueing_not_allowed;

	return arp;
}

/* See Chapter 5 of TS 26.102 */
static RANAP_RAB_Parameters_t *new_rab_par_voice(void)
{
	RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
	RANAP_SDU_ParameterItem_t *sdui;

	rab->trafficClass = RANAP_TrafficClass_conversational;
	rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_symmetric_bidirectional;

	ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(12200));
	rab->guaranteedBitRate = CALLOC(1, sizeof(*rab->guaranteedBitRate));
	ASN_SEQUENCE_ADD(rab->guaranteedBitRate, new_long(12200));
	rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
	rab->maxSDU_Size = 244;

	sdui = new_sdu_par_item(SDUPAR_P_VOICE0);
	ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
	sdui = new_sdu_par_item(SDUPAR_P_VOICE1);
	ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);
	sdui = new_sdu_par_item(SDUPAR_P_VOICE2);
	ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);

	rab->transferDelay = new_long(80);
	rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 1, 0);

	rab->sourceStatisticsDescriptor = new_long(RANAP_SourceStatisticsDescriptor_speech);

	return rab;
}

static RANAP_RAB_Parameters_t *new_rab_par_data(uint32_t dl_max_bitrate, uint32_t ul_max_bitrate)
{
	RANAP_RAB_Parameters_t *rab = CALLOC(1, sizeof(*rab));
	RANAP_SDU_ParameterItem_t *sdui;

	rab->trafficClass = RANAP_TrafficClass_background;
	rab->rAB_AsymmetryIndicator = RANAP_RAB_AsymmetryIndicator_asymmetric_bidirectional;

	ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(dl_max_bitrate));
	ASN_SEQUENCE_ADD(&rab->maxBitrate.list, new_long(ul_max_bitrate));
	rab->deliveryOrder = RANAP_DeliveryOrder_delivery_order_requested;
	rab->maxSDU_Size = 8000;

	sdui = new_sdu_par_item(SDUPAR_P_DATA);
	ASN_SEQUENCE_ADD(&rab->sDU_Parameters, sdui);

	rab->allocationOrRetentionPriority = new_alloc_ret_prio(RANAP_PriorityLevel_no_priority, 0, 0, 0);

	/* FIXME: RAB-Parameter-ExtendedMaxBitrateList for 42Mbps? */

	return rab;
}

static void new_transp_layer_addr(BIT_STRING_t *out, uint32_t ip, int use_x213_nsap)
{
	uint8_t *buf;
	unsigned int len;

	if (use_x213_nsap) {
		len = 7;
		buf = CALLOC(len, sizeof(uint8_t));
		buf[0] = 0x35;	/* AFI For IANA ICP */
		buf[1] = 0x00;	/* See A.5.2.1.2.7 of X.213 */
		buf[2] = 0x01;
		*(uint32_t *)&buf[3] = ntohl(ip);
	} else {
		len = 4;
		buf = CALLOC(len, sizeof(uint8_t));
		*(uint32_t *)buf = ip;
	}
	out->buf = buf;
	out->size = len;
	out->bits_unused = 0;
}

static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port)
{
	RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
	uint8_t binding_id[4];

#if 0
	binding_id[0] = port >> 8;
	binding_id[1] = port & 0xff;
	binding_id[2] = binding_id[3] = 0;
#else
	binding_id[0] = binding_id[1] = binding_id[2]  = 0;
	binding_id[3] = 1;
#endif

	new_transp_layer_addr(&tli->transportLayerAddress, ip, 1);
	tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID;
	OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
				(const char *) binding_id, sizeof(binding_id));

	return tli;
}

static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei)
{
	RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
	uint32_t binding_buf = htonl(tei);

	new_transp_layer_addr(&tli->transportLayerAddress, ip, 1);
	tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI;
	OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.gTP_TEI,
			     (const char *) &binding_buf, sizeof(binding_buf));

	return tli;
}

static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions)
{
	RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi));
	uint16_t *buf = CALLOC(1, sizeof(*buf));

	*buf = ntohs(mode_versions);

	upi->userPlaneMode = mode;
	upi->uP_ModeVersions.buf = (uint8_t *) buf;
	upi->uP_ModeVersions.size = sizeof(*buf);
	upi->uP_ModeVersions.bits_unused = 0;

	return upi;
}


static void assign_new_ra_id(RANAP_RAB_ID_t *id, uint8_t rab_id)
{
	uint8_t *buf = CALLOC(1, sizeof(*buf));
	*buf = rab_id;

	id->buf = buf;
	id->size = 1;
	id->bits_unused = 0;
}

/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for CS (voice) */
struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip, uint16_t rtp_port)
{
	RANAP_ProtocolIE_FieldPair_t *pair;
	RANAP_RAB_AssignmentRequestIEs_t ies;
	RANAP_RAB_AssignmentRequest_t out;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	/* only assingnment is present, no release */
	ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;

	/* put together the 'First' part */
	RANAP_RAB_SetupOrModifyItemFirst_t first;
	memset(&first, 0, sizeof(first));
	assign_new_ra_id(&first.rAB_ID, rab_id);
	//first.nAS_SynchronisationIndicator = FIXME;
	first.rAB_Parameters = new_rab_par_voice();
	first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */
	first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port);

	/* put together the 'Second' part */
	RANAP_RAB_SetupOrModifyItemSecond_t second;
	memset(&second, 0, sizeof(second));

	/* Build an IE Pair out of first and second part:
	 * (first, second) -> pair */
	pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
				 RANAP_Criticality_reject,
				 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first,
				 RANAP_Criticality_ignore,
				 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);

	/* the pair has been made, we can release any of its elements */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);

	RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
	/* Add the pair to the list of IEs of the RAB ass.req */
	ASN_SEQUENCE_ADD(container_pair, pair);
	ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);

	/* encode the IEs into the actual assignment request:
	 * ies -> out */
	rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
	/* 'out' has been generated, we can now release the input */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
				      &ies.raB_SetupOrModifyList);
	if (rc < 0)
		return NULL;

	/* generate an Initiating Mesasage: out -> msg */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_RAB_AssignmentRequest, &out);

	/* 'msg' has been generated, we cann now release the input 'out' */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);

	return msg;
}

/*! \brief generate RANAP RAB ASSIGNMENT REQUEST message for PS (data) */
struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip, uint32_t gtp_tei)
{
	RANAP_ProtocolIE_FieldPair_t *pair;
	RANAP_RAB_AssignmentRequestIEs_t ies;
	RANAP_RAB_AssignmentRequest_t out;
	RANAP_DataVolumeReportingIndication_t *dat_vol_ind;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	/* only assingnment is present, no release */
	ies.presenceMask = RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT;

	/* put together the 'First' part */
	RANAP_RAB_SetupOrModifyItemFirst_t first;
	memset(&first, 0, sizeof(first));
	assign_new_ra_id(&first.rAB_ID, rab_id);
	//first.nAS_SynchronisationIndicator = FIXME;

	first.rAB_Parameters = new_rab_par_data(1600000, 800000);
	first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1);
	first.transportLayerInformation = new_transp_info_gtp(gtp_ip, gtp_tei);

	/* put together the 'Second' part */
	RANAP_RAB_SetupOrModifyItemSecond_t second;
	memset(&second, 0, sizeof(second));
	second.pDP_TypeInformation = CALLOC(1, sizeof(*second.pDP_TypeInformation));
	ASN_SEQUENCE_ADD(second.pDP_TypeInformation, new_long(RANAP_PDP_Type_ipv4));
	dat_vol_ind = CALLOC(1, sizeof(*dat_vol_ind));
	*dat_vol_ind = RANAP_DataVolumeReportingIndication_do_not_report;
	second.dataVolumeReportingIndication = dat_vol_ind;
	second.dl_GTP_PDU_SequenceNumber = new_long(0);
	second.ul_GTP_PDU_SequenceNumber = new_long(0);

	/* Build an IE Pair out of first and second part:
	 * (first, second) -> pair */
	pair = ranap_new_ie_pair(RANAP_ProtocolIE_ID_id_RAB_SetupOrModifyItem,
				 RANAP_Criticality_reject,
				 &asn_DEF_RANAP_RAB_SetupOrModifyItemFirst,
				 &first, RANAP_Criticality_ignore,
				 &asn_DEF_RANAP_RAB_SetupOrModifyItemSecond,
				 &second);

	/* the pair has been made, we can release any of its elements */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemFirst, &first);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyItemSecond, &second);

	RANAP_ProtocolIE_ContainerPair_t *container_pair = CALLOC(1, sizeof(*container_pair));
	/* Add the pair to the list of IEs of the RAB ass.req */
	ASN_SEQUENCE_ADD(container_pair, pair);
	/* Add the pair to the list of IEs of the RAB ass.req */
	ASN_SEQUENCE_ADD(&ies.raB_SetupOrModifyList.list, container_pair);

	/* encode the IEs into the actual assignment request:
	 * ies -> out */
	rc = ranap_encode_rab_assignmentrequesties(&out, &ies);
	/* 'out' has been generated, we can now release the input */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_SetupOrModifyList,
				      &ies.raB_SetupOrModifyList);
	if (rc < 0)
		return NULL;

	/* generate an Initiating Mesasage: out -> msg */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_Assignment,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_RAB_AssignmentRequest, &out);

	/* 'msg' has been generated, we cann now release the input 'out' */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_AssignmentRequest, &out);

	return msg;
}

struct msgb *ranap_new_msg_iu_rel_req(const RANAP_Cause_t *cause)
{
	RANAP_Iu_ReleaseRequestIEs_t ies;
	RANAP_Iu_ReleaseRequest_t out;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	memcpy(&ies.cause, cause, sizeof(ies.cause));

	rc = ranap_encode_iu_releaserequesties(&out, &ies);
	if (rc < 0)
		return NULL;

	/* encode the output into the msgb */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_Iu_ReleaseRequest,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_Iu_ReleaseRequest, &out);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_Iu_ReleaseRequest, &out);

	return msg;
}

struct msgb *ranap_new_msg_rab_rel_req(uint8_t rab_id, const RANAP_Cause_t *cause)
{
	RANAP_RAB_ReleaseItemIEs_t item_ies;
	RANAP_RAB_ReleaseRequestIEs_t ies;
	RANAP_RAB_ReleaseRequest_t out;
	struct msgb *msg;
	int rc;

	memset(&item_ies, 0, sizeof(item_ies));
	memset(&ies, 0, sizeof(ies));
	memset(&out, 0, sizeof(out));

	/* put together the ReleaseItem */
	assign_new_ra_id(&item_ies.raB_ReleaseItem.rAB_ID, rab_id);
	memcpy(&item_ies.raB_ReleaseItem.cause, cause, sizeof(item_ies.raB_ReleaseItem.cause));

	/* add to the list */
	rc = ranap_encode_rab_releaseitemies(&ies.raB_ReleaseList, &item_ies);
	if (rc < 0)
		return NULL;
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_ReleaseItem, &item_ies.raB_ReleaseItem);

	/* encoe the list IEs into the output */
	rc = ranap_encode_rab_releaserequesties(&out, &ies);
	if (rc < 0)
		return NULL;
	/* 'out' has been generated, we can release the input */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_ReleaseList, &ies.raB_ReleaseList);

	/* encode the output into the msgb */
	msg = ranap_generate_initiating_message(RANAP_ProcedureCode_id_RAB_ReleaseRequest,
						RANAP_Criticality_reject,
						&asn_DEF_RANAP_RAB_ReleaseRequest, &out);

	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RANAP_RAB_ReleaseRequest, &out);

	return msg;
}
